mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
- Added raid cheat to configuration to add posibility to turn off (#1465)
- Added General Vezax strategy
This commit is contained in:
@@ -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"
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user