diff --git a/src/Ai/Raid/BWL/BWLActionContext.h b/src/Ai/Raid/BWL/BWLActionContext.h index db93476fe..fe59bf158 100644 --- a/src/Ai/Raid/BWL/BWLActionContext.h +++ b/src/Ai/Raid/BWL/BWLActionContext.h @@ -14,6 +14,8 @@ public: creators["bwl turn off suppression device"] = &RaidBwlActionContext::bwl_turn_off_suppression_device; creators["bwl use hourglass sand"] = &RaidBwlActionContext::bwl_use_hourglass_sand; creators["bwl nefarian fear ward"] = &RaidBwlActionContext::bwl_nefarian_fear_ward; + creators["bwl death talon wyrmguard tank move away"] = &RaidBwlActionContext::bwl_death_talon_wyrmguard_tank_move_away; + creators["bwl death talon wyrmguard ranged move away"] = &RaidBwlActionContext::bwl_death_talon_wyrmguard_ranged_move_away; } private: @@ -21,6 +23,8 @@ private: static Action* bwl_turn_off_suppression_device(PlayerbotAI* botAI) { return new BwlTurnOffSuppressionDeviceAction(botAI); } static Action* bwl_use_hourglass_sand(PlayerbotAI* botAI) { return new BwlUseHourglassSandAction(botAI); } static Action* bwl_nefarian_fear_ward(PlayerbotAI* botAI) { return new BwlNefarianFearWardAction(botAI); } + static Action* bwl_death_talon_wyrmguard_tank_move_away(PlayerbotAI* botAI) { return new BwlDeathTalonWyrmguardTankMoveAwayAction(botAI); } + static Action* bwl_death_talon_wyrmguard_ranged_move_away(PlayerbotAI* botAI) { return new BwlDeathTalonWyrmguardRangedMoveAwayAction(botAI); } }; #endif diff --git a/src/Ai/Raid/BWL/BWLActions.cpp b/src/Ai/Raid/BWL/BWLActions.cpp index 10c8dc4ae..8fad05f75 100644 --- a/src/Ai/Raid/BWL/BWLActions.cpp +++ b/src/Ai/Raid/BWL/BWLActions.cpp @@ -51,3 +51,85 @@ bool BwlNefarianFearWardAction::Execute(Event /*event*/) return botAI->CastSpell("fear ward", victim); } + +// Trash + +static constexpr float WYRMGUARD_SAFE_DISTANCE = 16.0f; + +Unit* BwlDeathTalonWyrmguardTankMoveAwayAction::GetTarget() +{ + // Find a nearby wyrmguard within 16 yards being tanked by someone else + for (auto const& [guid, ref] : bot->GetThreatMgr().GetThreatenedByMeList()) + { + Unit* unit = ref->GetOwner(); + if (!unit || !unit->IsAlive() || unit->GetEntry() != NPC_DEATH_TALON_WYRMGUARD) + continue; + if (bot->GetDistance2d(unit) > WYRMGUARD_SAFE_DISTANCE) + continue; + Unit* victim = unit->GetVictim(); + if (victim && victim != bot && victim->IsPlayer() && PlayerbotAI::IsTank(victim->ToPlayer())) + return unit; + } + return nullptr; +} + +bool BwlDeathTalonWyrmguardTankMoveAwayAction::isUseful() +{ + if (!GetTarget()) + return false; + + // Must be actively tanking a wyrmguard before moving away from another tank's + for (auto const& [guid, ref] : bot->GetThreatMgr().GetThreatenedByMeList()) + { + Unit* unit = ref->GetOwner(); + if (unit && unit->IsAlive() && unit->GetEntry() == NPC_DEATH_TALON_WYRMGUARD && unit->GetVictim() == bot) + return true; + } + return false; +} + +bool BwlDeathTalonWyrmguardTankMoveAwayAction::Execute(Event /*event*/) +{ + Unit* target = GetTarget(); + if (!target) + return false; + + float distToTravel = WYRMGUARD_SAFE_DISTANCE - bot->GetDistance2d(target); + if (distToTravel <= 0.0f) + return false; + + return MoveAway(target, distToTravel); +} + +Unit* BwlDeathTalonWyrmguardRangedMoveAwayAction::GetTarget() +{ + // Find the closest wyrmguard within 16 yards + Unit* closest = nullptr; + float closestDist = WYRMGUARD_SAFE_DISTANCE; + for (auto const& [guid, ref] : bot->GetThreatMgr().GetThreatenedByMeList()) + { + Unit* unit = ref->GetOwner(); + if (!unit || !unit->IsAlive() || unit->GetEntry() != NPC_DEATH_TALON_WYRMGUARD) + continue; + float dist = bot->GetDistance2d(unit); + if (dist < closestDist) + { + closestDist = dist; + closest = unit; + } + } + return closest; +} + +bool BwlDeathTalonWyrmguardRangedMoveAwayAction::Execute(Event /*event*/) +{ + Unit* target = GetTarget(); + if (!target) + return false; + + float distToTravel = WYRMGUARD_SAFE_DISTANCE - bot->GetDistance2d(target); + if (distToTravel <= 0.0f) + return false; + + return MoveAway(target, distToTravel); +} diff --git a/src/Ai/Raid/BWL/BWLActions.h b/src/Ai/Raid/BWL/BWLActions.h index 28b2f667c..9556c7569 100644 --- a/src/Ai/Raid/BWL/BWLActions.h +++ b/src/Ai/Raid/BWL/BWLActions.h @@ -2,6 +2,7 @@ #define _PLAYERBOT_RAIDBWLACTIONS_H #include "Action.h" +#include "MovementActions.h" // General @@ -36,4 +37,23 @@ public: bool Execute(Event event) override; }; +// Trash + +class BwlDeathTalonWyrmguardTankMoveAwayAction : public MovementAction +{ +public: + BwlDeathTalonWyrmguardTankMoveAwayAction(PlayerbotAI* botAI) : MovementAction(botAI, "bwl death talon wyrmguard tank move away") {} + Unit* GetTarget() override; + bool isUseful() override; + bool Execute(Event event) override; +}; + +class BwlDeathTalonWyrmguardRangedMoveAwayAction : public MovementAction +{ +public: + BwlDeathTalonWyrmguardRangedMoveAwayAction(PlayerbotAI* botAI) : MovementAction(botAI, "bwl death talon wyrmguard ranged move away") {} + Unit* GetTarget() override; + bool Execute(Event event) override; +}; + #endif diff --git a/src/Ai/Raid/BWL/BWLHelpers.h b/src/Ai/Raid/BWL/BWLHelpers.h index c76f0e892..0f7969f48 100644 --- a/src/Ai/Raid/BWL/BWLHelpers.h +++ b/src/Ai/Raid/BWL/BWLHelpers.h @@ -24,6 +24,12 @@ namespace BlackwingLairHelpers GO_SUPPRESSION_DEVICE = 179784 }; + enum BlackwingLairNPCs + { + // Trash + NPC_DEATH_TALON_WYRMGUARD = 12460 + }; + bool IsActiveSuppressionDeviceInRange(const GameObject* go, const Player* bot); } diff --git a/src/Ai/Raid/BWL/BWLStrategy.cpp b/src/Ai/Raid/BWL/BWLStrategy.cpp index 1e69be6e8..4b39724ec 100644 --- a/src/Ai/Raid/BWL/BWLStrategy.cpp +++ b/src/Ai/Raid/BWL/BWLStrategy.cpp @@ -16,4 +16,10 @@ void RaidBwlStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("bwl nefarian fear ward", { NextAction("bwl nefarian fear ward", ACTION_RAID) })); + + triggers.push_back(new TriggerNode("bwl death talon wyrmguard tank", { + NextAction("bwl death talon wyrmguard tank move away", ACTION_RAID) })); + + triggers.push_back(new TriggerNode("bwl death talon wyrmguard ranged", { + NextAction("bwl death talon wyrmguard ranged move away", ACTION_RAID) })); } diff --git a/src/Ai/Raid/BWL/BWLTriggerContext.h b/src/Ai/Raid/BWL/BWLTriggerContext.h index e3b9b599d..337fad7ba 100644 --- a/src/Ai/Raid/BWL/BWLTriggerContext.h +++ b/src/Ai/Raid/BWL/BWLTriggerContext.h @@ -13,6 +13,8 @@ public: creators["bwl affliction bronze"] = &RaidBwlTriggerContext::bwl_affliction_bronze; creators["bwl wild magic"] = &RaidBwlTriggerContext::bwl_wild_magic; creators["bwl nefarian fear ward"] = &RaidBwlTriggerContext::bwl_nefarian_fear_ward; + creators["bwl death talon wyrmguard tank"] = &RaidBwlTriggerContext::bwl_death_talon_wyrmguard_tank; + creators["bwl death talon wyrmguard ranged"] = &RaidBwlTriggerContext::bwl_death_talon_wyrmguard_ranged; } private: @@ -20,6 +22,8 @@ private: static Trigger* bwl_affliction_bronze(PlayerbotAI* ai) { return new BwlAfflictionBronzeTrigger(ai); } static Trigger* bwl_wild_magic(PlayerbotAI* ai) { return new BwlWildMagicTrigger(ai); } static Trigger* bwl_nefarian_fear_ward(PlayerbotAI* ai) { return new BwlNefarianFearWardTrigger(ai); } + static Trigger* bwl_death_talon_wyrmguard_tank(PlayerbotAI* ai) { return new BwlDeathTalonWyrmguardTankTrigger(ai); } + static Trigger* bwl_death_talon_wyrmguard_ranged(PlayerbotAI* ai) { return new BwlDeathTalonWyrmguardRangedTrigger(ai); } }; #endif diff --git a/src/Ai/Raid/BWL/BWLTriggers.cpp b/src/Ai/Raid/BWL/BWLTriggers.cpp index c977563d0..e3a55478f 100644 --- a/src/Ai/Raid/BWL/BWLTriggers.cpp +++ b/src/Ai/Raid/BWL/BWLTriggers.cpp @@ -28,6 +28,8 @@ bool BwlAfflictionBronzeTrigger::IsActive() return bot->HasAura(SPELL_BROOD_AFFLICTION_BRONZE); } +// Nefarian + bool BwlWildMagicTrigger::IsActive() { return bot->getClass() == CLASS_MAGE && bot->HasAura(SPELL_WILD_MAGIC); @@ -48,3 +50,15 @@ bool BwlNefarianFearWardTrigger::IsActive() return !botAI->HasAura("fear ward", victim); } + +// Trash + +bool BwlDeathTalonWyrmguardTankTrigger::IsActive() +{ + return PlayerbotAI::IsTank(bot) && AI_VALUE2(Unit*, "find target", "death talon wyrmguard"); +} + +bool BwlDeathTalonWyrmguardRangedTrigger::IsActive() +{ + return PlayerbotAI::IsRanged(bot) && AI_VALUE2(Unit*, "find target", "death talon wyrmguard"); +} diff --git a/src/Ai/Raid/BWL/BWLTriggers.h b/src/Ai/Raid/BWL/BWLTriggers.h index 8222cf592..9998b3fb6 100644 --- a/src/Ai/Raid/BWL/BWLTriggers.h +++ b/src/Ai/Raid/BWL/BWLTriggers.h @@ -37,4 +37,20 @@ public: bool IsActive() override; }; +// Trash + +class BwlDeathTalonWyrmguardTankTrigger : public Trigger +{ +public: + BwlDeathTalonWyrmguardTankTrigger(PlayerbotAI* botAI) : Trigger(botAI, "bwl death talon wyrmguard tank") {} + bool IsActive() override; +}; + +class BwlDeathTalonWyrmguardRangedTrigger : public Trigger +{ +public: + BwlDeathTalonWyrmguardRangedTrigger(PlayerbotAI* botAI) : Trigger(botAI, "bwl death talon wyrmguard ranged") {} + bool IsActive() override; +}; + #endif