- Added raid cheat to configuration to add posibility to turn off (#1465)

- Added General Vezax strategy
This commit is contained in:
kadeshar
2025-07-27 07:51:45 +02:00
committed by GitHub
parent 237c0cffc4
commit 1e33b28abe
11 changed files with 299 additions and 87 deletions

View File

@@ -501,9 +501,10 @@ AiPlayerbot.AutoGearScoreLimit = 0
# "mana" (bots have infinite mana) # "mana" (bots have infinite mana)
# "power" (bots have infinite energy, rage, and runic power) # "power" (bots have infinite energy, rage, and runic power)
# "taxi" (bots may use all flight paths, though they will not actually learn them) # "taxi" (bots may use all flight paths, though they will not actually learn them)
# "raid" (bots use cheats implemented into raid strategies)
# To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,taxi") # To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,taxi")
# Default: taxi is enabled # Default: taxi is enabled
AiPlayerbot.BotCheats = "taxi" AiPlayerbot.BotCheats = "taxi,raid"
# #
# #

View File

@@ -448,7 +448,7 @@ bool PlayerbotAIConfig::Initialize()
} }
botCheats.clear(); botCheats.clear();
LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.BotCheats", "taxi"), LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.BotCheats", "taxi,raid"),
botCheats); botCheats);
botCheatMask = 0; botCheatMask = 0;
@@ -463,6 +463,8 @@ bool PlayerbotAIConfig::Initialize()
botCheatMask |= (uint32)BotCheatMask::mana; botCheatMask |= (uint32)BotCheatMask::mana;
if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end()) if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end())
botCheatMask |= (uint32)BotCheatMask::power; botCheatMask |= (uint32)BotCheatMask::power;
if (std::find(botCheats.begin(), botCheats.end(), "raid") != botCheats.end())
botCheatMask |= (uint32)BotCheatMask::raid;
LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.AllowedLogFiles", ""), LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.AllowedLogFiles", ""),
allowedLogFiles); allowedLogFiles);

View File

@@ -22,7 +22,8 @@ enum class BotCheatMask : uint32
health = 4, health = 4,
mana = 8, mana = 8,
power = 16, power = 16,
maxMask = 32 raid = 32,
maxMask = 64
}; };
enum class HealingManaEfficiency : uint8 enum class HealingManaEfficiency : uint8

View File

@@ -53,6 +53,9 @@ BotCheatMask CheatAction::GetCheatMask(std::string const cheat)
if (cheat == "power") if (cheat == "power")
return BotCheatMask::power; return BotCheatMask::power;
if (cheat == "raid")
return BotCheatMask::raid;
return BotCheatMask::none; return BotCheatMask::none;
} }
@@ -70,6 +73,8 @@ std::string const CheatAction::GetCheatName(BotCheatMask cheatMask)
return "mana"; return "mana";
case BotCheatMask::power: case BotCheatMask::power:
return "power"; return "power";
case BotCheatMask::raid:
return "raid";
default: default:
return "none"; return "none";
} }

View File

@@ -62,6 +62,9 @@ public:
creators["mimiron rocket strike action"] = &RaidUlduarActionContext::mimiron_rocket_strike_action; creators["mimiron rocket strike action"] = &RaidUlduarActionContext::mimiron_rocket_strike_action;
creators["mimiron phase 4 mark dps action"] = &RaidUlduarActionContext::mimiron_phase_4_mark_dps_action; creators["mimiron phase 4 mark dps action"] = &RaidUlduarActionContext::mimiron_phase_4_mark_dps_action;
creators["mimiron cheat action"] = &RaidUlduarActionContext::mimiron_cheat_action; creators["mimiron cheat action"] = &RaidUlduarActionContext::mimiron_cheat_action;
creators["vezax cheat action"] = &RaidUlduarActionContext::vezax_cheat_action;
creators["vezax shadow crash action"] = &RaidUlduarActionContext::vezax_shadow_crash_action;
creators["vezax mark of the faceless action"] = &RaidUlduarActionContext::vezax_mark_of_the_faceless_action;
} }
private: private:
@@ -111,6 +114,9 @@ private:
static Action* mimiron_rocket_strike_action(PlayerbotAI* ai) { return new MimironRocketStrikeAction(ai); } static Action* mimiron_rocket_strike_action(PlayerbotAI* ai) { return new MimironRocketStrikeAction(ai); }
static Action* mimiron_phase_4_mark_dps_action(PlayerbotAI* ai) { return new MimironPhase4MarkDpsAction(ai); } static Action* mimiron_phase_4_mark_dps_action(PlayerbotAI* ai) { return new MimironPhase4MarkDpsAction(ai); }
static Action* mimiron_cheat_action(PlayerbotAI* ai) { return new MimironCheatAction(ai); } static Action* mimiron_cheat_action(PlayerbotAI* ai) { return new MimironCheatAction(ai); }
static Action* vezax_cheat_action(PlayerbotAI* ai) { return new VezaxCheatAction(ai); }
static Action* vezax_shadow_crash_action(PlayerbotAI* ai) { return new VezaxShadowCrashAction(ai); }
static Action* vezax_mark_of_the_faceless_action(PlayerbotAI* ai) { return new VezaxMarkOfTheFacelessAction(ai); }
}; };
#endif #endif

View File

@@ -42,7 +42,6 @@ const Position ULDUAR_KOLOGARN_RESTORE_POSITION = Position(1764.3749f, -24.02903
const Position ULDUAR_KOLOGARN_EYEBEAM_LEFT_POSITION = Position(1781.2051f, 9.34402f, 449.0f, 0.00087690353f); const Position ULDUAR_KOLOGARN_EYEBEAM_LEFT_POSITION = Position(1781.2051f, 9.34402f, 449.0f, 0.00087690353f);
const Position ULDUAR_KOLOGARN_EYEBEAM_RIGHT_POSITION = Position(1763.2561f, -24.44305f, 449.0f, 0.00087690353f); const Position ULDUAR_KOLOGARN_EYEBEAM_RIGHT_POSITION = Position(1763.2561f, -24.44305f, 449.0f, 0.00087690353f);
const Position ULDUAR_THORIM_JUMP_START_POINT = Position(2137.137f, -291.19025f, 438.24753f, 1.7059844f); const Position ULDUAR_THORIM_JUMP_START_POINT = Position(2137.137f, -291.19025f, 438.24753f, 1.7059844f);
const Position ULDUAR_THORIM_JUMP_END_POINT = Position(2137.8818f, -278.18942f, 419.66653f);
bool FlameLeviathanVehicleAction::Execute(Event event) bool FlameLeviathanVehicleAction::Execute(Event event)
{ {
@@ -568,7 +567,6 @@ bool RazorscaleAvoidSentinelAction::Execute(Event event)
} }
} }
return movedAway; // Return true if moved return movedAway; // Return true if moved
} }
@@ -654,7 +652,8 @@ bool RazorscaleAvoidWhirlwindAction::isUseful()
Unit* unit = botAI->GetUnit(npc); Unit* unit = botAI->GetUnit(npc);
if (unit && unit->GetEntry() == RazorscaleBossHelper::UNIT_DARK_RUNE_SENTINEL) if (unit && unit->GetEntry() == RazorscaleBossHelper::UNIT_DARK_RUNE_SENTINEL)
{ {
if (unit->HasAura(RazorscaleBossHelper::SPELL_SENTINEL_WHIRLWIND) || unit->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) if (unit->HasAura(RazorscaleBossHelper::SPELL_SENTINEL_WHIRLWIND) ||
unit->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{ {
if (bot->GetDistance2d(unit) < radius) if (bot->GetDistance2d(unit) < radius)
{ {
@@ -679,9 +678,9 @@ bool RazorscaleIgnoreBossAction::isUseful()
if (boss->GetPositionZ() >= RazorscaleBossHelper::RAZORSCALE_FLYING_Z_THRESHOLD) if (boss->GetPositionZ() >= RazorscaleBossHelper::RAZORSCALE_FLYING_Z_THRESHOLD)
{ {
// Check if the bot is outside the designated area // Check if the bot is outside the designated area
if (bot->GetDistance2d( if (bot->GetDistance2d(RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) >
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) > RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f) RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f)
{ {
return true; // Movement to the center is the top priority for all bots return true; // Movement to the center is the top priority for all bots
} }
@@ -751,18 +750,13 @@ bool RazorscaleIgnoreBossAction::Execute(Event event)
} }
// Check if the bot is outside the designated area and move inside first // Check if the bot is outside the designated area and move inside first
if (bot->GetDistance2d( if (bot->GetDistance2d(RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) >
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y) > RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f) RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS + 25.0f)
{ {
return MoveInside( return MoveInside(ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y, bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 10.0f, MovementPriority::MOVEMENT_NORMAL);
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y,
bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 10.0f,
MovementPriority::MOVEMENT_NORMAL
);
} }
if (!botAI->IsTank(bot)) if (!botAI->IsTank(bot))
@@ -802,14 +796,9 @@ bool RazorscaleIgnoreBossAction::Execute(Event event)
} }
// Tanks move inside the arena // Tanks move inside the arena
return MoveInside( return MoveInside(ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y, bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 10.0f, MovementPriority::MOVEMENT_NORMAL);
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y,
bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 10.0f,
MovementPriority::MOVEMENT_NORMAL
);
} }
bool RazorscaleGroundedAction::isUseful() bool RazorscaleGroundedAction::isUseful()
@@ -875,9 +864,8 @@ bool RazorscaleGroundedAction::isUseful()
float bossY = boss->GetPositionY(); float bossY = boss->GetPositionY();
float bossZ = boss->GetPositionZ(); float bossZ = boss->GetPositionZ();
bool atInitialLandingPosition = (fabs(bossX - landingX) < 2.0f) && bool atInitialLandingPosition =
(fabs(bossY - landingY) < 2.0f) && (fabs(bossX - landingX) < 2.0f) && (fabs(bossY - landingY) < 2.0f) && (fabs(bossZ - landingZ) < 1.0f);
(fabs(bossZ - landingZ) < 1.0f);
constexpr float initialLandingRadius = 14.0f; constexpr float initialLandingRadius = 14.0f;
constexpr float normalRadius = 12.0f; constexpr float normalRadius = 12.0f;
@@ -891,7 +879,8 @@ bool RazorscaleGroundedAction::isUseful()
return distanceToAdjustedCenter > initialLandingRadius; return distanceToAdjustedCenter > initialLandingRadius;
} }
float distanceToCenter = bot->GetDistance2d(RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y); float distanceToCenter = bot->GetDistance2d(RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y);
return distanceToCenter > normalRadius; return distanceToCenter > normalRadius;
} }
@@ -961,33 +950,22 @@ bool RazorscaleGroundedAction::Execute(Event event)
float bossY = boss->GetPositionY(); float bossY = boss->GetPositionY();
float bossZ = boss->GetPositionZ(); float bossZ = boss->GetPositionZ();
bool atInitialLandingPosition = (fabs(bossX - landingX) < 2.0f) && bool atInitialLandingPosition =
(fabs(bossY - landingY) < 2.0f) && (fabs(bossX - landingX) < 2.0f) && (fabs(bossY - landingY) < 2.0f) && (fabs(bossZ - landingZ) < 1.0f);
(fabs(bossZ - landingZ) < 1.0f);
if (atInitialLandingPosition) if (atInitialLandingPosition)
{ {
// If at the initial landing position, use 12-yard radius with a // If at the initial landing position, use 12-yard radius with a
// 20 yard offset on the Y axis so everyone is behind the boss // 20 yard offset on the Y axis so everyone is behind the boss
return MoveInside( return MoveInside(ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y - 20.0f, bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 12.0f, MovementPriority::MOVEMENT_COMBAT);
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y - 20.0f,
bot->GetPositionZ(),
RazorscaleBossHelper::RAZORSCALE_ARENA_RADIUS - 12.0f,
MovementPriority::MOVEMENT_COMBAT
);
} }
// Otherwise, move inside a 12-yard radius around the arena center // Otherwise, move inside a 12-yard radius around the arena center
return MoveInside( return MoveInside(ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X,
ULDUAR_MAP_ID, RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y, bot->GetPositionZ(), 12.0f,
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_X, MovementPriority::MOVEMENT_COMBAT);
RazorscaleBossHelper::RAZORSCALE_ARENA_CENTER_Y,
bot->GetPositionZ(),
12.0f,
MovementPriority::MOVEMENT_COMBAT
);
} }
return false; return false;
} }
@@ -1064,9 +1042,7 @@ bool RazorscaleHarpoonAction::Execute(Event event)
float botDist = bot->GetDistance(closestHarpoon); float botDist = bot->GetDistance(closestHarpoon);
if (botDist > INTERACTION_DISTANCE - 1.0f) if (botDist > INTERACTION_DISTANCE - 1.0f)
{ {
return MoveTo(bot->GetMapId(), return MoveTo(bot->GetMapId(), closestHarpoon->GetPositionX(), closestHarpoon->GetPositionY(),
closestHarpoon->GetPositionX(),
closestHarpoon->GetPositionY(),
closestHarpoon->GetPositionZ()); closestHarpoon->GetPositionZ());
} }
@@ -1453,7 +1429,12 @@ bool KologarnEyebeamAction::Execute(Event event)
bool KologarnEyebeamAction::isUseful() bool KologarnEyebeamAction::isUseful()
{ {
KologarnEyebeamTrigger kologarnEyebeamTrigger(botAI); KologarnEyebeamTrigger kologarnEyebeamTrigger(botAI);
return kologarnEyebeamTrigger.IsActive(); if (!kologarnEyebeamTrigger.IsActive())
{
return false;
}
return botAI->HasCheat(BotCheatMask::raid);
} }
bool KologarnRtiTargetAction::isUseful() bool KologarnRtiTargetAction::isUseful()
@@ -1477,7 +1458,12 @@ bool KologarnRtiTargetAction::Execute(Event event)
bool KologarnCrunchArmorAction::isUseful() bool KologarnCrunchArmorAction::isUseful()
{ {
KologarnCrunchArmorTrigger kologarnCrunchArmorTrigger(botAI); KologarnCrunchArmorTrigger kologarnCrunchArmorTrigger(botAI);
return kologarnCrunchArmorTrigger.IsActive(); if (!kologarnCrunchArmorTrigger.IsActive())
{
return false;
}
return botAI->HasCheat(BotCheatMask::raid);
} }
bool KologarnCrunchArmorAction::Execute(Event event) bool KologarnCrunchArmorAction::Execute(Event event)
@@ -1576,6 +1562,11 @@ bool HodirBitingColdJumpAction::Execute(Event event)
// return true; // return true;
} }
bool HodirBitingColdJumpAction::isUseful()
{
return botAI->HasCheat(BotCheatMask::raid);
}
bool FreyaMoveAwayNatureBombAction::isUseful() bool FreyaMoveAwayNatureBombAction::isUseful()
{ {
// Check boss and it is alive // Check boss and it is alive
@@ -1798,7 +1789,12 @@ bool FreyaMoveToHealingSporeAction::Execute(Event event)
bool ThorimUnbalancingStrikeAction::isUseful() bool ThorimUnbalancingStrikeAction::isUseful()
{ {
ThorimUnbalancingStrikeTrigger thorimUnbalancingStrikeTrigger(botAI); ThorimUnbalancingStrikeTrigger thorimUnbalancingStrikeTrigger(botAI);
return thorimUnbalancingStrikeTrigger.IsActive(); if (!thorimUnbalancingStrikeTrigger.IsActive())
{
return false;
}
return botAI->HasCheat(BotCheatMask::raid);
} }
bool ThorimUnbalancingStrikeAction::Execute(Event event) bool ThorimUnbalancingStrikeAction::Execute(Event event)
@@ -2647,3 +2643,67 @@ bool MimironCheatAction::Execute(Event event)
return true; return true;
} }
bool VezaxCheatAction::Execute(Event event)
{
// Restore bot's mana to full
uint32 maxMana = bot->GetMaxPower(POWER_MANA);
if (maxMana > 0)
{
bot->SetPower(POWER_MANA, maxMana);
}
return true;
}
bool VezaxShadowCrashAction::Execute(Event event)
{
// Find General Vezax boss
Unit* boss = AI_VALUE2(Unit*, "find target", "general vezax");
if (!boss || !boss->IsAlive())
{
return false;
}
// Get bot's current position relative to boss
float bossX = boss->GetPositionX();
float bossY = boss->GetPositionY();
float bossZ = boss->GetPositionZ();
float botX = bot->GetPositionX();
float botY = bot->GetPositionY();
// Calculate current angle and distance from boss
float currentAngle = atan2(botY - bossY, botX - bossX);
float currentDistance = bot->GetDistance2d(boss);
// Set desired distance from boss (stay close enough for melee, far enough for ranged)
float desiredDistance = 15.0f;
// If too close or too far, adjust distance first
if (currentDistance < desiredDistance - 2.0f || currentDistance > desiredDistance + 2.0f)
{
currentDistance = desiredDistance;
}
// Calculate movement increment - move in increments around the boss
float angleIncrement = M_PI / 10;
float newAngle = currentAngle + angleIncrement;
// Calculate new position
float newX = bossX + currentDistance * cos(newAngle);
float newY = bossY + currentDistance * sin(newAngle);
float newZ = bossZ; // Keep same Z level as boss
// Move to the new position
return MoveTo(boss->GetMapId(), newX, newY, newZ, false, false, false, true, MovementPriority::MOVEMENT_COMBAT,
true);
}
bool VezaxMarkOfTheFacelessAction::Execute(Event event)
{
return MoveTo(bot->GetMapId(), ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT.GetPositionX(),
ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT.GetPositionY(),
ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT.GetPositionZ(), false, false, false, true,
MovementPriority::MOVEMENT_FORCED, true, false);
}

View File

@@ -198,6 +198,7 @@ class HodirBitingColdJumpAction : public MovementAction
public: public:
HodirBitingColdJumpAction(PlayerbotAI* ai) : MovementAction(ai, "hodir biting cold jump") {} HodirBitingColdJumpAction(PlayerbotAI* ai) : MovementAction(ai, "hodir biting cold jump") {}
bool Execute(Event event) override; bool Execute(Event event) override;
bool isUseful() override;
}; };
class FreyaMoveAwayNatureBombAction : public MovementAction class FreyaMoveAwayNatureBombAction : public MovementAction
@@ -353,5 +354,28 @@ public:
bool Execute(Event event) override; bool Execute(Event event) override;
}; };
class VezaxCheatAction : public Action
{
public:
VezaxCheatAction(PlayerbotAI* ai) : Action(ai, "vezax cheat action") {}
bool Execute(Event event) override;
};
class VezaxShadowCrashAction : public MovementAction
{
public:
VezaxShadowCrashAction(PlayerbotAI* ai) : MovementAction(ai, "vezax shadow crash action") {}
bool Execute(Event event) override;
};
class VezaxMarkOfTheFacelessAction : public MovementAction
{
public:
VezaxMarkOfTheFacelessAction(PlayerbotAI* ai) : MovementAction(ai, "vezax mark of the faceless action") {}
bool Execute(Event event) override;
};
#endif #endif

View File

@@ -225,6 +225,21 @@ void RaidUlduarStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"mimiron cheat trigger", "mimiron cheat trigger",
NextAction::array(0, new NextAction("mimiron cheat action", ACTION_RAID), nullptr))); NextAction::array(0, new NextAction("mimiron cheat action", ACTION_RAID), nullptr)));
//
// General Vezax
//
triggers.push_back(new TriggerNode(
"vezax cheat trigger",
NextAction::array(0, new NextAction("vezax cheat action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"vezax shadow crash trigger",
NextAction::array(0, new NextAction("vezax shadow crash action", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode(
"vezax mark of the faceless trigger",
NextAction::array(0, new NextAction("vezax mark of the faceless action", ACTION_RAID), nullptr)));
} }
void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers) void RaidUlduarStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)

View File

@@ -64,6 +64,9 @@ public:
creators["mimiron rocket strike trigger"] = &RaidUlduarTriggerContext::mimiron_rocket_strike_trigger; creators["mimiron rocket strike trigger"] = &RaidUlduarTriggerContext::mimiron_rocket_strike_trigger;
creators["mimiron phase 4 mark dps trigger"] = &RaidUlduarTriggerContext::mimiron_phase_4_mark_dps_trigger; creators["mimiron phase 4 mark dps trigger"] = &RaidUlduarTriggerContext::mimiron_phase_4_mark_dps_trigger;
creators["mimiron cheat trigger"] = &RaidUlduarTriggerContext::mimiron_cheat_trigger; creators["mimiron cheat trigger"] = &RaidUlduarTriggerContext::mimiron_cheat_trigger;
creators["vezax cheat trigger"] = &RaidUlduarTriggerContext::vezax_cheat_trigger;
creators["vezax shadow crash trigger"] = &RaidUlduarTriggerContext::vezax_shadow_crash_trigger;
creators["vezax mark of the faceless trigger"] = &RaidUlduarTriggerContext::vezax_mark_of_the_faceless_trigger;
} }
private: private:
@@ -115,6 +118,9 @@ private:
static Trigger* mimiron_rocket_strike_trigger(PlayerbotAI* ai) { return new MimironRocketStrikeTrigger(ai); } static Trigger* mimiron_rocket_strike_trigger(PlayerbotAI* ai) { return new MimironRocketStrikeTrigger(ai); }
static Trigger* mimiron_phase_4_mark_dps_trigger(PlayerbotAI* ai) { return new MimironPhase4MarkDpsTrigger(ai); } static Trigger* mimiron_phase_4_mark_dps_trigger(PlayerbotAI* ai) { return new MimironPhase4MarkDpsTrigger(ai); }
static Trigger* mimiron_cheat_trigger(PlayerbotAI* ai) { return new MimironCheatTrigger(ai); } static Trigger* mimiron_cheat_trigger(PlayerbotAI* ai) { return new MimironCheatTrigger(ai); }
static Trigger* vezax_cheat_trigger(PlayerbotAI* ai) { return new VezaxCheatTrigger(ai); }
static Trigger* vezax_shadow_crash_trigger(PlayerbotAI* ai) { return new VezaxShadowCrashTrigger(ai); }
static Trigger* vezax_mark_of_the_faceless_trigger(PlayerbotAI* ai) { return new VezaxMarkOfTheFacelessTrigger(ai); }
}; };
#endif #endif

View File

@@ -1533,6 +1533,11 @@ bool MimironPhase4MarkDpsTrigger::IsActive()
bool MimironCheatTrigger::IsActive() bool MimironCheatTrigger::IsActive()
{ {
if (!botAI->HasCheat(BotCheatMask::raid))
{
return false;
}
if (!botAI->IsMainTank(bot)) if (!botAI->IsMainTank(bot))
{ {
return false; return false;
@@ -1557,3 +1562,60 @@ bool MimironCheatTrigger::IsActive()
return false; return false;
} }
bool VezaxCheatTrigger::IsActive()
{
if (!botAI->HasCheat(BotCheatMask::raid))
{
return false;
}
Unit* boss = AI_VALUE2(Unit*, "find target", "general vezax");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
{
return false;
}
if (!AI_VALUE2(bool, "has mana", "self target"))
{
return false;
}
return AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->lowMana;
}
bool VezaxShadowCrashTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "general vezax");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
{
return false;
}
return botAI->HasAura(SPELL_SHADOW_CRASH, bot);
}
bool VezaxMarkOfTheFacelessTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "general vezax");
// Check boss and it is alive
if (!boss || !boss->IsAlive())
{
return false;
}
if (!botAI->HasAura(SPELL_MARK_OF_THE_FACELESS, bot))
{
return false;
}
float distance = bot->GetDistance2d(ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT.GetPositionX(),
ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT.GetPositionY());
return distance > 2.0f;
}

View File

@@ -78,6 +78,10 @@ enum UlduarIDs
SPELL_P3WX2_LASER_BARRAGE_AURA_1 = 63274, SPELL_P3WX2_LASER_BARRAGE_AURA_1 = 63274,
SPELL_P3WX2_LASER_BARRAGE_AURA_2 = 63300, SPELL_P3WX2_LASER_BARRAGE_AURA_2 = 63300,
//General Vezax
SPELL_MARK_OF_THE_FACELESS = 63276,
SPELL_SHADOW_CRASH = 63277,
// Buffs // Buffs
SPELL_FROST_TRAP = 13809 SPELL_FROST_TRAP = 13809
}; };
@@ -106,6 +110,7 @@ const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_5_YARDS_1 = Position(2217.8877f
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1 = Position(2212.193f, -307.44992f, 412.1348f); const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_1 = Position(2212.193f, -307.44992f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2 = Position(2212.1353f, -318.20795f, 412.1348f); const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_2 = Position(2212.1353f, -318.20795f, 412.1348f);
const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3 = Position(2212.1956f, -328.0144f, 412.1348f); const Position ULDUAR_THORIM_GAUNTLET_RIGHT_SIDE_10_YARDS_3 = Position(2212.1956f, -328.0144f, 412.1348f);
const Position ULDUAR_THORIM_JUMP_END_POINT = Position(2137.8818f, -278.18942f, 419.66653f);
const Position ULDUAR_THORIM_PHASE2_TANK_SPOT = Position(2134.8572f, -287.0291f, 419.4935f); const Position ULDUAR_THORIM_PHASE2_TANK_SPOT = Position(2134.8572f, -287.0291f, 419.4935f);
const Position ULDUAR_THORIM_PHASE2_RANGE1_SPOT = Position(2112.8752f, -267.69305f, 419.52814f); const Position ULDUAR_THORIM_PHASE2_RANGE1_SPOT = Position(2112.8752f, -267.69305f, 419.52814f);
const Position ULDUAR_THORIM_PHASE2_RANGE2_SPOT = Position(2134.1296f, -257.3316f, 419.8462f); const Position ULDUAR_THORIM_PHASE2_RANGE2_SPOT = Position(2134.1296f, -257.3316f, 419.8462f);
@@ -117,6 +122,7 @@ const Position ULDUAR_MIMIRON_PHASE2_SIDE2MELEE_SPOT = Position(2739.4746f, 2569
const Position ULDUAR_MIMIRON_PHASE2_SIDE3RANGE_SPOT = Position(2754.1294f, 2553.9954f, 364.31357f); const Position ULDUAR_MIMIRON_PHASE2_SIDE3RANGE_SPOT = Position(2754.1294f, 2553.9954f, 364.31357f);
const Position ULDUAR_MIMIRON_PHASE2_SIDE3MELEE_SPOT = Position(2746.8513f, 2565.4263f, 364.31357f); const Position ULDUAR_MIMIRON_PHASE2_SIDE3MELEE_SPOT = Position(2746.8513f, 2565.4263f, 364.31357f);
const Position ULDUAR_MIMIRON_PHASE4_TANK_SPOT = Position(2744.5754f, 2570.8657f, 364.3138f); const Position ULDUAR_MIMIRON_PHASE4_TANK_SPOT = Position(2744.5754f, 2570.8657f, 364.3138f);
const Position ULDUAR_VEZAX_MARK_OF_THE_FACELESS_SPOT = Position(1913.6501f, 122.93989f, 342.38083f);
// //
// Flame Levi // Flame Levi
@@ -418,4 +424,28 @@ public:
bool IsActive() override; bool IsActive() override;
}; };
//
// General Vezax
//
class VezaxCheatTrigger : public Trigger
{
public:
VezaxCheatTrigger(PlayerbotAI* ai) : Trigger(ai, "vezax cheat trigger") {}
bool IsActive() override;
};
class VezaxShadowCrashTrigger : public Trigger
{
public:
VezaxShadowCrashTrigger(PlayerbotAI* ai) : Trigger(ai, "vezax shadow crash trigger") {}
bool IsActive() override;
};
class VezaxMarkOfTheFacelessTrigger : public Trigger
{
public:
VezaxMarkOfTheFacelessTrigger(PlayerbotAI* ai) : Trigger(ai, "vezax mark of the faceless trigger") {}
bool IsActive() override;
};
#endif #endif