mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Frost mage AI
This commit is contained in:
@@ -5,15 +5,68 @@
|
||||
#include "FrostMageStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class FrostMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FrostMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["deep freeze"] = &deep_freeze;
|
||||
creators["frostbolt and deep freeze"] = &frostbolt_and_deep_freeze;
|
||||
}
|
||||
private:
|
||||
static ActionNode* cold_snap([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("cold snap",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* ice_barrier([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("ice_barrier",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* summon_water_elemental([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("summon water elemental",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* deep_freeze([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("deep freeze",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("ice lance"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* frostbolt_and_deep_freeze([[maybe_unused]] PlayerbotAI* botAI)
|
||||
// Combo cast the last charge of fingers of frost for double crits.
|
||||
// Should only do this on the final charge of FoF.
|
||||
{
|
||||
return new ActionNode ("frostbolt",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ NextAction::array(0, new NextAction("deep freeze"), NULL));
|
||||
}
|
||||
};
|
||||
|
||||
FrostMageStrategy::FrostMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FrostMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
NextAction** FrostMageStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(0,
|
||||
new NextAction("frostbolt", ACTION_DEFAULT + 0.1f),
|
||||
new NextAction("shoot", ACTION_DEFAULT),
|
||||
new NextAction("frostbolt", ACTION_DEFAULT + 0.1f),
|
||||
new NextAction("shoot", ACTION_DEFAULT),
|
||||
nullptr);
|
||||
|
||||
}
|
||||
@@ -21,11 +74,22 @@ NextAction** FrostMageStrategy::getDefaultActions()
|
||||
void FrostMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericMageStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("icy veins", NextAction::array(0, new NextAction("icy veins", 50.0f), nullptr)));
|
||||
// No logic currently for cold snap usage.. possibly use right after icy veins drops off?
|
||||
// triggers.push_back(new TriggerNode("cold snap", NextAction::array(0, new NextAction("cold snap", 50.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("summon water elemental", 70.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("ice barrier", NextAction::array(0, new NextAction("ice barrier", 30.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("brain freeze", NextAction::array(0, new NextAction("frostfire bolt", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("fingers of frost single", NextAction::array(0, new NextAction("frostbolt and deep freeze", 20.0f), nullptr)));
|
||||
// May not need this, frostbolt is the default action so probably don't need to specify.
|
||||
// Maybe uncomment if you find the mage is prioritising auxillary spells while this buff is up, and wasting the proc.
|
||||
// triggers.push_back(new TriggerNode("fingers of frost double", NextAction::array(0, new NextAction("frostbolt", 10.0f), nullptr)));
|
||||
}
|
||||
|
||||
void FrostMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("cone of cold", 45.0f), nullptr)));
|
||||
}
|
||||
|
||||
@@ -12,9 +12,12 @@ class GenericMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
|
||||
GenericMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["frostbolt"] = &frostbolt;
|
||||
creators["frostfire bolt"] = &frostfire_bolt;
|
||||
creators["ice lance"] = &ice_lance;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["scorch"] = &scorch;
|
||||
creators["frost nova"] = &frost_nova;
|
||||
creators["cone of cold"] = &cone_of_cold;
|
||||
creators["icy veins"] = &icy_veins;
|
||||
creators["combustion"] = &combustion;
|
||||
creators["evocation"] = &evocation;
|
||||
@@ -34,6 +37,22 @@ class GenericMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* frostfire_bolt([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("frostfire bolt",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("fireball"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* ice_lance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("ice lance",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* fire_blast([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("fire blast",
|
||||
@@ -55,7 +74,15 @@ class GenericMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNod
|
||||
return new ActionNode ("frost nova",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* cone_of_cold([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("cone of cold",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* icy_veins([[maybe_unused]] PlayerbotAI* botAI)
|
||||
|
||||
@@ -35,7 +35,6 @@ class CastArcaneBlastAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneBlastAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "arcane blast") { }
|
||||
|
||||
std::string const GetTargetName() override { return "current target"; }
|
||||
};
|
||||
|
||||
@@ -68,7 +67,6 @@ class CastFrostNovaAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostNovaAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frost nova") { }
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
@@ -78,14 +76,39 @@ class CastFrostboltAction : public CastSpellAction
|
||||
CastFrostboltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frostbolt") { }
|
||||
};
|
||||
|
||||
class CastFrostfireBoltAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostfireBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frostfire bolt") { }
|
||||
};
|
||||
|
||||
class CastIceLanceAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceLanceAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "ice lance") { }
|
||||
};
|
||||
|
||||
class CastDeepFreezeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeepFreezeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "deep freeze") { }
|
||||
};
|
||||
|
||||
class CastBlizzardAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlizzardAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blizzard") { }
|
||||
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastConeOfColdAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastConeOfColdAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "cone of cold") { }
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
// bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastArcaneIntellectAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
@@ -116,6 +139,24 @@ class CastIcyVeinsAction : public CastBuffSpellAction
|
||||
CastIcyVeinsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "icy veins") { }
|
||||
};
|
||||
|
||||
class CastColdSnapAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastColdSnapAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cold snap") { }
|
||||
};
|
||||
|
||||
class CastIceBarrierAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceBarrierAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ice barrier") { }
|
||||
};
|
||||
|
||||
class CastSummonWaterElementalAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSummonWaterElementalAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "summon water elemental") { }
|
||||
};
|
||||
|
||||
class CastCombustionAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
@@ -183,7 +224,6 @@ class CastPolymorphAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastPolymorphAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "polymorph") { }
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
};
|
||||
|
||||
@@ -223,7 +263,6 @@ class CastEvocationAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEvocationAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "evocation") { }
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +79,12 @@ class MageTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
creators["fireball"] = &MageTriggerFactoryInternal::fireball;
|
||||
creators["pyroblast"] = &MageTriggerFactoryInternal::pyroblast;
|
||||
creators["combustion"] = &MageTriggerFactoryInternal::combustion;
|
||||
creators["fingers of frost single"] = &MageTriggerFactoryInternal::fingers_of_frost_single;
|
||||
creators["fingers of frost double"] = &MageTriggerFactoryInternal::fingers_of_frost_double;
|
||||
creators["brain freeze"] = &MageTriggerFactoryInternal::brain_freeze;
|
||||
creators["icy veins"] = &MageTriggerFactoryInternal::icy_veins;
|
||||
creators["cold snap"] = &MageTriggerFactoryInternal::cold_snap;
|
||||
creators["ice barrier"] = &MageTriggerFactoryInternal::ice_barrier;
|
||||
creators["arcane intellect"] = &MageTriggerFactoryInternal::arcane_intellect;
|
||||
creators["arcane intellect on party"] = &MageTriggerFactoryInternal::arcane_intellect_on_party;
|
||||
creators["mage armor"] = &MageTriggerFactoryInternal::mage_armor;
|
||||
@@ -110,7 +115,12 @@ class MageTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
static Trigger* fireball(PlayerbotAI* botAI) { return new FireballTrigger(botAI); }
|
||||
static Trigger* pyroblast(PlayerbotAI* botAI) { return new PyroblastTrigger(botAI); }
|
||||
static Trigger* combustion(PlayerbotAI* botAI) { return new CombustionTrigger(botAI); }
|
||||
static Trigger* fingers_of_frost_single(PlayerbotAI* botAI) { return new FingersOfFrostSingleTrigger(botAI); }
|
||||
static Trigger* fingers_of_frost_double(PlayerbotAI* botAI) { return new FingersOfFrostDoubleTrigger(botAI); }
|
||||
static Trigger* brain_freeze(PlayerbotAI* botAI) { return new BrainFreezeTrigger(botAI); }
|
||||
static Trigger* icy_veins(PlayerbotAI* botAI) { return new IcyVeinsTrigger(botAI); }
|
||||
static Trigger* cold_snap(PlayerbotAI* botAI) { return new ColdSnapTrigger(botAI); }
|
||||
static Trigger* ice_barrier(PlayerbotAI* botAI) { return new IceBarrierTrigger(botAI); }
|
||||
static Trigger* arcane_intellect(PlayerbotAI* botAI) { return new ArcaneIntellectTrigger(botAI); }
|
||||
static Trigger* arcane_intellect_on_party(PlayerbotAI* botAI) { return new ArcaneIntellectOnPartyTrigger(botAI); }
|
||||
static Trigger* mage_armor(PlayerbotAI* botAI) { return new MageArmorTrigger(botAI); }
|
||||
@@ -135,7 +145,11 @@ class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
creators["arcane power"] = &MageAiObjectContextInternal::arcane_power;
|
||||
creators["presence of mind"] = &MageAiObjectContextInternal::presence_of_mind;
|
||||
creators["frostbolt"] = &MageAiObjectContextInternal::frostbolt;
|
||||
creators["frostfire bolt"] = &MageAiObjectContextInternal::frostfire_bolt;
|
||||
creators["ice lance"] = &MageAiObjectContextInternal::ice_lance;
|
||||
creators["deep freeze"] = &MageAiObjectContextInternal::deep_freeze;
|
||||
creators["blizzard"] = &MageAiObjectContextInternal::blizzard;
|
||||
creators["cone of cold"] = &MageAiObjectContextInternal::cone_of_cold;
|
||||
creators["frost nova"] = &MageAiObjectContextInternal::frost_nova;
|
||||
creators["arcane intellect"] = &MageAiObjectContextInternal::arcane_intellect;
|
||||
creators["arcane intellect on party"] = &MageAiObjectContextInternal::arcane_intellect_on_party;
|
||||
@@ -156,6 +170,9 @@ class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
creators["remove lesser curse"] = &MageAiObjectContextInternal::remove_lesser_curse;
|
||||
creators["remove lesser curse on party"] = &MageAiObjectContextInternal::remove_lesser_curse_on_party;
|
||||
creators["icy veins"] = &MageAiObjectContextInternal::icy_veins;
|
||||
creators["cold snap"] = &MageAiObjectContextInternal::cold_snap;
|
||||
creators["ice barrier"] = &MageAiObjectContextInternal::ice_barrier;
|
||||
creators["summon_water_elemental"] = &MageAiObjectContextInternal::summon_water_elemental;
|
||||
creators["combustion"] = &MageAiObjectContextInternal::combustion;
|
||||
creators["ice block"] = &MageAiObjectContextInternal::ice_block;
|
||||
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
||||
@@ -183,7 +200,11 @@ class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
static Action* arcane_barrage(PlayerbotAI* botAI) { return new CastArcaneBarrageAction(botAI); }
|
||||
static Action* arcane_blast(PlayerbotAI* botAI) { return new CastArcaneBlastAction(botAI); }
|
||||
static Action* frostbolt(PlayerbotAI* botAI) { return new CastFrostboltAction(botAI); }
|
||||
static Action* frostfire_bolt(PlayerbotAI* botAI) { return new CastFrostfireBoltAction(botAI); }
|
||||
static Action* ice_lance(PlayerbotAI* botAI) { return new CastIceLanceAction(botAI); }
|
||||
static Action* deep_freeze(PlayerbotAI* botAI) { return new CastDeepFreezeAction(botAI); }
|
||||
static Action* blizzard(PlayerbotAI* botAI) { return new CastBlizzardAction(botAI); }
|
||||
static Action* cone_of_cold(PlayerbotAI* botAI) { return new CastConeOfColdAction(botAI); }
|
||||
static Action* frost_nova(PlayerbotAI* botAI) { return new CastFrostNovaAction(botAI); }
|
||||
static Action* arcane_intellect(PlayerbotAI* botAI) { return new CastArcaneIntellectAction(botAI); }
|
||||
static Action* arcane_intellect_on_party(PlayerbotAI* botAI) { return new CastArcaneIntellectOnPartyAction(botAI); }
|
||||
@@ -204,6 +225,9 @@ class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
static Action* remove_lesser_curse(PlayerbotAI* botAI) { return new CastRemoveLesserCurseAction(botAI); }
|
||||
static Action* remove_lesser_curse_on_party(PlayerbotAI* botAI) { return new CastRemoveLesserCurseOnPartyAction(botAI); }
|
||||
static Action* icy_veins(PlayerbotAI* botAI) { return new CastIcyVeinsAction(botAI); }
|
||||
static Action* cold_snap(PlayerbotAI* botAI) { return new CastColdSnapAction(botAI); }
|
||||
static Action* ice_barrier(PlayerbotAI* botAI) { return new CastIceBarrierAction(botAI); }
|
||||
static Action* summon_water_elemental(PlayerbotAI* botAI) { return new CastSummonWaterElementalAction(botAI); }
|
||||
static Action* combustion(PlayerbotAI* botAI) { return new CastCombustionAction(botAI); }
|
||||
static Action* ice_block(PlayerbotAI* botAI) { return new CastIceBlockAction(botAI); }
|
||||
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
||||
|
||||
@@ -74,6 +74,24 @@ class ArcaneBlastTrigger : public BuffTrigger
|
||||
ArcaneBlastTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "arcane blast") { }
|
||||
};
|
||||
|
||||
class FingersOfFrostSingleTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
FingersOfFrostSingleTrigger(PlayerbotAI* ai) : HasAuraStackTrigger(ai, "fingers of frost", 1, 1) {}
|
||||
};
|
||||
|
||||
class FingersOfFrostDoubleTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
FingersOfFrostDoubleTrigger(PlayerbotAI* ai) : HasAuraStackTrigger(ai, "fingers of frost", 2, 1) {}
|
||||
};
|
||||
|
||||
class BrainFreezeTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
BrainFreezeTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "fireball!") { }
|
||||
};
|
||||
|
||||
class CounterspellInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
@@ -92,6 +110,18 @@ class IcyVeinsTrigger : public BoostTrigger
|
||||
IcyVeinsTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "icy veins") { }
|
||||
};
|
||||
|
||||
class ColdSnapTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
ColdSnapTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "cold snap") { }
|
||||
};
|
||||
|
||||
class IceBarrierTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
IceBarrierTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "ice barrier") { }
|
||||
};
|
||||
|
||||
class PolymorphTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
@@ -134,7 +164,8 @@ class PresenceOfMindTrigger : public BuffTrigger
|
||||
PresenceOfMindTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "presence of mind") { }
|
||||
};
|
||||
|
||||
class ArcaneBlastStackTrigger : public HasAuraStackTrigger {
|
||||
class ArcaneBlastStackTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
ArcaneBlastStackTrigger(PlayerbotAI* ai) : HasAuraStackTrigger(ai, "arcane blast", 3, 1) {}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user