From 16ea1777f4003fc1d21170b7e8e0b5c76bb19555 Mon Sep 17 00:00:00 2001 From: Bobblybook Date: Tue, 8 Oct 2024 22:35:16 +1100 Subject: [PATCH] Old Kingdom implementation Ahn'kahet: The Old Kingdom bot AI --- src/strategy/AiObjectContext.cpp | 2 + .../dungeons/DungeonStrategyContext.h | 9 +-- .../wotlk/WotlkDungeonActionContext.h | 2 +- .../wotlk/WotlkDungeonTriggerContext.h | 2 +- .../oldkingdom/OldKingdomActionContext.h | 22 +++++ .../wotlk/oldkingdom/OldKingdomActions.cpp | 81 +++++++++++++++++++ .../wotlk/oldkingdom/OldKingdomActions.h | 31 +++++++ .../oldkingdom/OldKingdomMultipliers.cpp | 66 +++++++++++++++ .../wotlk/oldkingdom/OldKingdomMultipliers.h | 33 ++++++++ .../wotlk/oldkingdom/OldKingdomStrategy.cpp | 36 +++++++++ .../wotlk/oldkingdom/OldKingdomStrategy.h | 18 +++++ .../oldkingdom/OldKingdomTriggerContext.h | 23 ++++++ .../wotlk/oldkingdom/OldKingdomTriggers.cpp | 43 ++++++++++ .../wotlk/oldkingdom/OldKingdomTriggers.h | 45 +++++++++++ src/strategy/dungeons/wotlk/oldkingdom/TODO | 0 15 files changed, 405 insertions(+), 8 deletions(-) create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActionContext.h create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.h create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.h create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggerContext.h create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp create mode 100644 src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.h delete mode 100644 src/strategy/dungeons/wotlk/oldkingdom/TODO diff --git a/src/strategy/AiObjectContext.cpp b/src/strategy/AiObjectContext.cpp index 819ea98ae..cf6b43ea2 100644 --- a/src/strategy/AiObjectContext.cpp +++ b/src/strategy/AiObjectContext.cpp @@ -53,6 +53,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) actionContexts.Add(new WotlkDungeonUKActionContext()); actionContexts.Add(new WotlkDungeonNexActionContext()); actionContexts.Add(new WotlkDungeonANActionContext()); + actionContexts.Add(new WotlkDungeonOKActionContext()); triggerContexts.Add(new TriggerContext()); triggerContexts.Add(new ChatTriggerContext()); @@ -66,6 +67,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) triggerContexts.Add(new WotlkDungeonUKTriggerContext()); triggerContexts.Add(new WotlkDungeonNexTriggerContext()); triggerContexts.Add(new WotlkDungeonANTriggerContext()); + triggerContexts.Add(new WotlkDungeonOKTriggerContext()); valueContexts.Add(new ValueContext()); diff --git a/src/strategy/dungeons/DungeonStrategyContext.h b/src/strategy/dungeons/DungeonStrategyContext.h index 8764d3517..141953af0 100644 --- a/src/strategy/dungeons/DungeonStrategyContext.h +++ b/src/strategy/dungeons/DungeonStrategyContext.h @@ -5,13 +5,10 @@ #include "wotlk/utgardekeep/UtgardeKeepStrategy.h" #include "wotlk/nexus/NexusStrategy.h" #include "wotlk/azjolnerub/AzjolNerubStrategy.h" +#include "wotlk/oldkingdom/OldKingdomStrategy.h" /* Full list/TODO: - - -Ahn'kahet: The Old Kingdom - OK -Elder Nadox, Prince Taldaram, Jedoga Shadowseeker, Herald Volazj, Amanitar (Heroic Only) Drak'Tharon Keep - DTK Trollgore, Novos the Summoner, King Dred, The Prophet Tharon'ja The Violet Hold - VH @@ -77,8 +74,8 @@ class DungeonStrategyContext : public NamedObjectContext static Strategy* wotlk_uk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } static Strategy* wotlk_nex(PlayerbotAI* botAI) { return new WotlkDungeonNexStrategy(botAI); } static Strategy* wotlk_an(PlayerbotAI* botAI) { return new WotlkDungeonANStrategy(botAI); } - - static Strategy* wotlk_ok(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } + static Strategy* wotlk_ok(PlayerbotAI* botAI) { return new WotlkDungeonOKStrategy(botAI); } + static Strategy* wotlk_dtk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } static Strategy* wotlk_vh(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } static Strategy* wotlk_gd(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); } diff --git a/src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h b/src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h index 405295133..1a2af3ce2 100644 --- a/src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h +++ b/src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h @@ -4,7 +4,7 @@ #include "utgardekeep/UtgardeKeepActionContext.h" #include "nexus/NexusActionContext.h" #include "azjolnerub/AzjolNerubActionContext.h" -// #include "oldkingdom/OldKingdomActionContext.h" +#include "oldkingdom/OldKingdomActionContext.h" // #include "draktharonkeep/DraktharonKeepActionContext.h" // #include "violethold/VioletHoldActionContext.h" // #include "gundrak/GundrakActionContext.h" diff --git a/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h b/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h index b53d0fa5a..c43672cd3 100644 --- a/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h +++ b/src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h @@ -4,7 +4,7 @@ #include "utgardekeep/UtgardeKeepTriggerContext.h" #include "nexus/NexusTriggerContext.h" #include "azjolnerub/AzjolNerubTriggerContext.h" -// #include "oldkingdom/OldKingdomTriggerContext.h" +#include "oldkingdom/OldKingdomTriggerContext.h" // #include "draktharonkeep/DraktharonKeepTriggerContext.h" // #include "violethold/VioletHoldTriggerContext.h" // #include "gundrak/GundrakTriggerContext.h" diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActionContext.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActionContext.h new file mode 100644 index 000000000..19426c579 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActionContext.h @@ -0,0 +1,22 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKACTIONCONTEXT_H +#define _PLAYERBOT_WOTLKDUNGEONOKACTIONCONTEXT_H + +#include "Action.h" +#include "NamedObjectContext.h" +#include "OldKingdomActions.h" + +class WotlkDungeonOKActionContext : public NamedObjectContext +{ + public: + WotlkDungeonOKActionContext() { + creators["attack nadox guardian"] = &WotlkDungeonOKActionContext::attack_nadox_guardian; + creators["attack jedoga volunteer"] = &WotlkDungeonOKActionContext::attack_jedoga_volunteer; + creators["avoid shadow crash"] = &WotlkDungeonOKActionContext::avoid_shadow_crash; + } + private: + static Action* attack_nadox_guardian(PlayerbotAI* ai) { return new AttackNadoxGuardianAction(ai); } + static Action* attack_jedoga_volunteer(PlayerbotAI* ai) { return new AttackJedogaVolunteerAction(ai); } + static Action* avoid_shadow_crash(PlayerbotAI* ai) { return new AvoidShadowCrashAction(ai); } +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp new file mode 100644 index 000000000..c5b27ccad --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.cpp @@ -0,0 +1,81 @@ +#include "Playerbots.h" +#include "OldKingdomActions.h" +#include "OldKingdomStrategy.h" + + +bool AttackNadoxGuardianAction::Execute(Event event) +{ + Unit* target = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); + if (!target || AI_VALUE(Unit*, "current target") == target) + { + return false; + } + + return Attack(target); +} + +bool AttackJedogaVolunteerAction::Execute(Event event) +{ + Unit* target = nullptr; + // Target is not findable from threat table using AI_VALUE2(), + // therefore need to search manually for the unit name + GuidVector targets = AI_VALUE(GuidVector, "possible targets no los"); + + for (auto i = targets.begin(); i != targets.end(); ++i) + { + Unit* unit = botAI->GetUnit(*i); + if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER) + { + target = unit; + break; + } + } + + if (!target || AI_VALUE(Unit*, "current target") == target) + { + return false; + } + return Attack(target); +} + +bool AvoidShadowCrashAction::Execute(Event event) +{ + // Could check all enemy units in range as it's possible to pull multiple of these mobs. + // They should really be killed 1 by 1, multipulls are messy so we just handle singles for now + Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); + Unit* victim = nullptr; + float radius = 10.0f; + float targetDist = radius + 2.0f; + if (!npc) { return false; } + + // Actively move if targeted by a shadow crash. + // Spell check not needed, they don't have any other non-instant casts + if (npc->HasUnitState(UNIT_STATE_CASTING)) // && npc->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH)) + { + // This doesn't seem to avoid casts very well, perhaps because this isn't checked while allies are casting. + // TODO: Revisit if this is an issue in heroics, otherwise ignore shadow crashes for the most part. + victim = botAI->GetUnit(npc->GetTarget()); + if (victim && bot->GetExactDist2d(victim) < radius) + { + return MoveAway(victim, targetDist - bot->GetExactDist2d(victim)); + } + } + + // Otherwise ranged members passively spread, to avoid AoE overlap + if (botAI->IsMelee(bot)) { return false; } + + GuidVector members = AI_VALUE(GuidVector, "group members"); + for (auto& member : members) + { + if (bot->GetGUID() == member) + { + continue; + } + float currentDist = bot->GetExactDist2d(botAI->GetUnit(member)); + if (currentDist < radius) + { + return MoveAway(botAI->GetUnit(member), targetDist - currentDist); + } + } + return false; +} diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.h new file mode 100644 index 000000000..cba518784 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomActions.h @@ -0,0 +1,31 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKACTIONS_H +#define _PLAYERBOT_WOTLKDUNGEONOKACTIONS_H + +#include "Action.h" +#include "AttackAction.h" +#include "PlayerbotAI.h" +#include "Playerbots.h" +#include "OldKingdomTriggers.h" + +class AttackNadoxGuardianAction : public AttackAction +{ +public: + AttackNadoxGuardianAction(PlayerbotAI* ai) : AttackAction(ai, "attack nadox guardian") {} + bool Execute(Event event) override; +}; + +class AttackJedogaVolunteerAction : public AttackAction +{ +public: + AttackJedogaVolunteerAction(PlayerbotAI* ai) : AttackAction(ai, "attack jedoga volunteer") {} + bool Execute(Event event) override; +}; + +class AvoidShadowCrashAction : public MovementAction +{ +public: + AvoidShadowCrashAction(PlayerbotAI* ai) : MovementAction(ai, "avoid shadow crash") {} + bool Execute(Event event) override; +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp new file mode 100644 index 000000000..9fc908024 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.cpp @@ -0,0 +1,66 @@ +#include "OldKingdomMultipliers.h" +#include "OldKingdomActions.h" +#include "GenericSpellActions.h" +#include "ChooseTargetActions.h" +#include "MovementActions.h" +#include "OldKingdomTriggers.h" +#include "Action.h" + +float ElderNadoxMultiplier::GetValue(Action* action) +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox"); + Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); + + if (boss && guardian) + { + if (dynamic_cast(action)) + { + return 0.0f; + } + } + return 1.0f; +} + +float JedogaShadowseekerMultiplier::GetValue(Action* action) +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); + // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); + + Unit* volunteer = nullptr; + // Target is not findable from threat table using AI_VALUE2(), + // therefore need to search manually for the unit name + GuidVector targets = AI_VALUE(GuidVector, "possible targets no los"); + + for (auto i = targets.begin(); i != targets.end(); ++i) + { + Unit* unit = botAI->GetUnit(*i); + if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER) + { + volunteer = unit; + break; + } + } + + if (boss && volunteer) + { + if (dynamic_cast(action)) + { + return 0.0f; + } + } + return 1.0f; +} + +float ForgottenOneMultiplier::GetValue(Action* action) +{ + Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); + + if (npc && bot->isMoving()) + { + if (dynamic_cast(action)) + { + return 0.0f; + } + } + return 1.0f; +} diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.h new file mode 100644 index 000000000..88ae2fa51 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomMultipliers.h @@ -0,0 +1,33 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKMULTIPLIERS_H +#define _PLAYERBOT_WOTLKDUNGEONOKMULTIPLIERS_H + +#include "Multiplier.h" + +class ElderNadoxMultiplier : public Multiplier +{ + public: + ElderNadoxMultiplier(PlayerbotAI* ai) : Multiplier(ai, "elder nadox") {} + + public: + virtual float GetValue(Action* action); +}; + +class JedogaShadowseekerMultiplier : public Multiplier +{ + public: + JedogaShadowseekerMultiplier(PlayerbotAI* ai) : Multiplier(ai, "jedoga shadowseeker") {} + + public: + virtual float GetValue(Action* action); +}; + +class ForgottenOneMultiplier : public Multiplier +{ + public: + ForgottenOneMultiplier(PlayerbotAI* ai) : Multiplier(ai, "forgotten one") {} + + public: + virtual float GetValue(Action* action); +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp new file mode 100644 index 000000000..b353a05d4 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.cpp @@ -0,0 +1,36 @@ +#include "OldKingdomStrategy.h" +#include "OldKingdomMultipliers.h" + + +void WotlkDungeonOKStrategy::InitTriggers(std::vector &triggers) +{ + // Elder Nadox + triggers.push_back(new TriggerNode("nadox guardian", + NextAction::array(0, new NextAction("attack nadox guardian", ACTION_RAID + 5), nullptr))); + + // Prince Taldaram + // Flame Orb spawns in melee, doesn't have a clear direction until it starts moving. + // Maybe not worth trying to avoid and just heal through. Only consideration is not to have ranged + // players anywhere near melee when it spawns + + // Jedoga Shadowseeker + triggers.push_back(new TriggerNode("jedoga volunteer", + NextAction::array(0, new NextAction("attack jedoga volunteer", ACTION_RAID + 5), nullptr))); + + // Herald Volazj + // Trash mobs before him have a big telegraphed shadow crash spell, + // this can be avoided and is intended to be dodged + triggers.push_back(new TriggerNode("shadow crash", + NextAction::array(0, new NextAction("avoid shadow crash", ACTION_MOVE + 5), nullptr))); + // Volazj is not implemented properly in AC, insanity phase does nothing. + + // Amanitar (Heroic Only) + // TODO: once I get to heroics +} + +void WotlkDungeonOKStrategy::InitMultipliers(std::vector &multipliers) +{ + multipliers.push_back(new ElderNadoxMultiplier(botAI)); + multipliers.push_back(new JedogaShadowseekerMultiplier(botAI)); + multipliers.push_back(new ForgottenOneMultiplier(botAI)); +} diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h new file mode 100644 index 000000000..03c5085ee --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomStrategy.h @@ -0,0 +1,18 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKSTRATEGY_H +#define _PLAYERBOT_WOTLKDUNGEONOKSTRATEGY_H + +#include "Multiplier.h" +#include "AiObjectContext.h" +#include "Strategy.h" + + +class WotlkDungeonOKStrategy : public Strategy +{ +public: + WotlkDungeonOKStrategy(PlayerbotAI* ai) : Strategy(ai) {} + virtual std::string const getName() override { return "old kingdom"; } + virtual void InitTriggers(std::vector &triggers) override; + virtual void InitMultipliers(std::vector &multipliers) override; +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggerContext.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggerContext.h new file mode 100644 index 000000000..faca49764 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggerContext.h @@ -0,0 +1,23 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKTRIGGERCONTEXT_H +#define _PLAYERBOT_WOTLKDUNGEONOKTRIGGERCONTEXT_H + +#include "NamedObjectContext.h" +#include "AiObjectContext.h" +#include "OldKingdomTriggers.h" + +class WotlkDungeonOKTriggerContext : public NamedObjectContext +{ + public: + WotlkDungeonOKTriggerContext() + { + creators["nadox guardian"] = &WotlkDungeonOKTriggerContext::nadox_guardian; + creators["jedoga volunteer"] = &WotlkDungeonOKTriggerContext::jedoga_volunteer; + creators["shadow crash"] = &WotlkDungeonOKTriggerContext::shadow_crash; + } + private: + static Trigger* nadox_guardian(PlayerbotAI* ai) { return new NadoxGuardianTrigger(ai); } + static Trigger* jedoga_volunteer(PlayerbotAI* ai) { return new JedogaVolunteerTrigger(ai); } + static Trigger* shadow_crash(PlayerbotAI* ai) { return new ShadowCrashTrigger(ai); } +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp new file mode 100644 index 000000000..951ab7555 --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.cpp @@ -0,0 +1,43 @@ +#include "Playerbots.h" +#include "OldKingdomTriggers.h" +#include "AiObject.h" +#include "AiObjectContext.h" + + +bool NadoxGuardianTrigger::IsActive() +{ + if (botAI->IsHeal(bot)) { return false; } + + Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox"); + Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); + + return boss && guardian; +} + +bool JedogaVolunteerTrigger::IsActive() +{ + Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); + // Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); + Unit* volunteer = nullptr; + // Target is not findable from threat table using AI_VALUE2(), + // therefore need to search manually for the unit name + GuidVector targets = AI_VALUE(GuidVector, "possible targets no los"); + + for (auto i = targets.begin(); i != targets.end(); ++i) + { + Unit* unit = botAI->GetUnit(*i); + if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER) + { + volunteer = unit; + break; + } + } + + return boss && volunteer; +} + +bool ShadowCrashTrigger::IsActive() +{ + if (botAI->IsMelee(bot)) { return false; } + return !botAI->IsMelee(bot) && AI_VALUE2(Unit*, "find target", "forgotten one"); +} diff --git a/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.h b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.h new file mode 100644 index 000000000..2aa77986e --- /dev/null +++ b/src/strategy/dungeons/wotlk/oldkingdom/OldKingdomTriggers.h @@ -0,0 +1,45 @@ +#ifndef _PLAYERBOT_WOTLKDUNGEONOKTRIGGERS_H +#define _PLAYERBOT_WOTLKDUNGEONOKTRIGGERS_H + +#include "Trigger.h" +#include "PlayerbotAIConfig.h" +#include "GenericTriggers.h" +#include "DungeonStrategyUtils.h" + +enum OldKingdomIDs +{ + // Elder Nadox + BUFF_GUARDIAN_AURA = 56153, + + // Jedoga Shadowseeker + NPC_TWILIGHT_VOLUNTEER = 30385, + + // Forgotten One(s) + SPELL_SHADOW_CRASH_N = 60833, + SPELL_SHADOW_CRASH_H = 60848, +}; + +#define SPELL_SHADOW_CRASH DUNGEON_MODE(bot, SPELL_SHADOW_CRASH_N, SPELL_SHADOW_CRASH_H) + +class NadoxGuardianTrigger : public Trigger +{ +public: + NadoxGuardianTrigger(PlayerbotAI* ai) : Trigger(ai, "elder nadox guardian") {} + bool IsActive() override; +}; + +class JedogaVolunteerTrigger : public Trigger +{ +public: + JedogaVolunteerTrigger(PlayerbotAI* ai) : Trigger(ai, "jedoga volunteer") {} + bool IsActive() override; +}; + +class ShadowCrashTrigger : public Trigger +{ +public: + ShadowCrashTrigger(PlayerbotAI* ai) : Trigger(ai, "shadow crash") {} + bool IsActive() override; +}; + +#endif diff --git a/src/strategy/dungeons/wotlk/oldkingdom/TODO b/src/strategy/dungeons/wotlk/oldkingdom/TODO deleted file mode 100644 index e69de29bb..000000000