mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-17 09:04:36 +00:00
Merge pull request #585 from Bobblybook/master
Azjol-Nerub implementation
This commit is contained in:
@@ -52,6 +52,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
actionContexts.Add(new RaidIccActionContext());
|
actionContexts.Add(new RaidIccActionContext());
|
||||||
actionContexts.Add(new WotlkDungeonUKActionContext());
|
actionContexts.Add(new WotlkDungeonUKActionContext());
|
||||||
actionContexts.Add(new WotlkDungeonNexActionContext());
|
actionContexts.Add(new WotlkDungeonNexActionContext());
|
||||||
|
actionContexts.Add(new WotlkDungeonANActionContext());
|
||||||
|
|
||||||
triggerContexts.Add(new TriggerContext());
|
triggerContexts.Add(new TriggerContext());
|
||||||
triggerContexts.Add(new ChatTriggerContext());
|
triggerContexts.Add(new ChatTriggerContext());
|
||||||
@@ -64,6 +65,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
triggerContexts.Add(new RaidIccTriggerContext());
|
triggerContexts.Add(new RaidIccTriggerContext());
|
||||||
triggerContexts.Add(new WotlkDungeonUKTriggerContext());
|
triggerContexts.Add(new WotlkDungeonUKTriggerContext());
|
||||||
triggerContexts.Add(new WotlkDungeonNexTriggerContext());
|
triggerContexts.Add(new WotlkDungeonNexTriggerContext());
|
||||||
|
triggerContexts.Add(new WotlkDungeonANTriggerContext());
|
||||||
|
|
||||||
valueContexts.Add(new ValueContext());
|
valueContexts.Add(new ValueContext());
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include "Strategy.h"
|
#include "Strategy.h"
|
||||||
#include "wotlk/utgardekeep/UtgardeKeepStrategy.h"
|
#include "wotlk/utgardekeep/UtgardeKeepStrategy.h"
|
||||||
#include "wotlk/nexus/NexusStrategy.h"
|
#include "wotlk/nexus/NexusStrategy.h"
|
||||||
|
#include "wotlk/azjolnerub/AzjolNerubStrategy.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Full list/TODO:
|
Full list/TODO:
|
||||||
|
|
||||||
Azjol-Nerub: Azjol-Nerub - AN
|
|
||||||
Krik'thir the Gatewatcher, Hadronox, Anub'arak
|
|
||||||
Ahn'kahet: The Old Kingdom - OK
|
Ahn'kahet: The Old Kingdom - OK
|
||||||
Elder Nadox, Prince Taldaram, Jedoga Shadowseeker, Herald Volazj, Amanitar (Heroic Only)
|
Elder Nadox, Prince Taldaram, Jedoga Shadowseeker, Herald Volazj, Amanitar (Heroic Only)
|
||||||
Drak'Tharon Keep - DTK
|
Drak'Tharon Keep - DTK
|
||||||
@@ -76,7 +76,8 @@ class DungeonStrategyContext : public NamedObjectContext<Strategy>
|
|||||||
private:
|
private:
|
||||||
static Strategy* wotlk_uk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
static Strategy* wotlk_uk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
static Strategy* wotlk_nex(PlayerbotAI* botAI) { return new WotlkDungeonNexStrategy(botAI); }
|
static Strategy* wotlk_nex(PlayerbotAI* botAI) { return new WotlkDungeonNexStrategy(botAI); }
|
||||||
static Strategy* wotlk_an(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(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 WotlkDungeonUKStrategy(botAI); }
|
||||||
static Strategy* wotlk_dtk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
static Strategy* wotlk_dtk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
static Strategy* wotlk_vh(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
static Strategy* wotlk_vh(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "utgardekeep/UtgardeKeepActionContext.h"
|
#include "utgardekeep/UtgardeKeepActionContext.h"
|
||||||
#include "nexus/NexusActionContext.h"
|
#include "nexus/NexusActionContext.h"
|
||||||
// #include "azjolnerub/AzjolNerubActionContext.h"
|
#include "azjolnerub/AzjolNerubActionContext.h"
|
||||||
// #include "oldkingdom/OldKingdomActionContext.h"
|
// #include "oldkingdom/OldKingdomActionContext.h"
|
||||||
// #include "draktharonkeep/DraktharonKeepActionContext.h"
|
// #include "draktharonkeep/DraktharonKeepActionContext.h"
|
||||||
// #include "violethold/VioletHoldActionContext.h"
|
// #include "violethold/VioletHoldActionContext.h"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "utgardekeep/UtgardeKeepTriggerContext.h"
|
#include "utgardekeep/UtgardeKeepTriggerContext.h"
|
||||||
#include "nexus/NexusTriggerContext.h"
|
#include "nexus/NexusTriggerContext.h"
|
||||||
// #include "azjolnerub/AzjolNerubTriggerContext.h"
|
#include "azjolnerub/AzjolNerubTriggerContext.h"
|
||||||
// #include "oldkingdom/OldKingdomTriggerContext.h"
|
// #include "oldkingdom/OldKingdomTriggerContext.h"
|
||||||
// #include "draktharonkeep/DraktharonKeepTriggerContext.h"
|
// #include "draktharonkeep/DraktharonKeepTriggerContext.h"
|
||||||
// #include "violethold/VioletHoldTriggerContext.h"
|
// #include "violethold/VioletHoldTriggerContext.h"
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANACTIONCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANACTIONCONTEXT_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "AzjolNerubActions.h"
|
||||||
|
|
||||||
|
class WotlkDungeonANActionContext : public NamedObjectContext<Action>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonANActionContext() {
|
||||||
|
creators["attack web wrap"] = &WotlkDungeonANActionContext::attack_web_wrap;
|
||||||
|
creators["krik'thir priority"] = &WotlkDungeonANActionContext::krikthir_priority;
|
||||||
|
creators["dodge pound"] = &WotlkDungeonANActionContext::dodge_pound;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Action* attack_web_wrap(PlayerbotAI* ai) { return new AttackWebWrapAction(ai); }
|
||||||
|
static Action* krikthir_priority(PlayerbotAI* ai) { return new WatchersTargetAction(ai); }
|
||||||
|
static Action* dodge_pound(PlayerbotAI* ai) { return new AnubarakDodgePoundAction(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
110
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp
Normal file
110
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "AzjolNerubActions.h"
|
||||||
|
#include "AzjolNerubStrategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool AttackWebWrapAction::isUseful() { return !botAI->IsHeal(bot); }
|
||||||
|
bool AttackWebWrapAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* webWrap = 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_WEB_WRAP)
|
||||||
|
{
|
||||||
|
webWrap = unit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!webWrap || AI_VALUE(Unit*, "current target") == webWrap)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Attack(webWrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WatchersTargetAction::isUseful() { return !botAI->IsHeal(bot); }
|
||||||
|
bool WatchersTargetAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
// Always prioritise web wraps
|
||||||
|
Unit* currTarget = AI_VALUE(Unit*, "current target");
|
||||||
|
if (currTarget && currTarget->GetEntry() == NPC_WEB_WRAP) { return false; }
|
||||||
|
|
||||||
|
// Do not search all units in range!
|
||||||
|
// There are many adds we don't want to aggro in close proximity,
|
||||||
|
// only check in-combat adds now.
|
||||||
|
GuidVector attackers = AI_VALUE(GuidVector, "attackers");
|
||||||
|
Unit* priorityTargets[4] = {nullptr, nullptr, nullptr, nullptr};
|
||||||
|
|
||||||
|
for (auto& attacker : attackers)
|
||||||
|
{
|
||||||
|
Unit* npc = botAI->GetUnit(attacker);
|
||||||
|
if (!npc)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (npc->GetEntry())
|
||||||
|
{
|
||||||
|
// Focus skirmishers first
|
||||||
|
case NPC_WATCHER_SKIRMISHER:
|
||||||
|
priorityTargets[0] = npc;
|
||||||
|
break;
|
||||||
|
// Then shadowcaster. This doesn't work so well for the shadowcaster
|
||||||
|
// + skirmisher pack - ideally we would kill the watcher second.
|
||||||
|
// But don't want to make this unnecessarily complex and rigid...
|
||||||
|
// Will revisit if this causes problems in heroic.
|
||||||
|
case NPC_WATCHER_SHADOWCASTER:
|
||||||
|
priorityTargets[1] = npc;
|
||||||
|
break;
|
||||||
|
// Named watcher next
|
||||||
|
case NPC_WATCHER_SILTHIK:
|
||||||
|
case NPC_WATCHER_GASHRA:
|
||||||
|
case NPC_WATCHER_NARJIL:
|
||||||
|
priorityTargets[2] = npc;
|
||||||
|
break;
|
||||||
|
// Warrior last
|
||||||
|
case NPC_WATCHER_WARRIOR:
|
||||||
|
priorityTargets[3] = npc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Unit* target : priorityTargets)
|
||||||
|
{
|
||||||
|
// Attack the first valid split target in the priority list
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
if (currTarget != target)
|
||||||
|
{
|
||||||
|
// bot->Yell("ATTACKING "+target->GetName(), LANG_UNIVERSAL);
|
||||||
|
return Attack(target);
|
||||||
|
}
|
||||||
|
// Don't continue loop here, the target exists so we don't
|
||||||
|
// want to move down the prio list. We just don't need to send attack
|
||||||
|
// command again, just return false and exit the loop that way
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnubarakDodgePoundAction::isUseful() { return !AI_VALUE2(bool, "behind", "current target"); }
|
||||||
|
bool AnubarakDodgePoundAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "anub'arak");
|
||||||
|
if (!boss) { return false; }
|
||||||
|
|
||||||
|
float distance = bot->GetExactDist2d(boss->GetPosition());
|
||||||
|
// Extra units to move into the boss, instead of being just 1 pixel past his midpoint.
|
||||||
|
// Can be adjusted - this value tends to mirror how a human would play,
|
||||||
|
// and visibly ensures you won't get hit while not creating excessive movements.
|
||||||
|
float distanceExtra = 2.0f;
|
||||||
|
return Move(bot->GetAngle(boss), distance + distanceExtra);
|
||||||
|
}
|
||||||
34
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.h
Normal file
34
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubActions.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANACTIONS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANACTIONS_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "AttackAction.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "AzjolNerubTriggers.h"
|
||||||
|
|
||||||
|
class AttackWebWrapAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AttackWebWrapAction(PlayerbotAI* ai) : AttackAction(ai, "attack web wrap") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WatchersTargetAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WatchersTargetAction(PlayerbotAI* ai) : AttackAction(ai, "krik'thir priority") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AnubarakDodgePoundAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnubarakDodgePoundAction(PlayerbotAI* ai) : AttackAction(ai, "anub'arak dodge pound") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "AzjolNerubMultipliers.h"
|
||||||
|
#include "AzjolNerubActions.h"
|
||||||
|
#include "GenericSpellActions.h"
|
||||||
|
#include "ChooseTargetActions.h"
|
||||||
|
#include "MovementActions.h"
|
||||||
|
#include "AzjolNerubTriggers.h"
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
float KrikthirMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
// Target is not findable from threat table using AI_VALUE2(),
|
||||||
|
// therefore need to search manually for the unit name
|
||||||
|
Unit* boss = nullptr;
|
||||||
|
Unit* watcher = nullptr;
|
||||||
|
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) { continue; }
|
||||||
|
|
||||||
|
switch (unit->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_KRIKTHIR:
|
||||||
|
boss = unit;
|
||||||
|
continue;
|
||||||
|
case NPC_WATCHER_SILTHIK:
|
||||||
|
case NPC_WATCHER_GASHRA:
|
||||||
|
case NPC_WATCHER_NARJIL:
|
||||||
|
case NPC_WATCHER_SKIRMISHER:
|
||||||
|
case NPC_WATCHER_SHADOWCASTER:
|
||||||
|
case NPC_WATCHER_WARRIOR:
|
||||||
|
watcher = unit;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boss && watcher)
|
||||||
|
{
|
||||||
|
// Do not target swap
|
||||||
|
// TODO: Need to suppress AoE actions but unsure how to identify them
|
||||||
|
if (dynamic_cast<DpsAssistAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
// Doesn't seem to work
|
||||||
|
// if (action->getThreatType() == Action::ActionThreatType::Aoe)
|
||||||
|
// {
|
||||||
|
// bot->Yell("Suppressed AoE", LANG_UNIVERSAL);
|
||||||
|
// return 0.0f;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANMULTIPLIERS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANMULTIPLIERS_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
|
||||||
|
class KrikthirMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KrikthirMultiplier(PlayerbotAI* ai) : Multiplier(ai, "krik'thir the gatewatcher") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "AzjolNerubStrategy.h"
|
||||||
|
#include "AzjolNerubMultipliers.h"
|
||||||
|
|
||||||
|
|
||||||
|
void WotlkDungeonANStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||||
|
{
|
||||||
|
// Krik'thir the Gatewatcher
|
||||||
|
// TODO: Add CC trigger while web wraps are casting?
|
||||||
|
// TODO: Bring healer closer than ranged dps to avoid fixates?
|
||||||
|
triggers.push_back(new TriggerNode("krik'thir web wrap",
|
||||||
|
NextAction::array(0, new NextAction("attack web wrap", ACTION_RAID + 5), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("krik'thir watchers",
|
||||||
|
NextAction::array(0, new NextAction("krik'thir priority", ACTION_RAID + 4), nullptr)));
|
||||||
|
|
||||||
|
// Hadronox
|
||||||
|
// The core AC triggers are very buggy with this boss, but default strat seems to play correctly
|
||||||
|
|
||||||
|
//Anub'arak
|
||||||
|
// TODO: No clear way to track these spikes. They don't seem to appear as gameobjects or triggers,
|
||||||
|
// and cast time is instant so no way to check currently casting location.
|
||||||
|
// May need to hook boss AI.. might be able to just heal through it for now.
|
||||||
|
// triggers.push_back(new TriggerNode("anub'arak impale",
|
||||||
|
// NextAction::array(0, new NextAction("TODO", ACTION_MOVE + 5), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("anub'arak pound",
|
||||||
|
NextAction::array(0, new NextAction("dodge pound", ACTION_MOVE + 5), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WotlkDungeonANStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||||
|
{
|
||||||
|
multipliers.push_back(new KrikthirMultiplier(botAI));
|
||||||
|
}
|
||||||
18
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h
Normal file
18
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubStrategy.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANSTRATEGY_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "Strategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WotlkDungeonANStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonANStrategy(PlayerbotAI* ai) : Strategy(ai) {}
|
||||||
|
virtual std::string const getName() override { return "azjol-nerub"; }
|
||||||
|
virtual void InitTriggers(std::vector<TriggerNode*> &triggers) override;
|
||||||
|
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANTRIGGERCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANTRIGGERCONTEXT_H
|
||||||
|
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "AzjolNerubTriggers.h"
|
||||||
|
|
||||||
|
class WotlkDungeonANTriggerContext : public NamedObjectContext<Trigger>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonANTriggerContext()
|
||||||
|
{
|
||||||
|
creators["krik'thir web wrap"] = &WotlkDungeonANTriggerContext::krikthir_web_wrap;
|
||||||
|
creators["krik'thir watchers"] = &WotlkDungeonANTriggerContext::krikthir_watchers;
|
||||||
|
// creators["anub'arak impale"] = &WotlkDungeonANTriggerContext::anubarak_impale;
|
||||||
|
creators["anub'arak pound"] = &WotlkDungeonANTriggerContext::anubarak_pound;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Trigger* krikthir_web_wrap(PlayerbotAI* ai) { return new KrikthirWebWrapTrigger(ai); }
|
||||||
|
static Trigger* krikthir_watchers(PlayerbotAI* ai) { return new KrikthirWatchersTrigger(ai); }
|
||||||
|
// static Trigger* anubarak_impale(PlayerbotAI* ai) { return new AnubarakImpaleTrigger(ai); }
|
||||||
|
static Trigger* anubarak_pound(PlayerbotAI* ai) { return new AnubarakPoundTrigger(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "AzjolNerubTriggers.h"
|
||||||
|
#include "AiObject.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool KrikthirWebWrapTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot)) { return false; }
|
||||||
|
|
||||||
|
// 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_WEB_WRAP)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KrikthirWatchersTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!botAI->IsDps(bot)) { return false; }
|
||||||
|
|
||||||
|
// 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_KRIKTHIR)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool AnubarakImpaleTrigger::IsActive()
|
||||||
|
// {
|
||||||
|
// Unit* boss = AI_VALUE2(Unit*, "find target", "anub'arak");
|
||||||
|
// if (!boss) { return false; }
|
||||||
|
// GuidVector triggers = AI_VALUE(GuidVector, "possible triggers");
|
||||||
|
// for (auto i = triggers.begin(); i != triggers.end(); i++)
|
||||||
|
// {
|
||||||
|
// Unit* unit = botAI->GetUnit(*i);
|
||||||
|
|
||||||
|
// if (unit)
|
||||||
|
// {
|
||||||
|
// bot->Yell("TRIGGER="+unit->GetName(), LANG_UNIVERSAL);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool AnubarakPoundTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "anub'arak");
|
||||||
|
if (!boss) { return false; }
|
||||||
|
|
||||||
|
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_POUND);
|
||||||
|
}
|
||||||
61
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.h
Normal file
61
src/strategy/dungeons/wotlk/azjolnerub/AzjolNerubTriggers.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONANTRIGGERS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONANTRIGGERS_H
|
||||||
|
|
||||||
|
#include "Trigger.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
|
#include "GenericTriggers.h"
|
||||||
|
#include "DungeonStrategyUtils.h"
|
||||||
|
|
||||||
|
enum AzjolNerubIDs
|
||||||
|
{
|
||||||
|
// Krik'thir the Gatewatcher
|
||||||
|
NPC_KRIKTHIR = 28684,
|
||||||
|
NPC_WATCHER_SILTHIK = 28731,
|
||||||
|
NPC_WATCHER_GASHRA = 28730,
|
||||||
|
NPC_WATCHER_NARJIL = 28729,
|
||||||
|
NPC_WATCHER_SKIRMISHER = 28734,
|
||||||
|
NPC_WATCHER_SHADOWCASTER = 28733,
|
||||||
|
NPC_WATCHER_WARRIOR = 28732,
|
||||||
|
DEBUFF_WEB_WRAP = 52086,
|
||||||
|
NPC_WEB_WRAP = 28619,
|
||||||
|
|
||||||
|
// Anub'arak
|
||||||
|
// Not sure how to track this - first one is cast as a buff on himself,
|
||||||
|
// which triggers periodic casts of the spikes spell.
|
||||||
|
SPELL_IMPALE_PERIODIC = 53456,
|
||||||
|
SPELL_IMPALE_SPIKES = 53457,
|
||||||
|
SPELL_POUND_N = 53472,
|
||||||
|
SPELL_POUND_H = 59433,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SPELL_POUND DUNGEON_MODE(bot, SPELL_POUND_N, SPELL_POUND_H)
|
||||||
|
|
||||||
|
class KrikthirWebWrapTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KrikthirWebWrapTrigger(PlayerbotAI* ai) : Trigger(ai, "krik'thir web wrap") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KrikthirWatchersTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KrikthirWatchersTrigger(PlayerbotAI* ai) : Trigger(ai, "krik'thir watchers") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// class AnubarakImpaleTrigger : public Trigger
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// AnubarakImpaleTrigger(PlayerbotAI* ai) : Trigger(ai, "anub'arak impale") {}
|
||||||
|
// bool IsActive() override;
|
||||||
|
// };
|
||||||
|
|
||||||
|
class AnubarakPoundTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnubarakPoundTrigger(PlayerbotAI* ai) : Trigger(ai, "anub'arak pound") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user