mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge pull request #560 from Bobblybook/master
Wotlk dungeon structure & Utgarde Keep
This commit is contained in:
@@ -1529,12 +1529,60 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster)
|
|||||||
case 533:
|
case 533:
|
||||||
strategyName = "naxx";
|
strategyName = "naxx";
|
||||||
break;
|
break;
|
||||||
|
case 574:
|
||||||
|
strategyName = "wotlk-uk"; // Utgarde Keep
|
||||||
|
break;
|
||||||
|
case 575:
|
||||||
|
strategyName = "wotlk-up"; // Utgarde Pinnacle
|
||||||
|
break;
|
||||||
|
case 576:
|
||||||
|
strategyName = "wotlk-nex"; // The Nexus
|
||||||
|
break;
|
||||||
|
case 578:
|
||||||
|
strategyName = "wotlk-occ"; // The Oculus
|
||||||
|
break;
|
||||||
|
case 595:
|
||||||
|
strategyName = "wotlk-cos"; // The Culling of Stratholme
|
||||||
|
break;
|
||||||
|
case 599:
|
||||||
|
strategyName = "wotlk-hos"; // Halls of Stone
|
||||||
|
break;
|
||||||
|
case 600:
|
||||||
|
strategyName = "wotlk-dtk"; // Drak'Tharon Keep
|
||||||
|
break;
|
||||||
|
case 601:
|
||||||
|
strategyName = "wotlk-an"; // Azjol-Nerub
|
||||||
|
break;
|
||||||
|
case 602:
|
||||||
|
strategyName = "wotlk-hol"; // Halls of Lightning
|
||||||
|
break;
|
||||||
case 603:
|
case 603:
|
||||||
strategyName = "uld";
|
strategyName = "uld";
|
||||||
break;
|
break;
|
||||||
|
case 604:
|
||||||
|
strategyName = "wotlk-gd"; // Gundrak
|
||||||
|
break;
|
||||||
|
case 608:
|
||||||
|
strategyName = "wotlk-vh"; // Violet Hold
|
||||||
|
break;
|
||||||
|
case 619:
|
||||||
|
strategyName = "wotlk-ok"; // Ahn'kahet: The Old Kingdom
|
||||||
|
break;
|
||||||
case 631:
|
case 631:
|
||||||
strategyName = "icc";
|
strategyName = "icc";
|
||||||
break;
|
break;
|
||||||
|
case 632:
|
||||||
|
strategyName = "wotlk-fos"; // The Forge of Souls
|
||||||
|
break;
|
||||||
|
case 650:
|
||||||
|
strategyName = "wotlk-toc"; // Trial of the Champion
|
||||||
|
break;
|
||||||
|
case 658:
|
||||||
|
strategyName = "wotlk-pos"; // Pit of Saron
|
||||||
|
break;
|
||||||
|
case 668:
|
||||||
|
strategyName = "wotlk-hor"; // Halls of Reflection
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#include "raids/moltencore/RaidMcTriggerContext.h"
|
#include "raids/moltencore/RaidMcTriggerContext.h"
|
||||||
#include "raids/aq20/RaidAq20ActionContext.h"
|
#include "raids/aq20/RaidAq20ActionContext.h"
|
||||||
#include "raids/aq20/RaidAq20TriggerContext.h"
|
#include "raids/aq20/RaidAq20TriggerContext.h"
|
||||||
|
#include "dungeons/DungeonStrategyContext.h"
|
||||||
|
#include "dungeons/wotlk/WotlkDungeonActionContext.h"
|
||||||
|
#include "dungeons/wotlk/WotlkDungeonTriggerContext.h"
|
||||||
|
|
||||||
AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
||||||
{
|
{
|
||||||
@@ -36,6 +39,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
strategyContexts.Add(new AssistStrategyContext());
|
strategyContexts.Add(new AssistStrategyContext());
|
||||||
strategyContexts.Add(new QuestStrategyContext());
|
strategyContexts.Add(new QuestStrategyContext());
|
||||||
strategyContexts.Add(new RaidStrategyContext());
|
strategyContexts.Add(new RaidStrategyContext());
|
||||||
|
strategyContexts.Add(new DungeonStrategyContext());
|
||||||
|
|
||||||
actionContexts.Add(new ActionContext());
|
actionContexts.Add(new ActionContext());
|
||||||
actionContexts.Add(new ChatActionContext());
|
actionContexts.Add(new ChatActionContext());
|
||||||
@@ -46,6 +50,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
actionContexts.Add(new RaidNaxxActionContext());
|
actionContexts.Add(new RaidNaxxActionContext());
|
||||||
actionContexts.Add(new RaidUlduarActionContext());
|
actionContexts.Add(new RaidUlduarActionContext());
|
||||||
actionContexts.Add(new RaidIccActionContext());
|
actionContexts.Add(new RaidIccActionContext());
|
||||||
|
actionContexts.Add(new WotlkDungeonUKActionContext());
|
||||||
|
|
||||||
triggerContexts.Add(new TriggerContext());
|
triggerContexts.Add(new TriggerContext());
|
||||||
triggerContexts.Add(new ChatTriggerContext());
|
triggerContexts.Add(new ChatTriggerContext());
|
||||||
@@ -56,6 +61,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
triggerContexts.Add(new RaidNaxxTriggerContext());
|
triggerContexts.Add(new RaidNaxxTriggerContext());
|
||||||
triggerContexts.Add(new RaidUlduarTriggerContext());
|
triggerContexts.Add(new RaidUlduarTriggerContext());
|
||||||
triggerContexts.Add(new RaidIccTriggerContext());
|
triggerContexts.Add(new RaidIccTriggerContext());
|
||||||
|
triggerContexts.Add(new WotlkDungeonUKTriggerContext());
|
||||||
|
|
||||||
valueContexts.Add(new ValueContext());
|
valueContexts.Add(new ValueContext());
|
||||||
|
|
||||||
|
|||||||
96
src/strategy/dungeons/DungeonStrategyContext.h
Normal file
96
src/strategy/dungeons/DungeonStrategyContext.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#ifndef _PLAYERBOT_DUNGEONSTRATEGYCONTEXT_H_
|
||||||
|
#define _PLAYERBOT_DUNGEONSTRATEGYCONTEXT_H_
|
||||||
|
|
||||||
|
#include "Strategy.h"
|
||||||
|
#include "wotlk/utgardekeep/UtgardeKeepStrategy.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Full list/TODO:
|
||||||
|
|
||||||
|
The Nexus - Nex
|
||||||
|
Grand Magus Telestra, Anomalus, Ormorok the Tree-Shaper, Keristrasza, Commander Stoutbeard (Horde Heroic Only)/Commander Kolurg (Alliance Heroic Only)
|
||||||
|
Azjol-Nerub: Azjol-Nerub - AN
|
||||||
|
Krik'thir the Gatewatcher, Hadronox, Anub'arak
|
||||||
|
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
|
||||||
|
Erekem, Moragg, Ichoron, Xevozz, Lavanthor, Zuramat the Obliterator, Cyanigosa
|
||||||
|
Gundrak - GD
|
||||||
|
Slad'ran, Drakkari Colossus, Moorabi, Gal'darah, Eck the Ferocious (Heroic only)
|
||||||
|
Halls of Stone - HoS
|
||||||
|
Maiden of Grief, Krystallus, Tribunal of Ages, Sjonnir The Ironshaper
|
||||||
|
Halls of Lightning - HoL
|
||||||
|
General Bjarngrim, Volkhan, Ionar, Loken
|
||||||
|
The Oculus - Occ
|
||||||
|
Drakos the Interrogator, Varos Cloudstrider, Mage-Lord Urom, Ley-Guardian Eregos
|
||||||
|
Utgarde Pinnacle - UP
|
||||||
|
Svala Sorrowgrave, Gortok Palehoof, Skadi the Ruthless, King Ymiron
|
||||||
|
The Culling of Stratholme - CoS
|
||||||
|
Meathook, Salramm the Fleshcrafter, Chrono-Lord Epoch, Mal'Ganis, Infinite Corruptor (Heroic only)
|
||||||
|
Trial of the Champion - ToC
|
||||||
|
Alliance Champions: Deathstalker Visceri, Eressea Dawnsinger, Mokra the Skullcrusher, Runok Wildmane, Zul'tore
|
||||||
|
Horde Champions: Ambrose Boltspark, Colosos, Jacob Alerius, Jaelyne Evensong, Lana Stouthammer
|
||||||
|
Argent Champion: Argent Confessor Paletress/Eadric the Pure
|
||||||
|
The Black Knight
|
||||||
|
Halls of Reflection - HoR
|
||||||
|
Falric, Marwyn, The Lich King
|
||||||
|
Pit of Saron - PoS
|
||||||
|
Forgemaster Garfrost, Krick & Ick, Scourgelord Tyrannus
|
||||||
|
The Forge of Souls - FoS
|
||||||
|
Bronjahm, Devourer of Souls
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DungeonStrategyContext : public NamedObjectContext<Strategy>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DungeonStrategyContext() : NamedObjectContext<Strategy>(false, true)
|
||||||
|
{
|
||||||
|
// Vanilla
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Burning Crusade
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Wrath of the Lich King
|
||||||
|
creators["wotlk-uk"] = &DungeonStrategyContext::wotlk_uk; // Utgarde Keep
|
||||||
|
creators["wotlk-nex"] = &DungeonStrategyContext::wotlk_nex; // The Nexus
|
||||||
|
creators["wotlk-an"] = &DungeonStrategyContext::wotlk_an; // Azjol-Nerub
|
||||||
|
creators["wotlk-ok"] = &DungeonStrategyContext::wotlk_ok; // Ahn'kahet: The Old Kingdom
|
||||||
|
creators["wotlk-dtk"] = &DungeonStrategyContext::wotlk_dtk; // Drak'Tharon Keep
|
||||||
|
creators["wotlk-vh"] = &DungeonStrategyContext::wotlk_vh; // The Violet Hold
|
||||||
|
creators["wotlk-gd"] = &DungeonStrategyContext::wotlk_gd; // Gundrak
|
||||||
|
creators["wotlk-hos"] = &DungeonStrategyContext::wotlk_hos; // Halls of Stone
|
||||||
|
creators["wotlk-hol"] = &DungeonStrategyContext::wotlk_hol; // Halls of Lightning
|
||||||
|
creators["wotlk-occ"] = &DungeonStrategyContext::wotlk_occ; // The Oculus
|
||||||
|
creators["wotlk-up"] = &DungeonStrategyContext::wotlk_up; // Utgarde Pinnacle
|
||||||
|
creators["wotlk-cos"] = &DungeonStrategyContext::wotlk_cos; // The Culling of Stratholme
|
||||||
|
creators["wotlk-toc"] = &DungeonStrategyContext::wotlk_toc; // Trial of the Champion
|
||||||
|
creators["wotlk-hor"] = &DungeonStrategyContext::wotlk_hor; // Halls of Reflection
|
||||||
|
creators["wotlk-pos"] = &DungeonStrategyContext::wotlk_pos; // Pit of Saron
|
||||||
|
creators["wotlk-fos"] = &DungeonStrategyContext::wotlk_fos; // The Forge of Souls
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Strategy* wotlk_uk(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_nex(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_an(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_vh(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_gd(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_hos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_hol(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_occ(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_up(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_cos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_toc(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_hor(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_pos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_fos(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
21
src/strategy/dungeons/DungeonStrategyUtils.h
Normal file
21
src/strategy/dungeons/DungeonStrategyUtils.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _PLAYERBOT_DUNGEONUTILS_H_
|
||||||
|
#define _PLAYERBOT_DUNGEONUTILS_H_
|
||||||
|
|
||||||
|
|
||||||
|
template<class T> inline
|
||||||
|
const T& DUNGEON_MODE(Player* bot, const T& normal5, const T& heroic10)
|
||||||
|
{
|
||||||
|
switch (bot->GetMap()->GetDifficulty())
|
||||||
|
{
|
||||||
|
case DUNGEON_DIFFICULTY_NORMAL:
|
||||||
|
return normal5;
|
||||||
|
case DUNGEON_DIFFICULTY_HEROIC:
|
||||||
|
return heroic10;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return heroic10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
21
src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h
Normal file
21
src/strategy/dungeons/wotlk/WotlkDungeonActionContext.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONACTIONCONTEXT_H_
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONACTIONCONTEXT_H_
|
||||||
|
|
||||||
|
#include "utgardekeep/UtgardeKeepActionContext.h"
|
||||||
|
// #include "nexus/NexusActionContext.h"
|
||||||
|
// #include "azjolnerub/AzjolNerubActionContext.h"
|
||||||
|
// #include "oldkingdom/OldKingdomActionContext.h"
|
||||||
|
// #include "draktharonkeep/DraktharonKeepActionContext.h"
|
||||||
|
// #include "violethold/VioletHoldActionContext.h"
|
||||||
|
// #include "gundrak/GundrakActionContext.h"
|
||||||
|
// #include "hallsofstone/HallsOfStoneActionContext.h"
|
||||||
|
// #include "hallsoflightning/HallsOfLightningActionContext.h"
|
||||||
|
// #include "oculus/OculusActionContext.h"
|
||||||
|
// #include "utgardepinnacle/UtgardePinnacleActionContext.h"
|
||||||
|
// #include "cullingofstratholme/CullingOfStratholmeActionContext.h"
|
||||||
|
// #include "trialofthechampion/TrialOfTheChampionActionContext.h"
|
||||||
|
// #include "hallsofreflection/HallsOfReflectionActionContext.h"
|
||||||
|
// #include "pitofsaron/PitOfSaronActionContext.h"
|
||||||
|
// #include "forgeofsouls/ForgeOfSoulsActionContext.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
21
src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
Normal file
21
src/strategy/dungeons/wotlk/WotlkDungeonTriggerContext.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONTRIGGERCONTEXT_H_
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONTRIGGERCONTEXT_H_
|
||||||
|
|
||||||
|
#include "utgardekeep/UtgardeKeepTriggerContext.h"
|
||||||
|
// #include "nexus/NexusTriggerContext.h"
|
||||||
|
// #include "azjolnerub/AzjolNerubTriggerContext.h"
|
||||||
|
// #include "oldkingdom/OldKingdomTriggerContext.h"
|
||||||
|
// #include "draktharonkeep/DraktharonKeepTriggerContext.h"
|
||||||
|
// #include "violethold/VioletHoldTriggerContext.h"
|
||||||
|
// #include "gundrak/GundrakTriggerContext.h"
|
||||||
|
// #include "hallsofstone/HallsOfStoneTriggerContext.h"
|
||||||
|
// #include "hallsoflightning/HallsOfLightningTriggerContext.h"
|
||||||
|
// #include "oculus/OculusTriggerContext.h"
|
||||||
|
// #include "utgardepinnacle/UtgardePinnacleTriggerContext.h"
|
||||||
|
// #include "cullingofstratholme/CullingOfStratholmeTriggerContext.h"
|
||||||
|
// #include "trialofthechampion/TrialOfTheChampionTriggerContext.h"
|
||||||
|
// #include "hallsofreflection/HallsOfReflectionTriggerContext.h"
|
||||||
|
// #include "pitofsaron/PitOfSaronTriggerContext.h"
|
||||||
|
// #include "forgeofsouls/ForgeOfSoulsTriggerContext.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
0
src/strategy/dungeons/wotlk/azjolnerub/TODO
Normal file
0
src/strategy/dungeons/wotlk/azjolnerub/TODO
Normal file
0
src/strategy/dungeons/wotlk/draktharonkeep/TODO
Normal file
0
src/strategy/dungeons/wotlk/draktharonkeep/TODO
Normal file
0
src/strategy/dungeons/wotlk/forgeofsouls/TODO
Normal file
0
src/strategy/dungeons/wotlk/forgeofsouls/TODO
Normal file
0
src/strategy/dungeons/wotlk/gundrak/TODO
Normal file
0
src/strategy/dungeons/wotlk/gundrak/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsoflightning/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsoflightning/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsofreflection/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsofreflection/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsofstone/TODO
Normal file
0
src/strategy/dungeons/wotlk/hallsofstone/TODO
Normal file
0
src/strategy/dungeons/wotlk/nexus/TODO
Normal file
0
src/strategy/dungeons/wotlk/nexus/TODO
Normal file
0
src/strategy/dungeons/wotlk/oculus/TODO
Normal file
0
src/strategy/dungeons/wotlk/oculus/TODO
Normal file
0
src/strategy/dungeons/wotlk/oldkingdom/TODO
Normal file
0
src/strategy/dungeons/wotlk/oldkingdom/TODO
Normal file
0
src/strategy/dungeons/wotlk/pitofsaron/TODO
Normal file
0
src/strategy/dungeons/wotlk/pitofsaron/TODO
Normal file
0
src/strategy/dungeons/wotlk/trialofthechampion/TODO
Normal file
0
src/strategy/dungeons/wotlk/trialofthechampion/TODO
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONUKACTIONCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONUKACTIONCONTEXT_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "UtgardeKeepActions.h"
|
||||||
|
|
||||||
|
class WotlkDungeonUKActionContext : public NamedObjectContext<Action>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonUKActionContext() {
|
||||||
|
creators["attack frost tomb"] = &WotlkDungeonUKActionContext::attack_frost_tomb;
|
||||||
|
creators["attack dalronn"] = &WotlkDungeonUKActionContext::attack_dalronn;
|
||||||
|
creators["ingvar stop casting"] = &WotlkDungeonUKActionContext::ingvar_stop_casting;
|
||||||
|
creators["ingvar get behind"] = &WotlkDungeonUKActionContext::ingvar_get_behind;
|
||||||
|
// creators["ingvar hide los"] = &WotlkDungeonUKActionContext::ingvar_hide_los;
|
||||||
|
creators["ingvar dodge smash"] = &WotlkDungeonUKActionContext::ingvar_dodge_smash;
|
||||||
|
creators["ingvar smash return"] = &WotlkDungeonUKActionContext::ingvar_smash_return;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Action* attack_frost_tomb(PlayerbotAI* ai) { return new AttackFrostTombAction(ai); }
|
||||||
|
static Action* attack_dalronn(PlayerbotAI* ai) { return new AttackDalronnAction(ai); }
|
||||||
|
static Action* ingvar_stop_casting(PlayerbotAI* ai) { return new IngvarStopCastingAction(ai); }
|
||||||
|
static Action* ingvar_get_behind(PlayerbotAI* ai) { return new SetBehindTargetAction(ai); }
|
||||||
|
// static Action* ingvar_hide_los(PlayerbotAI* ai) { return new TellLosAction(ai); }
|
||||||
|
static Action* ingvar_dodge_smash(PlayerbotAI* ai) { return new IngvarDodgeSmashAction(ai); }
|
||||||
|
static Action* ingvar_smash_return(PlayerbotAI* ai) { return new IngvarSmashReturnAction(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "UtgardeKeepActions.h"
|
||||||
|
#include "UtgardeKeepStrategy.h"
|
||||||
|
|
||||||
|
bool AttackFrostTombAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* frostTomb = 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->GetName() == "Frost Tomb")
|
||||||
|
{
|
||||||
|
frostTomb = unit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!frostTomb || AI_VALUE(Unit*, "current target") == frostTomb)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Attack(frostTomb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Possibly add player stacking behaviour close to tank, to prevent Skarvald charging ranged
|
||||||
|
bool AttackDalronnAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller");
|
||||||
|
if (!boss || AI_VALUE(Unit*, "current target") == boss)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Attack(boss);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarStopCastingAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
// Doesn't work, this action gets queued behind the current spell instead of interrupting it
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 my_spell_id = AI_VALUE(uint32, "active spell");
|
||||||
|
if (!my_spell_id || my_spell_id == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Spell* spell = bot->FindCurrentSpellBySpellId(my_spell_id);
|
||||||
|
if (!spell)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bot->Yell("cancelling spell="+std::to_string(my_spell_id), LANG_UNIVERSAL);
|
||||||
|
bot->InterruptSpell(spell->GetCurrentContainer(), false, true, true);
|
||||||
|
|
||||||
|
// Can slightly optimise by allowing bot to keep casting if they will finish the cast
|
||||||
|
// before boss spell goes off, however need to hook boss AI for cast remaining.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarDodgeSmashAction::isUseful() { return !AI_VALUE2(bool, "behind", "current target"); }
|
||||||
|
bool IngvarDodgeSmashAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarSmashReturnAction::isUseful() { return AI_VALUE2(bool, "behind", "current target"); }
|
||||||
|
bool IngvarSmashReturnAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance = bot->GetExactDist2d(boss->GetPosition());
|
||||||
|
return Move(bot->GetAngle(boss), distance + bot->GetMeleeReach());
|
||||||
|
}
|
||||||
47
src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.h
Normal file
47
src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepActions.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONUKACTIONS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONUKACTIONS_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "AttackAction.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "UtgardeKeepTriggers.h"
|
||||||
|
|
||||||
|
class AttackFrostTombAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AttackFrostTombAction(PlayerbotAI* ai) : AttackAction(ai, "attack frost tomb") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttackDalronnAction : public AttackAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AttackDalronnAction(PlayerbotAI* ai) : AttackAction(ai, "attack dalronn") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarStopCastingAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarStopCastingAction(PlayerbotAI* ai) : Action(ai, "ingvar stop casting") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarDodgeSmashAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarDodgeSmashAction(PlayerbotAI* ai) : MovementAction(ai, "ingvar dodge smash") {}
|
||||||
|
bool isUseful() override;
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarSmashReturnAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarSmashReturnAction(PlayerbotAI* ai) : MovementAction(ai, "ingvar smash return") {}
|
||||||
|
bool isUseful() override;
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
#include "UtgardeKeepMultipliers.h"
|
||||||
|
#include "UtgardeKeepActions.h"
|
||||||
|
#include "GenericSpellActions.h"
|
||||||
|
#include "ChooseTargetActions.h"
|
||||||
|
#include "UtgardeKeepTriggers.h"
|
||||||
|
|
||||||
|
float PrinceKelesethMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "prince keleseth");
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
if (dynamic_cast<DpsAssistAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
float SkarvaldAndDalronnMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
// Unit* skarvald = AI_VALUE2(Unit*, "find target", "skarvald the constructor");
|
||||||
|
Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller");
|
||||||
|
|
||||||
|
if (!dalronn)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic_cast<DpsAssistAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float IngvarThePlundererMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
bool isTank = botAI->IsTank(bot);
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent movement actions overriding current movement, we're probably dodging a slam
|
||||||
|
if (isTank && bot->isMoving() && dynamic_cast<MovementAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If boss is casting a roar, do not allow beginning a spell cast that is non-instant
|
||||||
|
if (boss->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
if (boss->FindCurrentSpellBySpellId(SPELL_STAGGERING_ROAR) ||
|
||||||
|
boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR))
|
||||||
|
{
|
||||||
|
if (dynamic_cast<CastSpellAction*>(action))
|
||||||
|
{
|
||||||
|
uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName());
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!spellInfo)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 castTime = spellInfo->CalcCastTime(bot);
|
||||||
|
if (castTime != 0)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Done with non-tank logic
|
||||||
|
if (!isTank)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
// TANK ONLY
|
||||||
|
if (boss->FindCurrentSpellBySpellId(SPELL_SMASH) ||
|
||||||
|
boss->FindCurrentSpellBySpellId(SPELL_DARK_SMASH))
|
||||||
|
{
|
||||||
|
// Prevent movement actions during smash which can mess up boss position.
|
||||||
|
// Allow through IngvarDodgeSmashAction only, as well as any non-movement actions.
|
||||||
|
if (dynamic_cast<MovementAction*>(action) && !dynamic_cast<IngvarDodgeSmashAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _PLAYERRBOT_WOTLKDUNGEONUKMULTIPLIERS_H_
|
||||||
|
#define _PLAYERRBOT_WOTLKDUNGEONUKMULTIPLIERS_H_
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
|
||||||
|
class PrinceKelesethMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrinceKelesethMultiplier(PlayerbotAI* ai) : Multiplier(ai, "prince keleseth") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SkarvaldAndDalronnMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SkarvaldAndDalronnMultiplier(PlayerbotAI* ai) : Multiplier(ai, "skarvald and dalronn") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarThePlundererMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarThePlundererMultiplier(PlayerbotAI* ai) : Multiplier(ai, "ingvar the plunderer") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include "UtgardeKeepStrategy.h"
|
||||||
|
#include "UtgardeKeepMultipliers.h"
|
||||||
|
|
||||||
|
|
||||||
|
void WotlkDungeonUKStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||||
|
{
|
||||||
|
// Prince Keleseth
|
||||||
|
triggers.push_back(new TriggerNode("keleseth frost tomb",
|
||||||
|
NextAction::array(0, new NextAction("attack frost tomb", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
|
// Skarvald the Constructor & Dalronn the Controller
|
||||||
|
triggers.push_back(new TriggerNode("dalronn priority",
|
||||||
|
NextAction::array(0, new NextAction("attack dalronn", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
|
// Ingvar the Plunderer
|
||||||
|
|
||||||
|
// Doesn't work yet, this action doesn't get processed until the existing cast finishes
|
||||||
|
// triggers.push_back(new TriggerNode("ingvar staggering roar",
|
||||||
|
// NextAction::array(0, new NextAction("ingvar stop casting", ACTION_RAID + 1), nullptr)));
|
||||||
|
|
||||||
|
// No easy way to check LoS here, the pillars do not seem to count as gameobjects.
|
||||||
|
// Not implemented for now, unsure if this is needed as a good group can probably burst through the boss
|
||||||
|
// and just eat the debuff.
|
||||||
|
// triggers.push_back(new TriggerNode("ingvar dreadful roar",
|
||||||
|
// NextAction::array(0, new NextAction("ingvar hide los", ACTION_RAID + 1), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("ingvar smash tank",
|
||||||
|
NextAction::array(0, new NextAction("ingvar dodge smash", ACTION_MOVE + 5), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("ingvar smash tank return",
|
||||||
|
NextAction::array(0, new NextAction("ingvar smash return", ACTION_MOVE + 5), nullptr)));
|
||||||
|
// Buggy... if not behind target, ai can get stuck running towards and away from target.
|
||||||
|
// I think for ranged chars, a custom action should be added that doesn't attempt to run into melee.
|
||||||
|
// This is a bandaid for now, needs to be improved.
|
||||||
|
triggers.push_back(new TriggerNode("not behind ingvar",
|
||||||
|
NextAction::array(0, new NextAction("set behind", ACTION_MOVE + 1), nullptr)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WotlkDungeonUKStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||||
|
{
|
||||||
|
multipliers.push_back(new PrinceKelesethMultiplier(botAI));
|
||||||
|
multipliers.push_back(new SkarvaldAndDalronnMultiplier(botAI));
|
||||||
|
multipliers.push_back(new IngvarThePlundererMultiplier(botAI));
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONUKSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONUKSTRATEGY_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "Strategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WotlkDungeonUKStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonUKStrategy(PlayerbotAI* ai) : Strategy(ai) {}
|
||||||
|
virtual std::string const getName() override { return "utgarde keep"; }
|
||||||
|
virtual void InitTriggers(std::vector<TriggerNode*> &triggers) override;
|
||||||
|
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONUKTRIGGERCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONUKTRIGGERCONTEXT_H
|
||||||
|
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "UtgardeKeepTriggers.h"
|
||||||
|
|
||||||
|
class WotlkDungeonUKTriggerContext : public NamedObjectContext<Trigger>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonUKTriggerContext()
|
||||||
|
{
|
||||||
|
creators["keleseth frost tomb"] = &WotlkDungeonUKTriggerContext::keleseth_frost_tomb;
|
||||||
|
creators["dalronn priority"] = &WotlkDungeonUKTriggerContext::dalronn_priority_target;
|
||||||
|
creators["ingvar staggering roar"] = &WotlkDungeonUKTriggerContext::ingvar_staggering_roar;
|
||||||
|
creators["ingvar dreadful roar"] = &WotlkDungeonUKTriggerContext::ingvar_dreadful_roar;
|
||||||
|
creators["ingvar smash tank"] = &WotlkDungeonUKTriggerContext::ingvar_smash_tank;
|
||||||
|
creators["ingvar smash tank return"] = &WotlkDungeonUKTriggerContext::ingvar_smash_tank_return;
|
||||||
|
creators["not behind ingvar"] = &WotlkDungeonUKTriggerContext::not_behind_ingvar;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Trigger* keleseth_frost_tomb(PlayerbotAI* ai) { return new KelesethFrostTombTrigger(ai); }
|
||||||
|
static Trigger* dalronn_priority_target(PlayerbotAI* ai) { return new DalronnNontankTrigger(ai); }
|
||||||
|
static Trigger* ingvar_staggering_roar(PlayerbotAI* ai) { return new IngvarStaggeringRoarTrigger(ai); }
|
||||||
|
static Trigger* ingvar_dreadful_roar(PlayerbotAI* ai) { return new IngvarDreadfulRoarTrigger(ai); }
|
||||||
|
static Trigger* ingvar_smash_tank(PlayerbotAI* ai) { return new IngvarSmashTankTrigger(ai); }
|
||||||
|
static Trigger* ingvar_smash_tank_return(PlayerbotAI* ai) { return new IngvarSmashTankReturnTrigger(ai); }
|
||||||
|
static Trigger* not_behind_ingvar(PlayerbotAI* ai) { return new NotBehindIngvarTrigger(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
104
src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp
Normal file
104
src/strategy/dungeons/wotlk/utgardekeep/UtgardeKeepTriggers.cpp
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "UtgardeKeepTriggers.h"
|
||||||
|
#include "AiObject.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
|
||||||
|
bool KelesethFrostTombTrigger::IsActive()
|
||||||
|
{
|
||||||
|
GuidVector members = AI_VALUE(GuidVector, "group members");
|
||||||
|
for (auto& member : members)
|
||||||
|
{
|
||||||
|
if (botAI->GetUnit(member)->HasAura(DEBUFF_FROST_TOMB))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DalronnNontankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller");
|
||||||
|
if (!dalronn)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !botAI->IsTank(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarStaggeringRoarTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (boss->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
if (boss->FindCurrentSpellBySpellId(SPELL_STAGGERING_ROAR))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarDreadfulRoarTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (boss->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
if (boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarSmashTankTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss || !botAI->IsTank(bot))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boss->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
if (boss->FindCurrentSpellBySpellId(SPELL_SMASH) ||
|
||||||
|
boss->FindCurrentSpellBySpellId(SPELL_DARK_SMASH))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IngvarSmashTankReturnTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
// if (!boss || !botAI->IsTank(bot) || boss->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
// Ignore casting state as Ingvar will sometimes chain-cast a roar after a smash..
|
||||||
|
// We don't want this to prevent our tank from repositioning properly.
|
||||||
|
if (!boss || !botAI->IsTank(bot))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotBehindIngvarTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
|
||||||
|
if (!boss || botAI->IsTank(bot))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AI_VALUE2(bool, "behind", "current target");
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONUKTRIGGERS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONUKTRIGGERS_H
|
||||||
|
|
||||||
|
#include "EventMap.h"
|
||||||
|
#include "Trigger.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
|
#include "GenericTriggers.h"
|
||||||
|
#include "DungeonStrategyUtils.h"
|
||||||
|
|
||||||
|
// Taken from:
|
||||||
|
// src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
|
||||||
|
enum eSpells
|
||||||
|
{
|
||||||
|
SPELL_SUMMON_VALKYR = 42912,
|
||||||
|
SPELL_RESURRECTION_BEAM = 42857,
|
||||||
|
SPELL_RESURRECTION_BALL = 42862,
|
||||||
|
SPELL_RESURRECTION_HEAL = 42704,
|
||||||
|
SPELL_INGVAR_TRANSFORM = 42796,
|
||||||
|
|
||||||
|
SPELL_STAGGERING_ROAR_N = 42708,
|
||||||
|
SPELL_STAGGERING_ROAR_H = 59708,
|
||||||
|
SPELL_CLEAVE = 42724,
|
||||||
|
SPELL_SMASH_N = 42669,
|
||||||
|
SPELL_SMASH_H = 59706,
|
||||||
|
SPELL_ENRAGE_N = 42705,
|
||||||
|
SPELL_ENRAGE_H = 59707,
|
||||||
|
|
||||||
|
SPELL_DREADFUL_ROAR_N = 42729,
|
||||||
|
SPELL_DREADFUL_ROAR_H = 59734,
|
||||||
|
SPELL_WOE_STRIKE_N = 42730,
|
||||||
|
SPELL_WOE_STRIKE_H = 59735,
|
||||||
|
SPELL_DARK_SMASH = 42723,
|
||||||
|
SPELL_SHADOW_AXE = 42749,
|
||||||
|
|
||||||
|
// Added
|
||||||
|
DEBUFF_FROST_TOMB = 48400,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SPELL_STAGGERING_ROAR DUNGEON_MODE(bot, SPELL_STAGGERING_ROAR_N, SPELL_STAGGERING_ROAR_H)
|
||||||
|
#define SPELL_DREADFUL_ROAR DUNGEON_MODE(bot, SPELL_DREADFUL_ROAR_N, SPELL_DREADFUL_ROAR_H)
|
||||||
|
#define SPELL_WOE_STRIKE DUNGEON_MODE(bot, SPELL_WOE_STRIKE_N, SPELL_WOE_STRIKE_H)
|
||||||
|
#define SPELL_SMASH DUNGEON_MODE(bot, SPELL_SMASH_N, SPELL_SMASH_H)
|
||||||
|
#define SPELL_ENRAGE DUNGEON_MODE(bot, SPELL_ENRAGE_N, SPELL_ENRAGE_H)
|
||||||
|
|
||||||
|
class KelesethFrostTombTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KelesethFrostTombTrigger(PlayerbotAI* ai) : Trigger(ai, "keleseth frost tomb") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DalronnNontankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DalronnNontankTrigger(PlayerbotAI* ai) : Trigger(ai, "dalronn non-tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarStaggeringRoarTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarStaggeringRoarTrigger(PlayerbotAI* ai) : Trigger(ai, "ingvar staggering roar") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarDreadfulRoarTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarDreadfulRoarTrigger(PlayerbotAI* ai) : Trigger(ai, "ingvar dreadful roar") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarSmashTankTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarSmashTankTrigger(PlayerbotAI* ai) : Trigger(ai, "ingvar smash tank") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngvarSmashTankReturnTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IngvarSmashTankReturnTrigger(PlayerbotAI* ai) : Trigger(ai, "ingvar smash tank return") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NotBehindIngvarTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NotBehindIngvarTrigger(PlayerbotAI* ai) : Trigger(ai, "not behind ingvar") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
0
src/strategy/dungeons/wotlk/utgardepinnacle/TODO
Normal file
0
src/strategy/dungeons/wotlk/utgardepinnacle/TODO
Normal file
0
src/strategy/dungeons/wotlk/violethold/TODO
Normal file
0
src/strategy/dungeons/wotlk/violethold/TODO
Normal file
Reference in New Issue
Block a user