mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -56,6 +56,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
actionContexts.Add(new WotlkDungeonOKActionContext());
|
actionContexts.Add(new WotlkDungeonOKActionContext());
|
||||||
actionContexts.Add(new WotlkDungeonDTKActionContext());
|
actionContexts.Add(new WotlkDungeonDTKActionContext());
|
||||||
actionContexts.Add(new WotlkDungeonVHActionContext());
|
actionContexts.Add(new WotlkDungeonVHActionContext());
|
||||||
|
actionContexts.Add(new WotlkDungeonGDActionContext());
|
||||||
|
|
||||||
triggerContexts.Add(new TriggerContext());
|
triggerContexts.Add(new TriggerContext());
|
||||||
triggerContexts.Add(new ChatTriggerContext());
|
triggerContexts.Add(new ChatTriggerContext());
|
||||||
@@ -72,6 +73,7 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
|||||||
triggerContexts.Add(new WotlkDungeonOKTriggerContext());
|
triggerContexts.Add(new WotlkDungeonOKTriggerContext());
|
||||||
triggerContexts.Add(new WotlkDungeonDTKTriggerContext());
|
triggerContexts.Add(new WotlkDungeonDTKTriggerContext());
|
||||||
triggerContexts.Add(new WotlkDungeonVHTriggerContext());
|
triggerContexts.Add(new WotlkDungeonVHTriggerContext());
|
||||||
|
triggerContexts.Add(new WotlkDungeonGDTriggerContext());
|
||||||
|
|
||||||
valueContexts.Add(new ValueContext());
|
valueContexts.Add(new ValueContext());
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,11 @@
|
|||||||
#include "wotlk/oldkingdom/OldKingdomStrategy.h"
|
#include "wotlk/oldkingdom/OldKingdomStrategy.h"
|
||||||
#include "wotlk/draktharonkeep/DrakTharonKeepStrategy.h"
|
#include "wotlk/draktharonkeep/DrakTharonKeepStrategy.h"
|
||||||
#include "wotlk/violethold/VioletHoldStrategy.h"
|
#include "wotlk/violethold/VioletHoldStrategy.h"
|
||||||
|
#include "wotlk/gundrak/GundrakStrategy.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Full list/TODO:
|
Full list/TODO:
|
||||||
|
|
||||||
Gundrak - GD
|
|
||||||
Slad'ran, Drakkari Colossus, Moorabi, Gal'darah, Eck the Ferocious (Heroic only)
|
|
||||||
Halls of Stone - HoS
|
Halls of Stone - HoS
|
||||||
Maiden of Grief, Krystallus, Tribunal of Ages, Sjonnir The Ironshaper
|
Maiden of Grief, Krystallus, Tribunal of Ages, Sjonnir The Ironshaper
|
||||||
Halls of Lightning - HoL
|
Halls of Lightning - HoL
|
||||||
@@ -76,8 +75,8 @@ class DungeonStrategyContext : public NamedObjectContext<Strategy>
|
|||||||
static Strategy* wotlk_ok(PlayerbotAI* botAI) { return new WotlkDungeonOKStrategy(botAI); }
|
static Strategy* wotlk_ok(PlayerbotAI* botAI) { return new WotlkDungeonOKStrategy(botAI); }
|
||||||
static Strategy* wotlk_dtk(PlayerbotAI* botAI) { return new WotlkDungeonDTKStrategy(botAI); }
|
static Strategy* wotlk_dtk(PlayerbotAI* botAI) { return new WotlkDungeonDTKStrategy(botAI); }
|
||||||
static Strategy* wotlk_vh(PlayerbotAI* botAI) { return new WotlkDungeonVHStrategy(botAI); }
|
static Strategy* wotlk_vh(PlayerbotAI* botAI) { return new WotlkDungeonVHStrategy(botAI); }
|
||||||
|
static Strategy* wotlk_gd(PlayerbotAI* botAI) { return new WotlkDungeonGDStrategy(botAI); }
|
||||||
|
|
||||||
static Strategy* wotlk_gd(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
|
||||||
static Strategy* wotlk_hos(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_hol(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
static Strategy* wotlk_occ(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
static Strategy* wotlk_occ(PlayerbotAI* botAI) { return new WotlkDungeonUKStrategy(botAI); }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "oldkingdom/OldKingdomActionContext.h"
|
#include "oldkingdom/OldKingdomActionContext.h"
|
||||||
#include "draktharonkeep/DrakTharonKeepActionContext.h"
|
#include "draktharonkeep/DrakTharonKeepActionContext.h"
|
||||||
#include "violethold/VioletHoldActionContext.h"
|
#include "violethold/VioletHoldActionContext.h"
|
||||||
// #include "gundrak/GundrakActionContext.h"
|
#include "gundrak/GundrakActionContext.h"
|
||||||
// #include "hallsofstone/HallsOfStoneActionContext.h"
|
// #include "hallsofstone/HallsOfStoneActionContext.h"
|
||||||
// #include "hallsoflightning/HallsOfLightningActionContext.h"
|
// #include "hallsoflightning/HallsOfLightningActionContext.h"
|
||||||
// #include "oculus/OculusActionContext.h"
|
// #include "oculus/OculusActionContext.h"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "oldkingdom/OldKingdomTriggerContext.h"
|
#include "oldkingdom/OldKingdomTriggerContext.h"
|
||||||
#include "draktharonkeep/DrakTharonKeepTriggerContext.h"
|
#include "draktharonkeep/DrakTharonKeepTriggerContext.h"
|
||||||
#include "violethold/VioletHoldTriggerContext.h"
|
#include "violethold/VioletHoldTriggerContext.h"
|
||||||
// #include "gundrak/GundrakTriggerContext.h"
|
#include "gundrak/GundrakTriggerContext.h"
|
||||||
// #include "hallsofstone/HallsOfStoneTriggerContext.h"
|
// #include "hallsofstone/HallsOfStoneTriggerContext.h"
|
||||||
// #include "hallsoflightning/HallsOfLightningTriggerContext.h"
|
// #include "hallsoflightning/HallsOfLightningTriggerContext.h"
|
||||||
// #include "oculus/OculusTriggerContext.h"
|
// #include "oculus/OculusTriggerContext.h"
|
||||||
|
|||||||
20
src/strategy/dungeons/wotlk/gundrak/GundrakActionContext.h
Normal file
20
src/strategy/dungeons/wotlk/gundrak/GundrakActionContext.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDACTIONCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDACTIONCONTEXT_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "GundrakActions.h"
|
||||||
|
|
||||||
|
class WotlkDungeonGDActionContext : public NamedObjectContext<Action>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonGDActionContext() {
|
||||||
|
creators["avoid poison nova"] = &WotlkDungeonGDActionContext::avoid_poison_nova;
|
||||||
|
creators["avoid whirling slash"] = &WotlkDungeonGDActionContext::avoid_whirling_slash;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Action* avoid_poison_nova(PlayerbotAI* ai) { return new AvoidPoisonNovaAction(ai); }
|
||||||
|
static Action* avoid_whirling_slash(PlayerbotAI* ai) { return new AvoidWhirlingSlashAction(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
44
src/strategy/dungeons/wotlk/gundrak/GundrakActions.cpp
Normal file
44
src/strategy/dungeons/wotlk/gundrak/GundrakActions.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "GundrakActions.h"
|
||||||
|
#include "GundrakStrategy.h"
|
||||||
|
|
||||||
|
bool AvoidPoisonNovaAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "slad'ran");
|
||||||
|
if (!boss) { return false; }
|
||||||
|
|
||||||
|
float distance = bot->GetExactDist2d(boss->GetPosition());
|
||||||
|
float radius = 15.0f;
|
||||||
|
float distanceExtra = 2.0f;
|
||||||
|
|
||||||
|
if (distance < radius + distanceExtra)
|
||||||
|
{
|
||||||
|
return MoveAway(boss, radius + distanceExtra - distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvoidWhirlingSlashAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "gal'darah");
|
||||||
|
if (!boss) { return false; }
|
||||||
|
|
||||||
|
float distance = bot->GetExactDist2d(boss->GetPosition());
|
||||||
|
float radius = 5.0f;
|
||||||
|
float distanceExtra = 2.0f;
|
||||||
|
|
||||||
|
if (distance < radius + distanceExtra)
|
||||||
|
{
|
||||||
|
if (botAI->IsTank(bot))
|
||||||
|
{
|
||||||
|
// The boss chases tank during this, leads to jittery stutter-stepping
|
||||||
|
// by the tank if we don't pre-move additional range. 2*radius seems ok
|
||||||
|
return MoveAway(boss, (2.0f * radius) + distanceExtra - distance);
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
return MoveAway(boss, radius + distanceExtra - distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
24
src/strategy/dungeons/wotlk/gundrak/GundrakActions.h
Normal file
24
src/strategy/dungeons/wotlk/gundrak/GundrakActions.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDACTIONS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDACTIONS_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
#include "AttackAction.h"
|
||||||
|
#include "PlayerbotAI.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "GundrakTriggers.h"
|
||||||
|
|
||||||
|
class AvoidPoisonNovaAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AvoidPoisonNovaAction(PlayerbotAI* ai) : MovementAction(ai, "avoid poison nova") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AvoidWhirlingSlashAction : public MovementAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AvoidWhirlingSlashAction(PlayerbotAI* ai) : MovementAction(ai, "avoid whirling slash") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
37
src/strategy/dungeons/wotlk/gundrak/GundrakMultipliers.cpp
Normal file
37
src/strategy/dungeons/wotlk/gundrak/GundrakMultipliers.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include "GundrakMultipliers.h"
|
||||||
|
#include "GundrakActions.h"
|
||||||
|
#include "GenericSpellActions.h"
|
||||||
|
#include "ChooseTargetActions.h"
|
||||||
|
#include "MovementActions.h"
|
||||||
|
#include "GundrakTriggers.h"
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
float SladranMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "slad'ran");
|
||||||
|
if (!boss) { return 1.0f; }
|
||||||
|
|
||||||
|
if (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_POISON_NOVA))
|
||||||
|
{
|
||||||
|
if (dynamic_cast<MovementAction*>(action) && !dynamic_cast<AvoidPoisonNovaAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GaldarahMultiplier::GetValue(Action* action)
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "gal'darah");
|
||||||
|
if (!boss) { return 1.0f; }
|
||||||
|
|
||||||
|
if (boss->HasAura(SPELL_WHIRLING_SLASH))
|
||||||
|
{
|
||||||
|
if (dynamic_cast<MovementAction*>(action) && !dynamic_cast<AvoidWhirlingSlashAction*>(action))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
24
src/strategy/dungeons/wotlk/gundrak/GundrakMultipliers.h
Normal file
24
src/strategy/dungeons/wotlk/gundrak/GundrakMultipliers.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDMULTIPLIERS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDMULTIPLIERS_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
|
||||||
|
class SladranMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SladranMultiplier(PlayerbotAI* ai) : Multiplier(ai, "slad'ran") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class GaldarahMultiplier : public Multiplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GaldarahMultiplier(PlayerbotAI* ai) : Multiplier(ai, "gal'darah") {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetValue(Action* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
29
src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp
Normal file
29
src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.cpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include "GundrakStrategy.h"
|
||||||
|
#include "GundrakMultipliers.h"
|
||||||
|
|
||||||
|
|
||||||
|
void WotlkDungeonGDStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||||
|
{
|
||||||
|
// Moorabi
|
||||||
|
|
||||||
|
// Drakkari Colossus
|
||||||
|
|
||||||
|
// Slad'ran
|
||||||
|
// TODO: Might need to add target priority for heroic on the snakes or to burn down boss.
|
||||||
|
// Will re-test in heroic, decent dps groups should be able to blast him down with no funky strats.
|
||||||
|
triggers.push_back(new TriggerNode("poison nova",
|
||||||
|
NextAction::array(0, new NextAction("avoid poison nova", ACTION_RAID + 5), nullptr)));
|
||||||
|
|
||||||
|
// Gal'darah
|
||||||
|
triggers.push_back(new TriggerNode("whirling slash",
|
||||||
|
NextAction::array(0, new NextAction("avoid whirling slash", ACTION_RAID + 5), nullptr)));
|
||||||
|
|
||||||
|
// Eck the Ferocious (Heroic only)
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void WotlkDungeonGDStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||||
|
{
|
||||||
|
multipliers.push_back(new SladranMultiplier(botAI));
|
||||||
|
multipliers.push_back(new GaldarahMultiplier(botAI));
|
||||||
|
}
|
||||||
18
src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h
Normal file
18
src/strategy/dungeons/wotlk/gundrak/GundrakStrategy.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDSTRATEGY_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDSTRATEGY_H
|
||||||
|
|
||||||
|
#include "Multiplier.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "Strategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WotlkDungeonGDStrategy : public Strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonGDStrategy(PlayerbotAI* ai) : Strategy(ai) {}
|
||||||
|
virtual std::string const getName() override { return "gundrak"; }
|
||||||
|
virtual void InitTriggers(std::vector<TriggerNode*> &triggers) override;
|
||||||
|
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
21
src/strategy/dungeons/wotlk/gundrak/GundrakTriggerContext.h
Normal file
21
src/strategy/dungeons/wotlk/gundrak/GundrakTriggerContext.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDTRIGGERCONTEXT_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDTRIGGERCONTEXT_H
|
||||||
|
|
||||||
|
#include "NamedObjectContext.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "GundrakTriggers.h"
|
||||||
|
|
||||||
|
class WotlkDungeonGDTriggerContext : public NamedObjectContext<Trigger>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WotlkDungeonGDTriggerContext()
|
||||||
|
{
|
||||||
|
creators["poison nova"] = &WotlkDungeonGDTriggerContext::poison_nova;
|
||||||
|
creators["whirling slash"] = &WotlkDungeonGDTriggerContext::whirling_slash;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static Trigger* poison_nova(PlayerbotAI* ai) { return new SladranPoisonNovaTrigger(ai); }
|
||||||
|
static Trigger* whirling_slash(PlayerbotAI* ai) { return new GaldarahWhirlingSlashTrigger(ai); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
18
src/strategy/dungeons/wotlk/gundrak/GundrakTriggers.cpp
Normal file
18
src/strategy/dungeons/wotlk/gundrak/GundrakTriggers.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "Playerbots.h"
|
||||||
|
#include "GundrakTriggers.h"
|
||||||
|
#include "AiObject.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
|
||||||
|
bool SladranPoisonNovaTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "slad'ran");
|
||||||
|
if (!boss) { return false; }
|
||||||
|
|
||||||
|
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_POISON_NOVA);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GaldarahWhirlingSlashTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Unit* boss = AI_VALUE2(Unit*, "find target", "gal'darah");
|
||||||
|
return boss && boss->HasAura(SPELL_WHIRLING_SLASH);
|
||||||
|
}
|
||||||
37
src/strategy/dungeons/wotlk/gundrak/GundrakTriggers.h
Normal file
37
src/strategy/dungeons/wotlk/gundrak/GundrakTriggers.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef _PLAYERBOT_WOTLKDUNGEONGDTRIGGERS_H
|
||||||
|
#define _PLAYERBOT_WOTLKDUNGEONGDTRIGGERS_H
|
||||||
|
|
||||||
|
#include "Trigger.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
|
#include "GenericTriggers.h"
|
||||||
|
#include "DungeonStrategyUtils.h"
|
||||||
|
|
||||||
|
enum GundrakIDs
|
||||||
|
{
|
||||||
|
// Slad'ran
|
||||||
|
SPELL_POISON_NOVA_N = 55081,
|
||||||
|
SPELL_POISON_NOVA_H = 59842,
|
||||||
|
|
||||||
|
// Gal'darah
|
||||||
|
SPELL_WHIRLING_SLASH_N = 55250,
|
||||||
|
SPELL_WHIRLING_SLASH_H = 59824,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SPELL_POISON_NOVA DUNGEON_MODE(bot, SPELL_POISON_NOVA_N, SPELL_POISON_NOVA_H)
|
||||||
|
#define SPELL_WHIRLING_SLASH DUNGEON_MODE(bot, SPELL_WHIRLING_SLASH_N, SPELL_WHIRLING_SLASH_H)
|
||||||
|
|
||||||
|
class SladranPoisonNovaTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SladranPoisonNovaTrigger(PlayerbotAI* ai) : Trigger(ai, "slad'ran poison nova") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GaldarahWhirlingSlashTrigger : public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GaldarahWhirlingSlashTrigger(PlayerbotAI* ai) : Trigger(ai, "gal'darah whirling slash") {}
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user