mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-12-01 21:12:50 +08:00
better shaman totem strategy
This commit is contained in:
@@ -118,9 +118,9 @@ bool CastSpellAction::isUseful()
|
||||
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
|
||||
{
|
||||
range = ATTACK_DISTANCE;
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (target)
|
||||
range = bot->GetMeleeRange(target);
|
||||
// Unit* target = AI_VALUE(Unit*, "current target");
|
||||
// if (target)
|
||||
// range = bot->GetMeleeRange(target);
|
||||
|
||||
// range = target->GetCombinedCombatReach();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanSt
|
||||
NextAction** CasterShamanStrategy::getDefaultActions()
|
||||
{
|
||||
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),
|
||||
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(
|
||||
"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)));
|
||||
}
|
||||
|
||||
@@ -81,9 +81,9 @@ void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
"party member cleanse spirit curse",
|
||||
NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"no fire totem",
|
||||
NextAction::array(0, new NextAction("fire elemental totem", 11.0f), new NextAction("flametongue totem", 10.0f), NULL)));
|
||||
// triggers.push_back(new TriggerNode(
|
||||
// "no fire totem",
|
||||
// NextAction::array(0, new NextAction("flametongue totem", 10.0f), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"no water totem",
|
||||
|
||||
@@ -50,8 +50,9 @@ MeleeShamanStrategy::MeleeShamanStrategy(PlayerbotAI* botAI) : GenericShamanStra
|
||||
NextAction** MeleeShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(0,
|
||||
new NextAction("stormstrike", ACTION_DEFAULT + 0.4f),
|
||||
new NextAction("earth shock", ACTION_DEFAULT + 0.3f),
|
||||
new NextAction("stormstrike", ACTION_DEFAULT + 0.5f),
|
||||
new NextAction("earth shock", ACTION_DEFAULT + 0.4f),
|
||||
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("melee", ACTION_DEFAULT),
|
||||
@@ -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("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(
|
||||
"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(
|
||||
"medium mana",
|
||||
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)
|
||||
{
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
|
||||
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()
|
||||
@@ -27,7 +34,7 @@ bool CastSearingTotemAction::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()
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#ifndef _PLAYERBOT_SHAMANACTIONS_H
|
||||
#define _PLAYERBOT_SHAMANACTIONS_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
@@ -109,9 +111,19 @@ class CastWindfuryWeaponAction : public CastEnchantItemAction
|
||||
class CastTotemAction : public CastBuffSpellAction
|
||||
{
|
||||
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;
|
||||
protected:
|
||||
float needLifeTime;
|
||||
std::string buff;
|
||||
};
|
||||
|
||||
class CastStoneskinTotemAction : public CastTotemAction
|
||||
@@ -129,13 +141,13 @@ class CastEarthbindTotemAction : public CastTotemAction
|
||||
class CastStrengthOfEarthTotemAction : public CastTotemAction
|
||||
{
|
||||
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
|
||||
{
|
||||
public:
|
||||
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem") { }
|
||||
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem", "mana spring", 20.0f) { }
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
@@ -164,7 +176,7 @@ class CastCleansingTotemAction : public CastTotemAction
|
||||
class CastFlametongueTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem") { }
|
||||
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "", 20.0f) { }
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
@@ -184,16 +196,16 @@ class CastGraceOfAirTotemAction : public CastTotemAction
|
||||
class CastSearingTotemAction : public CastTotemAction
|
||||
{
|
||||
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"; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastMagmaTotemAction : public CastMeleeSpellAction
|
||||
class CastMagmaTotemAction : public CastTotemAction
|
||||
{
|
||||
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"; }
|
||||
bool isUseful() override;
|
||||
@@ -392,7 +404,7 @@ class CastTotemOfWrathAction : public CastTotemAction
|
||||
class CastFireElementalTotemAction : public CastTotemAction
|
||||
{
|
||||
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 bool isUseful() override { return CastTotemAction::isUseful(); }
|
||||
};
|
||||
@@ -400,7 +412,7 @@ class CastFireElementalTotemAction : public CastTotemAction
|
||||
class CastWrathOfAirTotemAction : public CastTotemAction
|
||||
{
|
||||
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
|
||||
@@ -408,4 +420,10 @@ class CastShamanisticRageAction : public CastBuffSpellAction
|
||||
public:
|
||||
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {}
|
||||
};
|
||||
|
||||
class CastFeralSpiritAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -74,6 +74,7 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
creators["mana spring totem"] = &ShamanATriggerFactoryInternal::mana_spring_totem;
|
||||
creators["flametongue totem"] = &ShamanATriggerFactoryInternal::flametongue_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["searing totem"] = &ShamanATriggerFactoryInternal::searing_totem;
|
||||
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["no fire totem"] = &ShamanATriggerFactoryInternal::no_fire_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["maelstrom weapon"] = &ShamanATriggerFactoryInternal::maelstrom_weapon;
|
||||
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* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemTrigger(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* searing_totem(PlayerbotAI* botAI) { return new SearingTotemTrigger(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* no_fire_totem(PlayerbotAI* ai) { return new NoFireTotemTrigger(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* flame_shock(PlayerbotAI* ai) { return new FlameShockTrigger(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["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
|
||||
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["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage;
|
||||
creators["feral spirit"] = &ShamanAiObjectContextInternal::feral_spirit;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -275,6 +279,7 @@ class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
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* shamanistic_rage(PlayerbotAI* ai) { return new CastShamanisticRageAction(ai); }
|
||||
static Action* feral_spirit(PlayerbotAI* ai) { return new CastFeralSpiritAction(ai); }
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -85,3 +85,9 @@ bool NoWaterTotemTrigger::IsActive()
|
||||
!AI_VALUE2(bool, "has totem", "mana spring 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");
|
||||
}
|
||||
@@ -65,6 +65,12 @@ class StrengthOfEarthTotemTrigger : public TotemTrigger
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -234,13 +240,13 @@ class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger
|
||||
class NoFireTotemTrigger : public Trigger {
|
||||
public:
|
||||
NoFireTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no fire totem") {}
|
||||
virtual bool IsActive() override;
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoWaterTotemTrigger : public Trigger {
|
||||
public:
|
||||
NoWaterTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no water totem") {}
|
||||
virtual bool IsActive() override;
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
@@ -259,4 +265,11 @@ class WrathOfAirTotemTrigger : public TotemTrigger
|
||||
public:
|
||||
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
|
||||
|
||||
@@ -13,19 +13,28 @@ void TotemsShamanStrategy::InitTriggers(std::vector<TriggerNode*>& 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(
|
||||
"wrath of air totem",
|
||||
"no air totem",
|
||||
NextAction::array(0, new NextAction("wrath of air totem", 8.0f), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"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(
|
||||
"strength of earth totem",
|
||||
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)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user