better shaman totem strategy

This commit is contained in:
Yunfan Li
2023-10-29 00:16:31 +08:00
parent 8b42ea3e89
commit a76290a149
10 changed files with 108 additions and 32 deletions

View File

@@ -118,9 +118,9 @@ bool CastSpellAction::isUseful()
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell) CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
{ {
range = ATTACK_DISTANCE; range = ATTACK_DISTANCE;
Unit* target = AI_VALUE(Unit*, "current target"); // Unit* target = AI_VALUE(Unit*, "current target");
if (target) // if (target)
range = bot->GetMeleeRange(target); // range = bot->GetMeleeRange(target);
// range = target->GetCombinedCombatReach(); // range = target->GetCombinedCombatReach();
} }

View File

@@ -39,7 +39,8 @@ CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanSt
NextAction** CasterShamanStrategy::getDefaultActions() NextAction** CasterShamanStrategy::getDefaultActions()
{ {
return NextAction::array(0, return NextAction::array(0,
new NextAction("lava burst", ACTION_DEFAULT + 0.1f), new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
new NextAction("thunderstorm", ACTION_DEFAULT + 0.1f),
new NextAction("lightning bolt", ACTION_DEFAULT), new NextAction("lightning bolt", ACTION_DEFAULT),
NULL); NULL);
} }
@@ -55,7 +56,9 @@ void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
// triggers.push_back(new TriggerNode("frost shock snare", NextAction::array(0, new NextAction("frost shock", 21.0f), nullptr))); // triggers.push_back(new TriggerNode("frost shock snare", NextAction::array(0, new NextAction("frost shock", 21.0f), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"no fire totem", "no fire totem",
NextAction::array(0, new NextAction("totem of wrath", 15.0f), NULL))); NextAction::array(0,
// new NextAction("fire elemental totem", 16.0f),
new NextAction("totem of wrath", 15.0f), NULL)));
triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr)));
} }

View File

@@ -81,9 +81,9 @@ void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"party member cleanse spirit curse", "party member cleanse spirit curse",
NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL))); NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL)));
triggers.push_back(new TriggerNode( // triggers.push_back(new TriggerNode(
"no fire totem", // "no fire totem",
NextAction::array(0, new NextAction("fire elemental totem", 11.0f), new NextAction("flametongue totem", 10.0f), NULL))); // NextAction::array(0, new NextAction("flametongue totem", 10.0f), NULL)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"no water totem", "no water totem",

View File

@@ -50,9 +50,10 @@ MeleeShamanStrategy::MeleeShamanStrategy(PlayerbotAI* botAI) : GenericShamanStra
NextAction** MeleeShamanStrategy::getDefaultActions() NextAction** MeleeShamanStrategy::getDefaultActions()
{ {
return NextAction::array(0, return NextAction::array(0,
new NextAction("stormstrike", ACTION_DEFAULT + 0.4f), new NextAction("stormstrike", ACTION_DEFAULT + 0.5f),
new NextAction("earth shock", ACTION_DEFAULT + 0.3f), new NextAction("earth shock", ACTION_DEFAULT + 0.4f),
new NextAction("fire nova", ACTION_DEFAULT + 0.2f), new NextAction("feral spirit", ACTION_DEFAULT + 0.3f),
new NextAction("fire nova", ACTION_DEFAULT + 0.2f),
new NextAction("lava lash", ACTION_DEFAULT + 0.1f), new NextAction("lava lash", ACTION_DEFAULT + 0.1f),
new NextAction("melee", ACTION_DEFAULT), new NextAction("melee", ACTION_DEFAULT),
NULL); NULL);
@@ -72,9 +73,23 @@ void MeleeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
// triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); // triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("strength of earth totem", ACTION_LIGHT_HEAL), nullptr))); triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("strength of earth totem", ACTION_LIGHT_HEAL), nullptr)));
triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr))); triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"no fire totem", "no fire totem",
NextAction::array(0, new NextAction("reach melee", 23.0f), new NextAction("magma totem", 22.0f), nullptr))); NextAction::array(0,
new NextAction("reach melee", 23.0f),
new NextAction("magma totem", 22.0f), nullptr)));
triggers.push_back(new TriggerNode("fire elemental totem",
NextAction::array(0,
new NextAction("reach melee", 33.0f),
new NextAction("fire elemental totem", 32.0f),
nullptr)));
triggers.push_back(new TriggerNode(
"no air totem",
NextAction::array(0, new NextAction("windfury totem", 20.0f), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"medium mana", "medium mana",
NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr))); NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
@@ -83,6 +98,6 @@ void MeleeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
void MeleeAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void MeleeAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back(new TriggerNode("magma totem", NextAction::array(0, new NextAction("magma totem", 26.0f), nullptr))); // triggers.push_back(new TriggerNode("magma totem", NextAction::array(0, new NextAction("magma totem", 26.0f), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fire nova", 25.0f), nullptr))); triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fire nova", 25.0f), nullptr)));
} }

View File

@@ -7,7 +7,14 @@
bool CastTotemAction::isUseful() bool CastTotemAction::isUseful()
{ {
return CastBuffSpellAction::isUseful() && !AI_VALUE2(bool, "has totem", name); if (needLifeTime > 0.1f) {
Unit* target = AI_VALUE(Unit*, "current target");
float dps = AI_VALUE(float, "expected group dps");
if (target->GetHealth() / dps < needLifeTime) {
return false;
}
}
return CastBuffSpellAction::isUseful() && !AI_VALUE2(bool, "has totem", name) && !botAI->HasAura(buff, bot);
} }
bool CastManaSpringTotemAction::isUseful() bool CastManaSpringTotemAction::isUseful()
@@ -27,7 +34,7 @@ bool CastSearingTotemAction::isUseful()
bool CastMagmaTotemAction::isUseful() bool CastMagmaTotemAction::isUseful()
{ {
return CastMeleeSpellAction::isUseful() && !AI_VALUE2(bool, "has totem", name); return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", name);
} }
bool CastCleansingTotemAction::isUseful() bool CastCleansingTotemAction::isUseful()

View File

@@ -5,7 +5,9 @@
#ifndef _PLAYERBOT_SHAMANACTIONS_H #ifndef _PLAYERBOT_SHAMANACTIONS_H
#define _PLAYERBOT_SHAMANACTIONS_H #define _PLAYERBOT_SHAMANACTIONS_H
#include "Define.h"
#include "GenericSpellActions.h" #include "GenericSpellActions.h"
#include "Playerbots.h"
#include "SharedDefines.h" #include "SharedDefines.h"
class PlayerbotAI; class PlayerbotAI;
@@ -109,9 +111,19 @@ class CastWindfuryWeaponAction : public CastEnchantItemAction
class CastTotemAction : public CastBuffSpellAction class CastTotemAction : public CastBuffSpellAction
{ {
public: public:
CastTotemAction(PlayerbotAI* botAI, std::string const spell) : CastBuffSpellAction(botAI, spell) { } CastTotemAction(PlayerbotAI* botAI, std::string const spell, std::string const buffName = "", float needLifeTime = 8.0f)
: CastBuffSpellAction(botAI, spell), needLifeTime(needLifeTime) {
if (buffName == "") {
buff = spell;
} else {
buff = buffName;
}
}
bool isUseful() override; bool isUseful() override;
protected:
float needLifeTime;
std::string buff;
}; };
class CastStoneskinTotemAction : public CastTotemAction class CastStoneskinTotemAction : public CastTotemAction
@@ -129,13 +141,13 @@ class CastEarthbindTotemAction : public CastTotemAction
class CastStrengthOfEarthTotemAction : public CastTotemAction class CastStrengthOfEarthTotemAction : public CastTotemAction
{ {
public: public:
CastStrengthOfEarthTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "strength of earth totem") { } CastStrengthOfEarthTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "strength of earth totem", "strength of earth", 20.0f) { }
}; };
class CastManaSpringTotemAction : public CastTotemAction class CastManaSpringTotemAction : public CastTotemAction
{ {
public: public:
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem") { } CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem", "mana spring", 20.0f) { }
bool isUseful() override; bool isUseful() override;
}; };
@@ -164,7 +176,7 @@ class CastCleansingTotemAction : public CastTotemAction
class CastFlametongueTotemAction : public CastTotemAction class CastFlametongueTotemAction : public CastTotemAction
{ {
public: public:
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem") { } CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "", 20.0f) { }
bool isUseful() override; bool isUseful() override;
}; };
@@ -184,16 +196,16 @@ class CastGraceOfAirTotemAction : public CastTotemAction
class CastSearingTotemAction : public CastTotemAction class CastSearingTotemAction : public CastTotemAction
{ {
public: public:
CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem") { } CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem", "", 0.0f) { }
std::string const GetTargetName() override { return "self target"; } std::string const GetTargetName() override { return "self target"; }
bool isUseful() override; bool isUseful() override;
}; };
class CastMagmaTotemAction : public CastMeleeSpellAction class CastMagmaTotemAction : public CastTotemAction
{ {
public: public:
CastMagmaTotemAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "magma totem") { } CastMagmaTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "magma totem", "", 0.0f) { }
std::string const GetTargetName() override { return "self target"; } std::string const GetTargetName() override { return "self target"; }
bool isUseful() override; bool isUseful() override;
@@ -392,7 +404,7 @@ class CastTotemOfWrathAction : public CastTotemAction
class CastFireElementalTotemAction : public CastTotemAction class CastFireElementalTotemAction : public CastTotemAction
{ {
public: public:
CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem") {} CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "", 0.0f) {}
virtual std::string const GetTargetName() override { return "self target"; } virtual std::string const GetTargetName() override { return "self target"; }
virtual bool isUseful() override { return CastTotemAction::isUseful(); } virtual bool isUseful() override { return CastTotemAction::isUseful(); }
}; };
@@ -400,7 +412,7 @@ class CastFireElementalTotemAction : public CastTotemAction
class CastWrathOfAirTotemAction : public CastTotemAction class CastWrathOfAirTotemAction : public CastTotemAction
{ {
public: public:
CastWrathOfAirTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "wrath of air totem") {} CastWrathOfAirTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "wrath of air totem", "wrath of air totem") {}
}; };
class CastShamanisticRageAction : public CastBuffSpellAction class CastShamanisticRageAction : public CastBuffSpellAction
@@ -408,4 +420,10 @@ class CastShamanisticRageAction : public CastBuffSpellAction
public: public:
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {} CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {}
}; };
class CastFeralSpiritAction : public CastSpellAction
{
public:
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {}
};
#endif #endif

View File

@@ -74,6 +74,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
creators["mana spring totem"] = &ShamanATriggerFactoryInternal::mana_spring_totem; creators["mana spring totem"] = &ShamanATriggerFactoryInternal::mana_spring_totem;
creators["flametongue totem"] = &ShamanATriggerFactoryInternal::flametongue_totem; creators["flametongue totem"] = &ShamanATriggerFactoryInternal::flametongue_totem;
creators["strength of earth totem"] = &ShamanATriggerFactoryInternal::strength_of_earth_totem; creators["strength of earth totem"] = &ShamanATriggerFactoryInternal::strength_of_earth_totem;
creators["fire elemental totem"] = &ShamanATriggerFactoryInternal::fire_elemental_totem;
creators["magma totem"] = &ShamanATriggerFactoryInternal::magma_totem; creators["magma totem"] = &ShamanATriggerFactoryInternal::magma_totem;
creators["searing totem"] = &ShamanATriggerFactoryInternal::searing_totem; creators["searing totem"] = &ShamanATriggerFactoryInternal::searing_totem;
creators["wind shear"] = &ShamanATriggerFactoryInternal::wind_shear; creators["wind shear"] = &ShamanATriggerFactoryInternal::wind_shear;
@@ -102,6 +103,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease; creators["party member cure disease"] = &ShamanATriggerFactoryInternal::party_member_cure_disease;
creators["no fire totem"] = &ShamanATriggerFactoryInternal::no_fire_totem; creators["no fire totem"] = &ShamanATriggerFactoryInternal::no_fire_totem;
creators["no water totem"] = &ShamanATriggerFactoryInternal::no_water_totem; creators["no water totem"] = &ShamanATriggerFactoryInternal::no_water_totem;
creators["no air totem"] = &ShamanATriggerFactoryInternal::no_air_totem;
creators["earth shield on main tank"] = &ShamanATriggerFactoryInternal::earth_shield_on_main_tank; creators["earth shield on main tank"] = &ShamanATriggerFactoryInternal::earth_shield_on_main_tank;
creators["maelstrom weapon"] = &ShamanATriggerFactoryInternal::maelstrom_weapon; creators["maelstrom weapon"] = &ShamanATriggerFactoryInternal::maelstrom_weapon;
creators["flame shock"] = &ShamanATriggerFactoryInternal::flame_shock; creators["flame shock"] = &ShamanATriggerFactoryInternal::flame_shock;
@@ -127,6 +129,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
static Trigger* mana_spring_totem(PlayerbotAI* botAI) { return new ManaSpringTotemTrigger(botAI); } static Trigger* mana_spring_totem(PlayerbotAI* botAI) { return new ManaSpringTotemTrigger(botAI); }
static Trigger* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemTrigger(botAI); } static Trigger* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemTrigger(botAI); }
static Trigger* strength_of_earth_totem(PlayerbotAI* botAI) { return new StrengthOfEarthTotemTrigger(botAI); } static Trigger* strength_of_earth_totem(PlayerbotAI* botAI) { return new StrengthOfEarthTotemTrigger(botAI); }
static Trigger* fire_elemental_totem(PlayerbotAI* botAI) { return new FireElementalTotemTrigger(botAI); }
static Trigger* magma_totem(PlayerbotAI* botAI) { return new MagmaTotemTrigger(botAI); } static Trigger* magma_totem(PlayerbotAI* botAI) { return new MagmaTotemTrigger(botAI); }
static Trigger* searing_totem(PlayerbotAI* botAI) { return new SearingTotemTrigger(botAI); } static Trigger* searing_totem(PlayerbotAI* botAI) { return new SearingTotemTrigger(botAI); }
static Trigger* wind_shear(PlayerbotAI* botAI) { return new WindShearInterruptSpellTrigger(botAI); } static Trigger* wind_shear(PlayerbotAI* botAI) { return new WindShearInterruptSpellTrigger(botAI); }
@@ -143,6 +146,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
static Trigger* party_member_cure_disease(PlayerbotAI* botAI) { return new PartyMemberCureDiseaseTrigger(botAI); } static Trigger* party_member_cure_disease(PlayerbotAI* botAI) { return new PartyMemberCureDiseaseTrigger(botAI); }
static Trigger* no_fire_totem(PlayerbotAI* ai) { return new NoFireTotemTrigger(ai); } static Trigger* no_fire_totem(PlayerbotAI* ai) { return new NoFireTotemTrigger(ai); }
static Trigger* no_water_totem(PlayerbotAI* ai) { return new NoWaterTotemTrigger(ai); } static Trigger* no_water_totem(PlayerbotAI* ai) { return new NoWaterTotemTrigger(ai); }
static Trigger* no_air_totem(PlayerbotAI* ai) { return new NoAirTotemTrigger(ai); }
static Trigger* earth_shield_on_main_tank(PlayerbotAI* ai) { return new EarthShieldOnMainTankTrigger(ai); } static Trigger* earth_shield_on_main_tank(PlayerbotAI* ai) { return new EarthShieldOnMainTankTrigger(ai); }
static Trigger* flame_shock(PlayerbotAI* ai) { return new FlameShockTrigger(ai); } static Trigger* flame_shock(PlayerbotAI* ai) { return new FlameShockTrigger(ai); }
static Trigger* wrath_of_air_totem(PlayerbotAI* ai) { return new WrathOfAirTotemTrigger(ai); } static Trigger* wrath_of_air_totem(PlayerbotAI* ai) { return new WrathOfAirTotemTrigger(ai); }
@@ -210,9 +214,9 @@ class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
creators["earth shield on main tank"] = &ShamanAiObjectContextInternal::earth_shield_on_main_tank; creators["earth shield on main tank"] = &ShamanAiObjectContextInternal::earth_shield_on_main_tank;
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem; creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath; creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath;
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem; creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem;
creators["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage; creators["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage;
creators["feral spirit"] = &ShamanAiObjectContextInternal::feral_spirit;
} }
private: private:
@@ -275,6 +279,7 @@ class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); } static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); }
static Action* wrath_of_air_totem(PlayerbotAI* ai) { return new CastWrathOfAirTotemAction(ai); } static Action* wrath_of_air_totem(PlayerbotAI* ai) { return new CastWrathOfAirTotemAction(ai); }
static Action* shamanistic_rage(PlayerbotAI* ai) { return new CastShamanisticRageAction(ai); } static Action* shamanistic_rage(PlayerbotAI* ai) { return new CastShamanisticRageAction(ai); }
static Action* feral_spirit(PlayerbotAI* ai) { return new CastFeralSpiritAction(ai); }
}; };

View File

@@ -84,4 +84,10 @@ bool NoWaterTotemTrigger::IsActive()
!AI_VALUE2(bool, "has totem", "cleansing totem") && !AI_VALUE2(bool, "has totem", "cleansing totem") &&
!AI_VALUE2(bool, "has totem", "mana spring totem") && !AI_VALUE2(bool, "has totem", "mana spring totem") &&
!AI_VALUE2(bool, "has totem", "healing stream totem"); !AI_VALUE2(bool, "has totem", "healing stream totem");
}
bool NoAirTotemTrigger::IsActive()
{
return !AI_VALUE2(bool, "has totem", "wrath of air totem") &&
!AI_VALUE2(bool, "has totem", "windfury totem");
} }

View File

@@ -65,6 +65,12 @@ class StrengthOfEarthTotemTrigger : public TotemTrigger
StrengthOfEarthTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "strength of earth totem") { } StrengthOfEarthTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "strength of earth totem") { }
}; };
class FireElementalTotemTrigger : public BoostTrigger
{
public:
FireElementalTotemTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "fire elemental totem") { }
};
class MagmaTotemTrigger : public TotemTrigger class MagmaTotemTrigger : public TotemTrigger
{ {
public: public:
@@ -234,13 +240,13 @@ class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger
class NoFireTotemTrigger : public Trigger { class NoFireTotemTrigger : public Trigger {
public: public:
NoFireTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no fire totem") {} NoFireTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no fire totem") {}
virtual bool IsActive() override; bool IsActive() override;
}; };
class NoWaterTotemTrigger : public Trigger { class NoWaterTotemTrigger : public Trigger {
public: public:
NoWaterTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no water totem") {} NoWaterTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no water totem") {}
virtual bool IsActive() override; bool IsActive() override;
}; };
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger
@@ -259,4 +265,11 @@ class WrathOfAirTotemTrigger : public TotemTrigger
public: public:
WrathOfAirTotemTrigger(PlayerbotAI* ai) : TotemTrigger(ai, "wrath of air totem") {} WrathOfAirTotemTrigger(PlayerbotAI* ai) : TotemTrigger(ai, "wrath of air totem") {}
}; };
class NoAirTotemTrigger : public TotemTrigger
{
public:
NoAirTotemTrigger(PlayerbotAI* ai) : TotemTrigger(ai, "no air totem") {}
bool IsActive() override;
};
#endif #endif

View File

@@ -13,19 +13,28 @@ void TotemsShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
GenericShamanStrategy::InitTriggers(triggers); GenericShamanStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem", 32.0f), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"wrath of air totem", "no air totem",
NextAction::array(0, new NextAction("wrath of air totem", 8.0f), NULL))); NextAction::array(0, new NextAction("wrath of air totem", 8.0f), NULL)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"no water totem", "no water totem",
NextAction::array(0, new NextAction("mana spring totem", 7.0f), NULL))); NextAction::array(0,
new NextAction("mana spring totem", 7.0f),
new NextAction("healing stream totem", 6.0f),
nullptr)));
triggers.push_back(new TriggerNode(
"no fire totem",
NextAction::array(0,
new NextAction("flametongue totem", 7.0f),
new NextAction("searing totem", 6.0f),
nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"strength of earth totem", "strength of earth totem",
NextAction::array(0, new NextAction("strength of earth totem", 6.0f), NULL))); NextAction::array(0, new NextAction("strength of earth totem", 6.0f), NULL)));
triggers.push_back(new TriggerNode(
"no fire totem",
NextAction::array(0, new NextAction("flametongue totem", 5.0f), NULL)));
} }