mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Shaman Overhaul (#1566)
* Shaman Overhaul Hello everyone, I bring to you the Shaman Overhaul. This was the most fun project I've had so far. Here is a simplified list of the changes this brings: 1. Added Call of the Elements - making the shaman able to set 4 totems down simultaneously! This saves them multiple global cooldowns in combat. 2. Totems are now selected based on their combat strategies. These strategies set totems on the Call of the Elements bar, as well as change what totem is summoned if a single totem is missing. NOTE: Only one strategy of each elemental type (earth, fire, water, air) can be active at a time. Earth - strength of earth, stoneskin, tremor, earthbind Fire - searing, magma, flametongue, wrath, frost resistance Water - healing stream, mana spring, cleansing, fire resistance Air - wrath of air, windfury, nature resistance, grounding There are a few exceptions to totems without strategies: Stoneclaw Totem, Fire Elemental Totem, and Mana Tide Totem. These each have triggers that fire under certain conditions: Stoneclaw Totem: Resto/Ele shaman has low health and isn't in a group Fire Elemental Totem: Boost trigger for Ele/Enhance Mana Tide Totem: Resto Shaman medium mana 3. Added Totemic Recall - a spell that picks up the totems outside of combat to regain 25% of the mana spent. Useful to avoid patrols. 4. Changed the config slightly - Enhance uses Fire Nova Glyph for crazy AoE damage, and enhance pve spec uses both clearcasting and improved shock talent now. 5. Enhancement Shamans will use their Spirit Wolves' Spirit Walk ability - this helps them close the gap and improves their DPS on fights that require movement. 6. Boost Strategy - Moved Bloodlust/Heroism/Fire Elemental Totem from the generic strategy triggers to a new Boost strategy. Now you can control their uses with Boost! (co +boost or co -boost. Enabled by default.) 7. AoE Strategy - Unified both of the AoE strategies for Ele/Enhance to "aoe", rather than "caster aoe" and "melee aoe". NOTE: Healers will still aoe under "healer dps". (co +aoe or co -aoe. Enabled by default.) 8. Moved the weapon imbue strategies from combat to non-combat. I noticed that they were only casting their weapon imbues during combat - this fixes that. 9. Added logic for only using Lava Burst on targets with Flame Shock active, ensuring that it's as close to 100% crit chance as possible. I did notice on a sample size of 112 lava bursts in testing that it still fails to crit around 3 percent of the time - that is because the lava burst starts to cast while flame shock is on the target, but by the time the projectile lands, flame shock has worn off. 10. Added Earth Shock as an execute ability for elemental shamans only. This helps their DPS tremendously at low levels, as well as in PVP. There is logic in place to prevent the use of Earth Shock as elemental entirely on bosses (it's garbage on bosses), as it will only be used as an execute if the target has less than 1500 hp and it's at 25% hp or less. 10. Added chain lightning as an AoE option for enhancement shamans while maelstrom weapon is at 4 or 5 stacks. This continues to push the AoE dps on enhance higher! Here is a file-by-file list of the changes: conf\playerbots.conf.dist - Enhancement shamans use Fire Nova Glyph as early as level 15, they also use the clearcasting talent in elemental and improved shocks in enhance. It really helps their mana usage. Also swapped the position of two glyphs in resto. src\AiFactory.cpp - Set the default spec that new altbot shamans start as to Elemental. Put Arcane, Fire, and Frost comments on the mage specs. Set the strategies of the shaman specs to "ele, resto, and enh", as well as added the default totem strategies for each spec. Also added in the aoe strategy. Removed bmana/bdps, as those were set for lightning/mana sheld - those have been moved to both the non-combat strategy, as well as to each spec combat strategy. Enhancement will use Lightning Shield, and Elemental and Resto will use Water Shield both in and out of combat. src\strategy\shaman\CasterShamanStrategy.cpp/CasterShamanStrategy.h - Renamed to Elemental. src\strategy\shaman\ElementalShamanStrategy.cpp/ElementalShamanStrategy.h - Renamed from CasterShamanStrategy, most logic is the same. Moved the totem of wrath passthrough to the GenericShamanStrategy. Moved the Weapon Imbue to the NonCombatShamanStrategy. Moved the AoE spells to GenericShamanStrategy, under the AoE strategy there. Added the use of Stoneclaw totem, as well as Earth Shock Execute. Changed the use of Thunderstorm from medium mana to high mana, so it can be used more often in longer fights. Moved the individual casting of totems to the totem strategies. Added the use of Call of the Elements. src\strategy\shaman\EnhancementShamanStrategy.cpp/EnhancementShamanStrategy.h - Renamed from MeleeShamanStrategy. Moved the totem passthroughs to GenericShamanStrategy. Refined the priorities in the default actions and triggers to closer match guides online. Moved the weapon imbues to the non-combat strategy. Moved the individual casting of totems to the totem strategies. Moved the AoE spells to the AoE strategy in GenericShamanStrategy. Added the use of Call of the Elements (while in melee range) and Spirit Walk. src\strategy\shaman\GenericShamanStrategy.cpp/GenericShamanStrategy.h - Moved weapon imbue passthroughs to non-combat. Set up all totem passthroughs here so lower level shamans could function well. Set up a boost strategy for heroism/bloodlust/fire elemental totem. Set up an AoE strategy for Elemental/Enhancement. Cleaned up tablature of the code. Moved the Healer DPS strategy to the RestoShamanStrategy. Added a medium mana trigger so they can use more mana potions in longer fights. src\strategy\shaman\HealShamanStrategy.cpp/HealShamanStrategy.h - Renamed to RestoShamanStrategy. src\strategy\shaman\MeleeShamanStrategy.cpp/MeleeShamanStrategy.h - Renamed to EnhancementShamanStrategy. src\strategy\shaman\RestoShamanStrategy.cpp/RestoShamanStrategy.h - Renamed from HealShamanStrategy. Moved weapon imbue to non-combat strategy. Moved the individual casting of totems to the totem strategies (except mana tide totem). Added in Healer DPS from genericshamanstrategy. Added in use of Stoneclaw totem and Call of the Elements. src\strategy\shaman\ShamanActions.cpp/ShamanActions.h - Organized the actions by type. Removed the TTL check in the totem action and Flame Shock. Added logic in the Stoneclaw totem to only be used when not in a group. Added logic on LavaBurst Action to only be used when the target has flame shock debuff from the caster. Added custom logic for casting Spirit Walk (no code exists in AC/Playerbots to make a guardian cast a spell). Added in the "SetXTotemAction"s, which set a totem to the highest rank of the spell in the totem bar. src\strategy\shaman\ShamanAiObjectContext.cpp/ShamanAiObjectContext.h - Cleaned up strategies, triggers, and actions as a whole. Renamed melee, heal, and caster to ele, enh, and resto. Changed the "totems" strategy to individualized elemental totem strategies. src\strategy\shaman\ShamanNonCombatStrategy.cpp/ShamanNonCombatStrategy.cpp - Moved weapon imbues here. Cleaned up tablature. Added the Totemic Recall spell. src\strategy\shaman\ShamanTriggers.cpp/ShamanTriggers.h - Removed the commented out section. Added triggers + logic for: EarthShockExecute Call of the Elements Totemic Recall "SetXTotemTrigger" Spirit Walk Elemental Mastery No Earth/Fire/Water/Air Totem src\strategy\shaman\TotemsShamanStrategy.h - Master hub for all defined constants and arrays used in other files, as well as names all of the totem strategy types. src\strategy\shaman\TotemsShamanStrategy.cpp - Each strategy has a "set x totem" to change the bar totem, as well as a "no x totem" trigger with a corresponding "cast x totem". NOTE: some totems aren't learned by level 30 when a shaman learns call of the elements, so I had to set an alternative for those (Totem of Wrath, Wrath of Air, Cleansing Totem, and Windfury). Testing showed me that this is necessary - without this, the trigger would just fire over and over, and the shaman would recast the same totem over and over. Scope of Testing: 8/5/25 (2 hours): Began work on the Shaman class. Cleaned up actions and triggers. 8/6/25 (3.5 hours): Tried what felt like everything to get the totem bar changed. Seems impossible to change a client-side thing with cpp. 8/9/25(3 hours): Initial totem strategies created. Through the help of Revision, I was able make a functioning action that would change the totem bar's spell. The spells are stored in the database! I was able to get a strategy of each type working, and Call of the Elements was casting the correct totems. 8/10/25 (3.5 hours): Testing on Noth the Plaguebringer. The elemental shaman's dps was low - I noticed that the shaman was casting lava burst regardless of if the target had flame shock. I fixed this. I also noticed that the enhancement shaman was casting call of the elements at max range, resulting in the magma totem never doing damage. Changed so enhance would only cast Call of the Elements in melee range. Also, had to add "cast x totem" spells to each strategy, so magma totem would recast once expired (as well as other totems). 8/11/25 - (2.5 hours)Did a full run of Naxxramas. Enhancement did crazy dps for the gear it had. Elemental was consistently placing between 14-18th place of 18 dps. I noticed that totemic recall was messing up with the KT encounter, and had to look in the AC repo for logic to check if a boss encounter is active. Fixed it, and shamans weren't spamming totemic recall between packs. I wonder what I can do to fix elemental? 8/12/25 (1.5 hours) - Added a check in lava burst's isuseful to ensure flame shock was on the target. DPS went up a little bit. Also, made chain lightning the highest spell priority - DPS went up quite a bit after that. It is quite costly, but it is worth it - even on one target, but especially 3. Added spirit walk for enhancement. 8/13/25 - (5 hours) Tested on level 1-10 level, 15, 25, 35, 45, and 55 instances: I had a ton of bugs at level 35. Essentially, the shaman was standing there casting the totems it didn't know (wrath, cleansing, wrath of air). I had to add some checks and passthroughs for it to run smoothly again. Elemental was still doing just okay dps at lower levels, while enhancement was CRUSHING it. The fact that enhancement has the fire glyph from 15 on now is crazy. 8/14/2025 (2 hours) - Tested in 65/75 instances, as well as little bit of ulduar. I am pretty happy with the state of shamans now, they are consistently performing highly (enhance top 5, elemental top 8 in ulduar). Tweaked elemental mastery to cause lava burst to be instant cast, not chain lightning. This improved the DPS of elemental shamans right out of the gate. Total testing - 23 hours If y'all have any questions or comments, please let me know either here or on discord! * Fixed the Bracket so the code will compile Fixed the Bracket so the code will compile * - Code refactoring * - Non windows compilation error fixes --------- Co-authored-by: kadeshar <kadeshar@gmail.com>
This commit is contained in:
@@ -1429,11 +1429,11 @@ AiPlayerbot.PremadeSpecGlyph.7.0 = 41536,43385,41532,43386,44923,45776
|
||||
AiPlayerbot.PremadeSpecLink.7.0.60 = 4530001520213351102301351
|
||||
AiPlayerbot.PremadeSpecLink.7.0.80 = 3530001523213351322301351-005050031
|
||||
AiPlayerbot.PremadeSpecName.7.1 = enh pve
|
||||
AiPlayerbot.PremadeSpecGlyph.7.1 = 41542,43385,41539,43386,44923,45771
|
||||
AiPlayerbot.PremadeSpecLink.7.1.60 = -30205033005001333031131131051
|
||||
AiPlayerbot.PremadeSpecLink.7.1.80 = 053030052-30205033005021333031131131051
|
||||
AiPlayerbot.PremadeSpecGlyph.7.1 = 41530,43385,41539,43386,44923,45771
|
||||
AiPlayerbot.PremadeSpecLink.7.1.60 = -30305003105021333031121131051
|
||||
AiPlayerbot.PremadeSpecLink.7.1.80 = 053030152-30305003105021333031131131051
|
||||
AiPlayerbot.PremadeSpecName.7.2 = resto pve
|
||||
AiPlayerbot.PremadeSpecGlyph.7.2 = 41517,43385,41527,43386,44923,45775
|
||||
AiPlayerbot.PremadeSpecGlyph.7.2 = 41527,43385,41517,43386,44923,45775
|
||||
AiPlayerbot.PremadeSpecLink.7.2.60 = --50005301235310501102321251
|
||||
AiPlayerbot.PremadeSpecLink.7.2.80 = -00502033-50005331335310501122331251
|
||||
AiPlayerbot.PremadeSpecName.7.3 = ele pvp
|
||||
|
||||
@@ -91,6 +91,9 @@ uint8 AiFactory::GetPlayerSpecTab(Player* bot)
|
||||
case CLASS_WARLOCK:
|
||||
tab = WARLOCK_TAB_DEMONOLOGY;
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
tab = SHAMAN_TAB_ELEMENTAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return tab;
|
||||
@@ -304,9 +307,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategiesNoInit("dps assist", "cure", nullptr);
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
if (tab == 0)
|
||||
if (tab == 0) // Arcane
|
||||
engine->addStrategiesNoInit("arcane", nullptr);
|
||||
else if (tab == 1)
|
||||
else if (tab == 1) // Fire
|
||||
{
|
||||
if (player->HasSpell(44614) /*Frostfire Bolt*/ && player->HasAura(15047) /*Ice Shards*/)
|
||||
{
|
||||
@@ -317,7 +320,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategiesNoInit("fire", nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
else // Frost
|
||||
engine->addStrategiesNoInit("frost", nullptr);
|
||||
|
||||
engine->addStrategiesNoInit("dps", "dps assist", "cure", "aoe", nullptr);
|
||||
@@ -331,14 +334,14 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategiesNoInit("fury", "aoe", "dps assist", /*"behind",*/ nullptr);
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab == 0)
|
||||
engine->addStrategiesNoInit("caster", "caster aoe", "bmana", nullptr);
|
||||
else if (tab == 2)
|
||||
engine->addStrategiesNoInit("heal", "bmana", nullptr);
|
||||
else
|
||||
engine->addStrategiesNoInit("melee", "melee aoe", "bdps", nullptr);
|
||||
if (tab == 0) // Elemental
|
||||
engine->addStrategiesNoInit("ele", "stoneskin", "wrath", "mana spring", "wrath of air", nullptr);
|
||||
else if (tab == 2) // Restoration
|
||||
engine->addStrategiesNoInit("resto", "stoneskin", "flametongue", "mana spring", "wrath of air", nullptr);
|
||||
else // Enhancement
|
||||
engine->addStrategiesNoInit("enh", "strength of earth", "magma", "healing stream", "windfury", nullptr);
|
||||
|
||||
engine->addStrategiesNoInit("dps assist", "cure", "totems", nullptr);
|
||||
engine->addStrategiesNoInit("dps assist", "cure", "aoe", nullptr);
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (tab == 1)
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "CasterShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class CasterShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
CasterShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["magma totem"] = &magma_totem;
|
||||
creators["totem of wrath"] = &totem_of_wrath;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("magma totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ NextAction::array(0, new NextAction("fire nova"), nullptr));
|
||||
}
|
||||
static ActionNode* totem_of_wrath([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("totem of wrath",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new CasterShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
NextAction** CasterShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
|
||||
new NextAction("lightning bolt", ACTION_DEFAULT + 0.1f),
|
||||
// new NextAction("earth shock", ACTION_DEFAULT), // cast during movement
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
|
||||
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
|
||||
// NextAction("flametongue weapon", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"enough mana", NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",
|
||||
NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f),
|
||||
// nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("elemental mastery",
|
||||
NextAction::array(0, new NextAction("elemental mastery", 27.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("no fire totem", NextAction::array(0,
|
||||
new NextAction("totem of wrath", 15.0f),
|
||||
new NextAction("searing totem", 6.0f),
|
||||
nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("fire elemental totem",
|
||||
NextAction::array(0, new NextAction("fire elemental totem", 32.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium mana", NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
||||
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy is close",
|
||||
NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell",
|
||||
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||
}
|
||||
|
||||
void CasterAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("light aoe", NextAction::array(0, new NextAction("chain lightning", 25.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fire nova", 24.0f), nullptr)));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_CASTSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_CASTSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CasterShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
CasterShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
NextAction** getDefaultActions() override;
|
||||
std::string const getName() override { return "caster"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_RANGED; }
|
||||
};
|
||||
|
||||
class CasterAoeShamanStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
CasterAoeShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "caster aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
76
src/strategy/shaman/ElementalShamanStrategy.cpp
Normal file
76
src/strategy/shaman/ElementalShamanStrategy.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "ElementalShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class ElementalShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
ElementalShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["flame shock"] = &flame_shock;
|
||||
creators["earth shock"] = &earth_shock;
|
||||
creators["lava burst"] = &lava_burst;
|
||||
creators["lightning bolt"] = &lightning_bolt;
|
||||
creators["call of the elements"] = &call_of_the_elements;
|
||||
creators["elemental mastery"] = &elemental_mastery;
|
||||
creators["stoneclaw totem"] = &stoneclaw_totem;
|
||||
creators["water shield"] = &water_shield;
|
||||
creators["thunderstorm"] = &thunderstorm;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* elemental_mastery(PlayerbotAI*) { return new ActionNode("elemental mastery", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* thunderstorm(PlayerbotAI*) { return new ActionNode("thunderstorm", nullptr, nullptr, nullptr); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
ElementalShamanStrategy::ElementalShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new ElementalShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
NextAction** ElementalShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(0, new NextAction("lava burst", 5.2f),
|
||||
new NextAction("lightning bolt", 5.0f),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void ElementalShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// Totem Triggers
|
||||
triggers.push_back(new TriggerNode("call of the elements", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("stoneclaw totem", 40.0f), nullptr)));
|
||||
|
||||
// Cooldown Trigger
|
||||
triggers.push_back(new TriggerNode("elemental mastery", NextAction::array(0, new NextAction("elemental mastery", 29.0f), nullptr)));
|
||||
|
||||
// Damage Triggers
|
||||
triggers.push_back(new TriggerNode("earth shock execute", NextAction::array(0, new NextAction("earth shock", 5.5f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 5.3f), nullptr)));
|
||||
|
||||
// Mana Triggers
|
||||
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 19.5f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("high mana", NextAction::array(0, new NextAction("thunderstorm", 19.0f), nullptr)));
|
||||
|
||||
// Range Triggers
|
||||
triggers.push_back(new TriggerNode("enemy is close", NextAction::array(0, new NextAction("thunderstorm", 19.0f), nullptr)));
|
||||
}
|
||||
|
||||
24
src/strategy/shaman/ElementalShamanStrategy.h
Normal file
24
src/strategy/shaman/ElementalShamanStrategy.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_ELEMENTALSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_ELEMENTALSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ElementalShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
ElementalShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
NextAction** getDefaultActions() override;
|
||||
std::string const getName() override { return "ele"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_RANGED; }
|
||||
};
|
||||
|
||||
#endif
|
||||
83
src/strategy/shaman/EnhancementShamanStrategy.cpp
Normal file
83
src/strategy/shaman/EnhancementShamanStrategy.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "EnhancementShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class EnhancementShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
EnhancementShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["stormstrike"] = &stormstrike;
|
||||
creators["lava lash"] = &lava_lash;
|
||||
creators["feral spirit"] = &feral_spirit;
|
||||
creators["lightning bolt"] = &lightning_bolt;
|
||||
creators["earth shock"] = &earth_shock;
|
||||
creators["flame shock"] = &flame_shock;
|
||||
creators["shamanistic rage"] = &shamanistic_rage;
|
||||
creators["call of the elements"] = &call_of_the_elements;
|
||||
creators["lightning shield"] = &lightning_shield;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* stormstrike(PlayerbotAI*) { return new ActionNode("stormstrike", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lava_lash([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("lava lash",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("melee"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* feral_spirit(PlayerbotAI*) { return new ActionNode("feral spirit", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* shamanistic_rage(PlayerbotAI*) { return new ActionNode("shamanistic rage", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lightning_shield(PlayerbotAI*) { return new ActionNode("lightning shield", nullptr, nullptr, nullptr); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
EnhancementShamanStrategy::EnhancementShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new EnhancementShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
NextAction** EnhancementShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(0,
|
||||
new NextAction("stormstrike", 5.5f),
|
||||
new NextAction("feral spirit", 5.4f),
|
||||
new NextAction("earth shock", 5.3f),
|
||||
new NextAction("lava lash", 5.2f),
|
||||
new NextAction("melee", 5.0f), NULL);
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void EnhancementShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// Totem Trigger
|
||||
triggers.push_back(new TriggerNode("call of the elements and enemy within melee", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
|
||||
|
||||
// Spirit Walk Trigger
|
||||
triggers.push_back(new TriggerNode("spirit walk ready", NextAction::array(0, new NextAction("spirit walk", 50.0f), nullptr)));
|
||||
|
||||
// Damage Triggers
|
||||
triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", 40.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 5", NextAction::array(0, new NextAction("lightning bolt", 20.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 4", NextAction::array(0, new NextAction("lightning bolt", 19.5f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 19.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 18.5f), nullptr)));
|
||||
|
||||
// Health/Mana Triggers
|
||||
triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
||||
}
|
||||
@@ -3,31 +3,22 @@
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_MELEESHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_MELEESHAMANSTRATEGY_H
|
||||
#ifndef _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class MeleeShamanStrategy : public GenericShamanStrategy
|
||||
class EnhancementShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
MeleeShamanStrategy(PlayerbotAI* botAI);
|
||||
EnhancementShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
NextAction** getDefaultActions() override;
|
||||
std::string const getName() override { return "melee"; }
|
||||
std::string const getName() override { return "enh"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
class MeleeAoeShamanStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
MeleeAoeShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "melee aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,109 +4,95 @@
|
||||
*/
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "HealShamanStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["flametongue weapon"] = &flametongue_weapon;
|
||||
creators["frostbrand weapon"] = &frostbrand_weapon;
|
||||
creators["windfury weapon"] = &windfury_weapon;
|
||||
creators["lesser healing wave"] = &lesser_healing_wave;
|
||||
creators["lesser healing wave on party"] = &lesser_healing_wave_on_party;
|
||||
creators["chain heal on party"] = &chain_heal;
|
||||
creators["riptide"] = &riptide;
|
||||
creators["riptide on party"] = &riptide_on_party;
|
||||
creators["earth shock"] = &earth_shock;
|
||||
creators["water shield"] = &water_shield;
|
||||
creators["totem of wrath"] = &totem_of_wrath;
|
||||
creators["flametongue totem"] = &flametongue_totem;
|
||||
creators["magma totem"] = &magma_totem;
|
||||
creators["searing totem"] = &searing_totem;
|
||||
creators["strength of earth totem"] = &strength_of_earth_totem;
|
||||
creators["stoneskin totem"] = &stoneskin_totem;
|
||||
creators["cleansing totem"] = &cleansing_totem;
|
||||
creators["mana spring totem"] = &mana_spring_totem;
|
||||
creators["healing stream totem"] = &healing_stream_totem;
|
||||
creators["wrath of air totem"] = &wrath_of_air_totem;
|
||||
creators["windfury totem"] = &windfury_totem;
|
||||
creators["grounding totem"] = &grounding_totem;
|
||||
creators["wind shear"] = &wind_shear;
|
||||
creators["purge"] = &purge;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* earth_shock([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("earth shock",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flame shock"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* flametongue_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("flametongue weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("rockbiter weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* frostbrand_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frostbrand weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* windfury_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("windfury weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* lesser_healing_wave([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("lesser healing wave",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("healing wave"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* lesser_healing_wave_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("lesser healing wave on party",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("healing wave on party"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* chain_heal([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("chain heal on party",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("lesser healing wave on party"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* riptide([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("riptide",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("healing wave"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* riptide_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("riptide on party",
|
||||
/*P*/ nullptr,
|
||||
// /*A*/ NextAction::array(0, new NextAction("healing wave on party"), nullptr),
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* water_shield([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("water shield",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("lightning shield"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
// Passthrough totems are set up so lower level shamans will still cast totems.
|
||||
// Totem of Wrath -> Flametongue Totem -> Searing Totem
|
||||
// Magma Totem -> Searing Totem
|
||||
// Strength of Earth Totem -> Stoneskin Totem
|
||||
// Cleansing Totem -> Mana Spring Totem
|
||||
// Wrath of Air Totem -> Windfury Totem -> Grounding Totem
|
||||
|
||||
static ActionNode* totem_of_wrath([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("totem of wrath",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* flametongue_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("flametongue totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("searing totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("magma totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("searing totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* searing_totem(PlayerbotAI*) { return new ActionNode("searing totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* strength_of_earth_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("strength of earth totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("stoneskin totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* stoneskin_totem(PlayerbotAI*) { return new ActionNode("stoneskin totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* cleansing_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cleansing totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("mana spring totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* mana_spring_totem(PlayerbotAI*) { return new ActionNode("mana spring totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* healing_stream_totem(PlayerbotAI*) { return new ActionNode("healing stream totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* wrath_of_air_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("wrath of air totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("windfury totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* windfury_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("windfury totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("grounding totem"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* grounding_totem(PlayerbotAI*) { return new ActionNode("grounding totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", nullptr, nullptr, nullptr); }
|
||||
};
|
||||
|
||||
GenericShamanStrategy::GenericShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
@@ -118,75 +104,68 @@ void GenericShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("wind shear", NextAction::array(0, new NextAction("wind shear", 23.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("wind shear on enemy healer",
|
||||
NextAction::array(0, new NextAction("wind shear on enemy healer", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("wind shear", NextAction::array(0, new NextAction("wind shear", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("wind shear on enemy healer", NextAction::array(0, new NextAction("wind shear on enemy healer", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("purge", NextAction::array(0, new NextAction("purge", ACTION_DISPEL), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0, new NextAction("lesser
|
||||
// healing wave on party", 25.0f), nullptr))); triggers.push_back(new TriggerNode("party member low health",
|
||||
// NextAction::array(0, new NextAction("riptide on party", 25.0f), nullptr))); triggers.push_back(new
|
||||
// TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("chain heal on party", 27.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("lesser healing
|
||||
// wave", 26.0f), nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new
|
||||
// NextAction("riptide", 26.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 31.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 22.0f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana potion", ACTION_DISPEL), nullptr)));
|
||||
triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison",
|
||||
NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit poison",
|
||||
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cleanse spirit poison",
|
||||
NextAction::array(0, new NextAction("cleanse spirit poison on party", 23.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure disease",
|
||||
NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit disease",
|
||||
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cleanse spirit disease",
|
||||
NextAction::array(0, new NextAction("cleanse spirit disease on party", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit curse",
|
||||
NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cleanse spirit curse",
|
||||
NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit poison on party", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure disease", NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit disease on party", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit curse", NextAction::array(0, new NextAction("cleanse spirit", 24.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit curse", NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
void ShamanBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("healer should attack",
|
||||
NextAction::array(0,
|
||||
new NextAction("flame shock", ACTION_DEFAULT + 0.2f),
|
||||
new NextAction("lava burst", ACTION_DEFAULT + 0.1f),
|
||||
new NextAction("lightning bolt", ACTION_DEFAULT), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe and healer should attack",
|
||||
NextAction::array(0,
|
||||
new NextAction("chain lightning", ACTION_DEFAULT + 0.3f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("heroism", NextAction::array(0, new NextAction("heroism", 30.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("bloodlust", NextAction::array(0, new NextAction("bloodlust", 30.0f), nullptr)));
|
||||
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Elemental
|
||||
{
|
||||
triggers.push_back(new TriggerNode("fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem", 23.0f), nullptr)));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem melee", 24.0f), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
void ShamanAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Elemental
|
||||
{
|
||||
triggers.push_back(new TriggerNode("medium aoe",NextAction::array(0, new NextAction("fire nova", 23.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("chain lightning no cd", NextAction::array(0, new NextAction("chain lightning", 5.6f), nullptr)));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("medium aoe",NextAction::array(0,
|
||||
new NextAction("magma totem", 24.0f),
|
||||
new NextAction("fire nova", 23.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 5 and medium aoe", NextAction::array(0, new NextAction("chain lightning", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 4 and medium aoe", NextAction::array(0, new NextAction("chain lightning", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("enemy within melee", NextAction::array(0, new NextAction("fire nova", 5.1f), nullptr)));
|
||||
}
|
||||
else if (tab == 2) // Restoration
|
||||
{
|
||||
// Handled by "Healer DPS" Strategy
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,24 +18,6 @@ public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class ShamanBuffDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanBuffDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bdps"; }
|
||||
};
|
||||
|
||||
class ShamanBuffManaStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanBuffManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bmana"; }
|
||||
};
|
||||
|
||||
class ShamanCureStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
@@ -45,13 +27,22 @@ public:
|
||||
std::string const getName() override { return "cure"; }
|
||||
};
|
||||
|
||||
class ShamanHealerDpsStrategy : public Strategy
|
||||
class ShamanBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
ShamanBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "healer dps"; }
|
||||
std::string const getName() override { return "boost"; }
|
||||
};
|
||||
|
||||
class ShamanAoeStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
ShamanAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "HealShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class HealShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
HealShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["earthliving weapon"] = &earthliving_weapon;
|
||||
creators["mana tide totem"] = &mana_tide_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* earthliving_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("earthliving weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* mana_tide_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mana tide totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("mana potion"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
HealShamanStrategy::HealShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new HealShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void HealShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
|
||||
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
|
||||
// NextAction("earthliving weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",
|
||||
NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"group heal setting",
|
||||
NextAction::array(0, new NextAction("riptide on party", 27.0f), new NextAction("chain heal on party", 26.0f), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member critical health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 25.0f), new NextAction("healing wave on party", 24.0f),
|
||||
new NextAction("lesser healing wave on party", 23.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member low health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 19.0f), new NextAction("healing wave on party", 18.0f),
|
||||
new NextAction("lesser healing wave on party", 17.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member medium health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 16.0f), new NextAction("healing wave on party", 15.0f),
|
||||
new NextAction("lesser healing wave on party", 14.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member almost full health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 12.0f),
|
||||
new NextAction("lesser healing wave on party", 11.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cleanse spirit poison",
|
||||
NextAction::array(0, new NextAction("cleanse spirit poison on party", ACTION_DISPEL + 2),
|
||||
new NextAction("cleansing totem", ACTION_DISPEL + 2), NULL)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cleanse spirit disease",
|
||||
NextAction::array(0, new NextAction("cleanse spirit disease on party", ACTION_DISPEL + 2),
|
||||
new NextAction("cleansing totem", ACTION_DISPEL + 1), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"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("flametongue totem", 10.0f), NULL)));
|
||||
|
||||
// triggers.push_back(new TriggerNode(
|
||||
// "no water totem",
|
||||
// NextAction::array(0, new NextAction("healing stream totem", 13.0f), NULL)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("earth shield on main tank",
|
||||
NextAction::array(0, new NextAction("earth shield on main tank", ACTION_HIGH + 7), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell",
|
||||
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana tide totem", ACTION_HIGH + 5), NULL)));
|
||||
|
||||
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("fire elemental totem",
|
||||
NextAction::array(0, new NextAction("fire elemental totem", 32.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member to heal out of spell range",
|
||||
NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_HEALSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_HEALSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class HealShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
HealShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "heal"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_RANGED | STRATEGY_TYPE_HEAL; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "MeleeShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class MeleeShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
MeleeShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["stormstrike"] = &stormstrike;
|
||||
creators["lava lash"] = &lava_lash;
|
||||
creators["magma totem"] = &magma_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* stormstrike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("stormstrike",
|
||||
/*P*/ nullptr,
|
||||
// /*A*/ NextAction::array(0, new NextAction("lava lash"), nullptr),
|
||||
nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* lava_lash([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("lava lash",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("melee"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("magma totem",
|
||||
/*P*/ NULL,
|
||||
/*A*/ NextAction::array(0, new NextAction("searing totem"), NULL),
|
||||
/*C*/ NULL);
|
||||
}
|
||||
};
|
||||
|
||||
MeleeShamanStrategy::MeleeShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new MeleeShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
NextAction** MeleeShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return NextAction::array(
|
||||
0, 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), NULL);
|
||||
}
|
||||
|
||||
void MeleeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("flametongue
|
||||
// weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",
|
||||
NextAction::array(0, new NextAction("windfury weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("off hand weapon no imbue",
|
||||
NextAction::array(0, new NextAction("flametongue weapon", 21.0f), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("reach melee", 22.0f),
|
||||
// new NextAction("searing totem", 22.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("flame shock", NextAction::array(0, new NextAction("flame shock", 20.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("maelstrom weapon 4", NextAction::array(0, new NextAction("lightning bolt", 25.0f), 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_HIGH + 1), 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)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"fire elemental totem", NextAction::array(0, new NextAction("fire elemental totem melee", 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)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("low health", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
||||
}
|
||||
|
||||
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("medium aoe", NextAction::array(0, new NextAction("fire nova", 25.0f), nullptr)));
|
||||
}
|
||||
124
src/strategy/shaman/RestoShamanStrategy.cpp
Normal file
124
src/strategy/shaman/RestoShamanStrategy.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "RestoShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class RestoShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
RestoShamanStrategyActionNodeFactory()
|
||||
{
|
||||
creators["mana tide totem"] = &mana_tide_totem;
|
||||
creators["call of the elements"] = &call_of_the_elements;
|
||||
creators["stoneclaw totem"] = &stoneclaw_totem;
|
||||
creators["riptide on party"] = &riptide_on_party;
|
||||
creators["chain heal on party"] = &chain_heal_on_party;
|
||||
creators["healing wave on party"] = &healing_wave_on_party;
|
||||
creators["lesser healing wave on party"] = &lesser_healing_wave_on_party;
|
||||
creators["earth shield on main tank"] = &earth_shield_on_main_tank;
|
||||
creators["cleanse spirit poison on party"] = &cleanse_spirit_poison_on_party;
|
||||
creators["cleanse spirit disease on party"] = &cleanse_spirit_disease_on_party;
|
||||
creators["cleanse spirit curse on party"] = &cleanse_spirit_curse_on_party;
|
||||
creators["cleansing totem"] = &cleansing_totem;
|
||||
creators["water shield"] = &water_shield;
|
||||
creators["flame shock"] = &flame_shock;
|
||||
creators["lava burst"] = &lava_burst;
|
||||
creators["lightning bolt"] = &lightning_bolt;
|
||||
creators["chain lightning"] = &chain_lightning;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* mana_tide_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mana tide totem",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("mana potion"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* riptide_on_party(PlayerbotAI*) { return new ActionNode("riptide on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* chain_heal_on_party(PlayerbotAI*) { return new ActionNode("chain heal on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* healing_wave_on_party(PlayerbotAI*) { return new ActionNode("healing wave on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lesser_healing_wave_on_party(PlayerbotAI*) { return new ActionNode("lesser healing wave on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* earth_shield_on_main_tank(PlayerbotAI*) { return new ActionNode("earth shield on main tank", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* cleanse_spirit_poison_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit poison on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* cleanse_spirit_disease_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit disease on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* cleanse_spirit_curse_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit curse on party", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* cleansing_totem(PlayerbotAI*) { return new ActionNode("cleansing totem", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* chain_lightning(PlayerbotAI*) { return new ActionNode("chain lightning", nullptr, nullptr, nullptr); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
RestoShamanStrategy::RestoShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new RestoShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void RestoShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// Totem Triggers
|
||||
triggers.push_back(new TriggerNode("call of the elements", NextAction::array(0, new NextAction("call of the elements", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("stoneclaw totem", 40.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("mana tide totem", ACTION_HIGH + 5), NULL)));
|
||||
|
||||
// Healing Triggers
|
||||
triggers.push_back(new TriggerNode("group heal setting", NextAction::array(0,
|
||||
new NextAction("riptide on party", 27.0f),
|
||||
new NextAction("chain heal on party", 26.0f), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0,
|
||||
new NextAction("riptide on party", 25.0f),
|
||||
new NextAction("healing wave on party", 24.0f),
|
||||
new NextAction("lesser healing wave on party", 23.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member low health", NextAction::array(0,
|
||||
new NextAction("riptide on party", 19.0f),
|
||||
new NextAction("healing wave on party", 18.0f),
|
||||
new NextAction("lesser healing wave on party", 17.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0,
|
||||
new NextAction("riptide on party", 16.0f),
|
||||
new NextAction("healing wave on party", 15.0f),
|
||||
new NextAction("lesser healing wave on party", 14.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0,
|
||||
new NextAction("riptide on party", 12.0f),
|
||||
new NextAction("lesser healing wave on party", 11.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("earth shield on main tank", NextAction::array(0, new NextAction("earth shield on main tank", ACTION_HIGH + 7), NULL)));
|
||||
|
||||
// Dispel Triggers
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit poison", NextAction::array(0, new NextAction("cleanse spirit poison on party", ACTION_DISPEL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit disease", NextAction::array(0, new NextAction("cleanse spirit disease on party", ACTION_DISPEL + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit curse",NextAction::array(0, new NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2), NULL)));
|
||||
|
||||
// Range/Mana Triggers
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 19.5f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("healer should attack",
|
||||
NextAction::array(0, new NextAction("flame shock", ACTION_DEFAULT + 0.2f),
|
||||
new NextAction("lava burst", ACTION_DEFAULT + 0.1f),
|
||||
new NextAction("lightning bolt", ACTION_DEFAULT), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe and healer should attack",
|
||||
NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.3f), nullptr)));
|
||||
}
|
||||
33
src/strategy/shaman/RestoShamanStrategy.h
Normal file
33
src/strategy/shaman/RestoShamanStrategy.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_RESTOSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_RESTOSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class RestoShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
RestoShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "resto"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_RANGED | STRATEGY_TYPE_HEAL; }
|
||||
};
|
||||
|
||||
class ShamanHealerDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "healer dps"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,42 +4,17 @@
|
||||
*/
|
||||
|
||||
#include "ShamanActions.h"
|
||||
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Totem.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Action.h"
|
||||
|
||||
bool CastTotemAction::isUseful()
|
||||
{
|
||||
if (needLifeTime > 0.1f && AI_VALUE(uint8, "attacker count") < 3)
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float dps = AI_VALUE(float, "estimated 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()
|
||||
{
|
||||
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "healing stream totem");
|
||||
}
|
||||
|
||||
bool CastFlametongueTotemAction::isUseful()
|
||||
{
|
||||
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "magma totem") &&
|
||||
!botAI->HasAura("totem of wrath", bot);
|
||||
}
|
||||
|
||||
bool CastSearingTotemAction::isUseful()
|
||||
{
|
||||
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "flametongue totem");
|
||||
return CastBuffSpellAction::isUseful()
|
||||
&& !AI_VALUE2(bool, "has totem", name)
|
||||
&& !botAI->HasAura(buff, bot);
|
||||
}
|
||||
|
||||
bool CastMagmaTotemAction::isUseful() {
|
||||
@@ -67,4 +42,70 @@ bool CastFireNovaAction::isUseful() {
|
||||
bool CastCleansingTotemAction::isUseful()
|
||||
{
|
||||
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", "mana tide totem");
|
||||
}
|
||||
}
|
||||
|
||||
// Will only cast Stoneclaw Totem if low on health and not in a group
|
||||
bool CastStoneclawTotemAction::isUseful() { return !botAI->GetBot()->GetGroup(); }
|
||||
|
||||
// Will only cast Lava Burst if Flame Shock is on the target
|
||||
bool CastLavaBurstAction::isUseful()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
static const uint32 FLAME_SHOCK_IDS[] = {8050, 8052, 8053, 10447, 10448, 29228, 25457, 49232, 49233};
|
||||
|
||||
ObjectGuid botGuid = botAI->GetBot()->GetGUID();
|
||||
for (uint32 spellId : FLAME_SHOCK_IDS)
|
||||
{
|
||||
if (target->HasAura(spellId, botGuid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Logic for making a guardian (spirit wolf) use a spell (spirit walk)
|
||||
// There is no existing code for guardians casting spells in the AC/Playerbots repo.
|
||||
bool CastSpiritWalkAction::Execute(Event event)
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
constexpr uint32 SPIRIT_WOLF = 29264;
|
||||
constexpr uint32 SPIRIT_WALK_SPELL = 58875;
|
||||
|
||||
for (Unit* unit : bot->m_Controlled)
|
||||
{
|
||||
if (unit->GetEntry() == SPIRIT_WOLF)
|
||||
{
|
||||
if (unit->HasSpell(SPIRIT_WALK_SPELL))
|
||||
{
|
||||
unit->CastSpell(unit, SPIRIT_WALK_SPELL, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set Strategy Assigned Totems (Actions) - First, it checks
|
||||
// the highest-rank spell the bot knows for each totem type,
|
||||
// then adds it to the Call of the Elements bar.
|
||||
|
||||
bool SetTotemAction::Execute(Event event)
|
||||
{
|
||||
size_t spellIdsCount = sizeof(totemSpellIds) / sizeof(uint32);
|
||||
|
||||
uint32 totemSpell = 0;
|
||||
for (int i = spellIdsCount - 1; i >= 0; --i)
|
||||
{
|
||||
if (bot->HasSpell(totemSpellIds[i]))
|
||||
{
|
||||
totemSpell = totemSpellIds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!totemSpell)
|
||||
return false;
|
||||
bot->addActionButton(actionButtonId, totemSpell, ACTION_BUTTON_SPELL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,286 @@
|
||||
#include "GenericSpellActions.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "TotemsShamanStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
// Buff and Out of Combat Actions
|
||||
|
||||
class CastWaterShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water shield") {}
|
||||
};
|
||||
|
||||
class CastLightningShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastLightningShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "lightning shield") {}
|
||||
};
|
||||
|
||||
class CastEarthlivingWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastEarthlivingWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "earthliving weapon") {}
|
||||
};
|
||||
|
||||
class CastRockbiterWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastRockbiterWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "rockbiter weapon") {}
|
||||
};
|
||||
|
||||
class CastFlametongueWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastFlametongueWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "flametongue weapon") {}
|
||||
};
|
||||
|
||||
class CastFrostbrandWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastFrostbrandWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "frostbrand weapon") {}
|
||||
};
|
||||
|
||||
class CastWindfuryWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastWindfuryWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "windfury weapon") {}
|
||||
};
|
||||
|
||||
class CastAncestralSpiritAction : public ResurrectPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastAncestralSpiritAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "ancestral spirit") {}
|
||||
};
|
||||
|
||||
class CastWaterBreathingAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterBreathingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water breathing") {}
|
||||
};
|
||||
|
||||
class CastWaterWalkingAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterWalkingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water walking") {}
|
||||
};
|
||||
|
||||
class CastWaterBreathingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastWaterBreathingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water breathing") {}
|
||||
};
|
||||
|
||||
class CastWaterWalkingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastWaterWalkingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water walking") {}
|
||||
};
|
||||
|
||||
// Boost Actions
|
||||
|
||||
class CastHeroismAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastHeroismAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "heroism") {}
|
||||
};
|
||||
|
||||
class CastBloodlustAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodlustAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bloodlust") {}
|
||||
};
|
||||
|
||||
class CastElementalMasteryAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastElementalMasteryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "elemental mastery") {}
|
||||
};
|
||||
|
||||
class CastShamanisticRageAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {}
|
||||
};
|
||||
|
||||
class CastFeralSpiritAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {}
|
||||
};
|
||||
|
||||
class CastSpiritWalkAction : public Action
|
||||
{
|
||||
public:
|
||||
CastSpiritWalkAction(PlayerbotAI* botAI) : Action(botAI, "spirit walk") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
// CC, Interrupt, and Dispel Actions
|
||||
|
||||
class CastWindShearAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastWindShearAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class CastWindShearOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class CastPurgeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastPurgeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "purge") {}
|
||||
};
|
||||
|
||||
class CastCleanseSpiritAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse spirit") {}
|
||||
};
|
||||
|
||||
class CastCleanseSpiritPoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritPoisonOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_POISON)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit poison on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseSpiritCurseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritCurseOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit curse on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseSpiritDiseaseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritDiseaseOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit disease on party"; }
|
||||
};
|
||||
|
||||
class CastCurePoisonActionSham : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCurePoisonActionSham(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure poison") {}
|
||||
};
|
||||
|
||||
class CastCurePoisonOnPartyActionSham : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCurePoisonOnPartyActionSham(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure poison", DISPEL_POISON) {}
|
||||
|
||||
std::string const getName() override { return "cure poison on party"; }
|
||||
};
|
||||
|
||||
class CastCureDiseaseActionSham : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCureDiseaseActionSham(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure disease") {}
|
||||
};
|
||||
|
||||
class CastCureDiseaseOnPartyActionSham : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCureDiseaseOnPartyActionSham(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure disease", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cure disease on party"; }
|
||||
};
|
||||
|
||||
// Damage and Debuff Actions
|
||||
|
||||
class CastFireNovaAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastFireNovaAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "fire nova") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastStormstrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastStormstrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "stormstrike") {}
|
||||
};
|
||||
|
||||
class CastLavaLashAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastLavaLashAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "lava lash") {}
|
||||
};
|
||||
|
||||
class CastFlameShockAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true, 6.0f) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastEarthShockAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEarthShockAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "earth shock") {}
|
||||
};
|
||||
|
||||
class CastFrostShockAction : public CastSnareSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostShockAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "frost shock") {}
|
||||
};
|
||||
|
||||
class CastChainLightningAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastChainLightningAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chain lightning") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastLightningBoltAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastLightningBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "lightning bolt") {}
|
||||
};
|
||||
|
||||
class CastThunderstormAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastThunderstormAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "thunderstorm") {}
|
||||
};
|
||||
|
||||
class CastLavaBurstAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastLavaBurstAction(PlayerbotAI* ai) : CastSpellAction(ai, "lava burst") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
|
||||
// Healing Actions
|
||||
|
||||
class CastLesserHealingWaveAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
@@ -78,351 +355,109 @@ public:
|
||||
CastEarthShieldOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "earth shield") {}
|
||||
};
|
||||
|
||||
class CastWaterShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water shield") {}
|
||||
};
|
||||
|
||||
class CastLightningShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastLightningShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "lightning shield") {}
|
||||
};
|
||||
|
||||
class CastEarthlivingWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastEarthlivingWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "earthliving weapon") {}
|
||||
};
|
||||
|
||||
class CastRockbiterWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastRockbiterWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "rockbiter weapon") {}
|
||||
};
|
||||
|
||||
class CastFlametongueWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastFlametongueWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "flametongue weapon") {}
|
||||
};
|
||||
|
||||
class CastFrostbrandWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastFrostbrandWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "frostbrand weapon") {}
|
||||
};
|
||||
|
||||
class CastWindfuryWeaponAction : public CastEnchantItemAction
|
||||
{
|
||||
public:
|
||||
CastWindfuryWeaponAction(PlayerbotAI* botAI) : CastEnchantItemAction(botAI, "windfury weapon") {}
|
||||
};
|
||||
|
||||
class CastTotemAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
CastStoneskinTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneskin totem") {}
|
||||
};
|
||||
|
||||
class CastEarthbindTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastEarthbindTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "earthbind totem") {}
|
||||
};
|
||||
|
||||
class CastStrengthOfEarthTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
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", "mana spring", 0.0f) {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastManaTideTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastManaTideTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana tide totem") {}
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
};
|
||||
|
||||
class CastHealingStreamTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastHealingStreamTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "healing stream totem") {}
|
||||
};
|
||||
|
||||
class CastCleansingTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastCleansingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "cleansing totem") {}
|
||||
virtual bool isUseful();
|
||||
};
|
||||
|
||||
class CastFlametongueTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "", 20.0f) {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastWindfuryTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastWindfuryTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "windfury totem") {}
|
||||
};
|
||||
|
||||
class CastGraceOfAirTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastGraceOfAirTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "grace of air totem") {}
|
||||
};
|
||||
|
||||
class CastSearingTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem", "", 0.0f) {}
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastMagmaTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastMagmaTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "magma totem", "", 0.0f) {}
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastFireNovaAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastFireNovaAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "fire nova") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastWindShearAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastWindShearAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class CastAncestralSpiritAction : public ResurrectPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastAncestralSpiritAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "ancestral spirit") {}
|
||||
};
|
||||
|
||||
class CastPurgeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastPurgeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "purge") {}
|
||||
};
|
||||
|
||||
class CastStormstrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastStormstrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "stormstrike") {}
|
||||
};
|
||||
|
||||
class CastLavaLashAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastLavaLashAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "lava lash") {}
|
||||
};
|
||||
|
||||
class CastWaterBreathingAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterBreathingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water breathing") {}
|
||||
};
|
||||
|
||||
class CastWaterWalkingAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWaterWalkingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "water walking") {}
|
||||
};
|
||||
|
||||
class CastWaterBreathingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastWaterBreathingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water breathing") {}
|
||||
};
|
||||
|
||||
class CastWaterWalkingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastWaterWalkingOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "water walking") {}
|
||||
};
|
||||
|
||||
class CastCleanseSpiritAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse spirit") {}
|
||||
};
|
||||
|
||||
class CastCleanseSpiritPoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritPoisonOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_POISON)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit poison on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseSpiritCurseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritCurseOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit curse on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseSpiritDiseaseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseSpiritDiseaseOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "cleanse spirit", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "cleanse spirit disease on party"; }
|
||||
};
|
||||
|
||||
class CastFlameShockAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true, 6.0f) {}
|
||||
};
|
||||
|
||||
class CastEarthShockAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEarthShockAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "earth shock") {}
|
||||
};
|
||||
|
||||
class CastFrostShockAction : public CastSnareSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostShockAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "frost shock") {}
|
||||
};
|
||||
|
||||
class CastChainLightningAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastChainLightningAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chain lightning") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastLightningBoltAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastLightningBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "lightning bolt") {}
|
||||
};
|
||||
|
||||
class CastThunderstormAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastThunderstormAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "thunderstorm") {}
|
||||
};
|
||||
|
||||
class CastHeroismAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastHeroismAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "heroism") {}
|
||||
};
|
||||
|
||||
class CastBloodlustAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodlustAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bloodlust") {}
|
||||
};
|
||||
|
||||
class CastElementalMasteryAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastElementalMasteryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "elemental mastery") {}
|
||||
};
|
||||
|
||||
class CastWindShearOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastWindShearOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
CURE_ACTION(CastCurePoisonActionSham, "cure disease");
|
||||
CURE_PARTY_ACTION(CastCurePoisonOnPartyActionSham, "cure poison", DISPEL_POISON);
|
||||
|
||||
CURE_ACTION(CastCureDiseaseActionSham, "cure disease");
|
||||
CURE_PARTY_ACTION(CastCureDiseaseOnPartyActionSham, "cure disease", DISPEL_DISEASE);
|
||||
|
||||
class CastLavaBurstAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastLavaBurstAction(PlayerbotAI* ai) : CastSpellAction(ai, "lava burst") {}
|
||||
};
|
||||
|
||||
class CastEarthShieldOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastEarthShieldOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "earth shield", false) {}
|
||||
};
|
||||
|
||||
// Totem Spells
|
||||
|
||||
class CastTotemAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTotemAction(PlayerbotAI* botAI, std::string const spell, std::string const buffName = "")
|
||||
: CastBuffSpellAction(botAI, spell)
|
||||
{
|
||||
buff = (buffName == "") ? spell : buffName;
|
||||
}
|
||||
|
||||
bool isUseful() override;
|
||||
|
||||
protected:
|
||||
std::string buff;
|
||||
};
|
||||
|
||||
class CastCallOfTheElementsAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastCallOfTheElementsAction(PlayerbotAI* ai) : CastSpellAction(ai, "call of the elements") {}
|
||||
};
|
||||
|
||||
class CastTotemicRecallAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastTotemicRecallAction(PlayerbotAI* ai) : CastSpellAction(ai, "totemic recall") {}
|
||||
};
|
||||
|
||||
class CastStrengthOfEarthTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastStrengthOfEarthTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "strength of earth totem", "strength of earth") {}
|
||||
};
|
||||
|
||||
class CastStoneskinTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastStoneskinTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneskin totem", "stoneskin") {}
|
||||
};
|
||||
|
||||
class CastTremorTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastTremorTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "tremor totem", "") {}
|
||||
};
|
||||
|
||||
class CastEarthbindTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastEarthbindTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "earthbind totem", "") {}
|
||||
};
|
||||
|
||||
class CastStoneclawTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastStoneclawTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "stoneclaw totem", "") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastSearingTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastSearingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "searing totem", "") {}
|
||||
};
|
||||
|
||||
class CastMagmaTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastMagmaTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "magma totem", "") {}
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastFlametongueTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFlametongueTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "flametongue totem", "flametongue totem") {}
|
||||
};
|
||||
|
||||
class CastTotemOfWrathAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastTotemOfWrathAction(PlayerbotAI* ai) : CastTotemAction(ai, "totem of wrath") {}
|
||||
virtual std::string const GetTargetName() override { return "self target"; }
|
||||
virtual bool isUseful() override { return CastTotemAction::isUseful(); }
|
||||
CastTotemOfWrathAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "totem of wrath", "totem of wrath") {}
|
||||
};
|
||||
|
||||
class CastFrostResistanceTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFrostResistanceTotemAction(PlayerbotAI* botAI)
|
||||
: CastTotemAction(botAI, "frost resistance totem", "frost resistance") {}
|
||||
};
|
||||
|
||||
class CastFireElementalTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "", 0.0f) {}
|
||||
CastFireElementalTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "") {}
|
||||
virtual std::string const GetTargetName() override { return "self target"; }
|
||||
virtual bool isUseful() override { return CastTotemAction::isUseful(); }
|
||||
};
|
||||
@@ -430,7 +465,7 @@ public:
|
||||
class CastFireElementalTotemMeleeAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFireElementalTotemMeleeAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "", 0.0f) {}
|
||||
CastFireElementalTotemMeleeAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "") {}
|
||||
virtual std::string const GetTargetName() override { return "self target"; }
|
||||
virtual bool isUseful() override
|
||||
{
|
||||
@@ -441,21 +476,187 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CastHealingStreamTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastHealingStreamTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "healing stream totem", "") {}
|
||||
};
|
||||
|
||||
class CastManaSpringTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastManaSpringTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana spring totem", "mana spring") {}
|
||||
};
|
||||
|
||||
class CastCleansingTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastCleansingTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "cleansing totem", "") {}
|
||||
virtual bool isUseful();
|
||||
};
|
||||
|
||||
class CastManaTideTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastManaTideTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "mana tide totem", "") {}
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
};
|
||||
|
||||
class CastFireResistanceTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFireResistanceTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "fire resistance totem", "fire resistance") {}
|
||||
};
|
||||
|
||||
class CastWrathOfAirTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastWrathOfAirTotemAction(PlayerbotAI* ai) : CastTotemAction(ai, "wrath of air totem", "wrath of air totem") {}
|
||||
};
|
||||
|
||||
class CastShamanisticRageAction : public CastBuffSpellAction
|
||||
class CastWindfuryTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastShamanisticRageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "shamanistic rage") {}
|
||||
CastWindfuryTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "windfury totem", "windfury totem") {}
|
||||
};
|
||||
|
||||
class CastFeralSpiritAction : public CastSpellAction
|
||||
class CastNatureResistanceTotemAction : public CastTotemAction
|
||||
{
|
||||
public:
|
||||
CastFeralSpiritAction(PlayerbotAI* ai) : CastSpellAction(ai, "feral spirit") {}
|
||||
CastNatureResistanceTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "nature resistance totem", "nature resistance") {}
|
||||
};
|
||||
|
||||
// Set Strategy Assigned Totems
|
||||
|
||||
class SetTotemAction : public Action
|
||||
{
|
||||
public:
|
||||
SetTotemAction(PlayerbotAI* botAI, std::string const totemName, const uint32 totemSpellIds[], int actionButtonId)
|
||||
: Action(botAI, "set " + totemName), totemSpellIds(totemSpellIds), actionButtonId(actionButtonId)
|
||||
{
|
||||
}
|
||||
bool Execute(Event event) override;
|
||||
uint32 const* totemSpellIds;
|
||||
int actionButtonId;
|
||||
};
|
||||
|
||||
class SetStrengthOfEarthTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetStrengthOfEarthTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "strength of earth totem", STRENGTH_OF_EARTH_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetStoneskinTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetStoneskinTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "stoneskin totem", STONESKIN_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetTremorTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetTremorTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "tremor totem", TREMOR_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetEarthbindTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetEarthbindTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "earthbind totem", EARTHBIND_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetSearingTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetSearingTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "searing totem", SEARING_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetMagmaTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetMagmaTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "magma totem", MAGMA_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetFlametongueTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetFlametongueTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "flametongue totem", FLAMETONGUE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetTotemOfWrathAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetTotemOfWrathAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "totem of wrath", TOTEM_OF_WRATH, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetFrostResistanceTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetFrostResistanceTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "frost resistance totem", FROST_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetHealingStreamTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetHealingStreamTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "healing stream totem", HEALING_STREAM_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetManaSpringTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetManaSpringTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "mana spring totem", MANA_SPRING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetCleansingTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetCleansingTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "cleansing totem", CLEANSING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetFireResistanceTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetFireResistanceTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "fire resistance totem", FIRE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetWrathOfAirTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetWrathOfAirTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "wrath of air totem", WRATH_OF_AIR_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetWindfuryTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetWindfuryTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "windfury totem", WINDFURY_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetNatureResistanceTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetNatureResistanceTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "nature resistance totem", NATURE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetGroundingTotemAction : public SetTotemAction
|
||||
{
|
||||
public:
|
||||
SetGroundingTotemAction(PlayerbotAI* ai)
|
||||
: SetTotemAction(ai, "grounding totem", GROUNDING_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
#include "ShamanAiObjectContext.h"
|
||||
|
||||
#include "CasterShamanStrategy.h"
|
||||
#include "ElementalShamanStrategy.h"
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "HealShamanStrategy.h"
|
||||
#include "MeleeShamanStrategy.h"
|
||||
#include "RestoShamanStrategy.h"
|
||||
#include "EnhancementShamanStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ShamanActions.h"
|
||||
@@ -22,34 +22,18 @@ public:
|
||||
ShamanStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &ShamanStrategyFactoryInternal::nc;
|
||||
creators["totems"] = &ShamanStrategyFactoryInternal::totems;
|
||||
creators["melee aoe"] = &ShamanStrategyFactoryInternal::melee_aoe;
|
||||
creators["caster aoe"] = &ShamanStrategyFactoryInternal::caster_aoe;
|
||||
creators["aoe"] = &ShamanStrategyFactoryInternal::aoe;
|
||||
creators["cure"] = &ShamanStrategyFactoryInternal::cure;
|
||||
creators["healer dps"] = &ShamanStrategyFactoryInternal::healer_dps;
|
||||
creators["boost"] = &ShamanStrategyFactoryInternal::boost;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new ShamanNonCombatStrategy(botAI); }
|
||||
static Strategy* totems(PlayerbotAI* botAI) { return new TotemsShamanStrategy(botAI); }
|
||||
static Strategy* melee_aoe(PlayerbotAI* botAI) { return new MeleeAoeShamanStrategy(botAI); }
|
||||
static Strategy* caster_aoe(PlayerbotAI* botAI) { return new CasterAoeShamanStrategy(botAI); }
|
||||
static Strategy* aoe(PlayerbotAI* botAI) { return new ShamanAoeStrategy(botAI); }
|
||||
static Strategy* cure(PlayerbotAI* botAI) { return new ShamanCureStrategy(botAI); }
|
||||
static Strategy* healer_dps(PlayerbotAI* botAI) { return new ShamanHealerDpsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bmana"] = &ShamanBuffStrategyFactoryInternal::bmana;
|
||||
creators["bdps"] = &ShamanBuffStrategyFactoryInternal::bdps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bmana(PlayerbotAI* botAI) { return new ShamanBuffManaStrategy(botAI); }
|
||||
static Strategy* bdps(PlayerbotAI* botAI) { return new ShamanBuffDpsStrategy(botAI); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new ShamanBoostStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
@@ -57,16 +41,89 @@ class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
public:
|
||||
ShamanCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["heal"] = &ShamanCombatStrategyFactoryInternal::heal;
|
||||
creators["melee"] = &ShamanCombatStrategyFactoryInternal::dps;
|
||||
creators["dps"] = &ShamanCombatStrategyFactoryInternal::dps;
|
||||
creators["caster"] = &ShamanCombatStrategyFactoryInternal::caster;
|
||||
creators["resto"] = &ShamanCombatStrategyFactoryInternal::resto;
|
||||
creators["enh"] = &ShamanCombatStrategyFactoryInternal::enh;
|
||||
creators["ele"] = &ShamanCombatStrategyFactoryInternal::ele;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* heal(PlayerbotAI* botAI) { return new HealShamanStrategy(botAI); }
|
||||
static Strategy* dps(PlayerbotAI* botAI) { return new MeleeShamanStrategy(botAI); }
|
||||
static Strategy* caster(PlayerbotAI* botAI) { return new CasterShamanStrategy(botAI); }
|
||||
static Strategy* resto(PlayerbotAI* botAI) { return new RestoShamanStrategy(botAI); }
|
||||
static Strategy* enh(PlayerbotAI* botAI) { return new EnhancementShamanStrategy(botAI); }
|
||||
static Strategy* ele(PlayerbotAI* botAI) { return new ElementalShamanStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanEarthTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanEarthTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["strength of earth"] = &ShamanEarthTotemStrategyFactoryInternal::strength_of_earth_totem;
|
||||
creators["stoneskin"] = &ShamanEarthTotemStrategyFactoryInternal::stoneclaw_totem;
|
||||
creators["tremor"] = &ShamanEarthTotemStrategyFactoryInternal::earth_totem;
|
||||
creators["earthbind"] = &ShamanEarthTotemStrategyFactoryInternal::earthbind_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* strength_of_earth_totem(PlayerbotAI* botAI) { return new StrengthOfEarthTotemStrategy(botAI); }
|
||||
static Strategy* stoneclaw_totem(PlayerbotAI* botAI) { return new StoneclawTotemStrategy(botAI); }
|
||||
static Strategy* earth_totem(PlayerbotAI* botAI) { return new EarthTotemStrategy(botAI); }
|
||||
static Strategy* earthbind_totem(PlayerbotAI* botAI) { return new EarthbindTotemStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanFireTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanFireTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["searing"] = &ShamanFireTotemStrategyFactoryInternal::searing_totem;
|
||||
creators["magma"] = &ShamanFireTotemStrategyFactoryInternal::magma_totem;
|
||||
creators["flametongue"] = &ShamanFireTotemStrategyFactoryInternal::flametongue_totem;
|
||||
creators["wrath"] = &ShamanFireTotemStrategyFactoryInternal::totem_of_wrath;
|
||||
creators["frost resistance"] = &ShamanFireTotemStrategyFactoryInternal::frost_resistance_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* searing_totem(PlayerbotAI* botAI) { return new SearingTotemStrategy(botAI); }
|
||||
static Strategy* magma_totem(PlayerbotAI* botAI) { return new MagmaTotemStrategy(botAI); }
|
||||
static Strategy* flametongue_totem(PlayerbotAI* botAI) { return new FlametongueTotemStrategy(botAI); }
|
||||
static Strategy* totem_of_wrath(PlayerbotAI* botAI) { return new TotemOfWrathStrategy(botAI); }
|
||||
static Strategy* frost_resistance_totem(PlayerbotAI* botAI) { return new FrostResistanceTotemStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanWaterTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanWaterTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["healing stream"] = &ShamanWaterTotemStrategyFactoryInternal::healing_stream_totem;
|
||||
creators["mana spring"] = &ShamanWaterTotemStrategyFactoryInternal::mana_spring_totem;
|
||||
creators["cleansing"] = &ShamanWaterTotemStrategyFactoryInternal::cleansing_totem;
|
||||
creators["fire resistance"] = &ShamanWaterTotemStrategyFactoryInternal::fire_resistance_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* healing_stream_totem(PlayerbotAI* botAI) { return new HealingStreamTotemStrategy(botAI); }
|
||||
static Strategy* mana_spring_totem(PlayerbotAI* botAI) { return new ManaSpringTotemStrategy(botAI); }
|
||||
static Strategy* cleansing_totem(PlayerbotAI* botAI) { return new CleansingTotemStrategy(botAI); }
|
||||
static Strategy* fire_resistance_totem(PlayerbotAI* botAI) { return new FireResistanceTotemStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanAirTotemStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanAirTotemStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["wrath of air"] = &ShamanAirTotemStrategyFactoryInternal::wrath_of_air_totem;
|
||||
creators["windfury"] = &ShamanAirTotemStrategyFactoryInternal::windfury_totem;
|
||||
creators["nature resistance"] = &ShamanAirTotemStrategyFactoryInternal::nature_resistance_totem;
|
||||
creators["grounding"] = &ShamanAirTotemStrategyFactoryInternal::grounding_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* wrath_of_air_totem(PlayerbotAI* botAI) { return new WrathOfAirTotemStrategy(botAI); }
|
||||
static Strategy* windfury_totem(PlayerbotAI* botAI) { return new WindfuryTotemStrategy(botAI); }
|
||||
static Strategy* nature_resistance_totem(PlayerbotAI* botAI) { return new NatureResistanceTotemStrategy(botAI); }
|
||||
static Strategy* grounding_totem(PlayerbotAI* botAI) { return new GroundingTotemStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
@@ -74,17 +131,8 @@ class ShamanATriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
public:
|
||||
ShamanATriggerFactoryInternal()
|
||||
{
|
||||
creators["grace of air totem"] = &ShamanATriggerFactoryInternal::grace_of_air_totem;
|
||||
creators["windfury totem"] = &ShamanATriggerFactoryInternal::windfury_totem;
|
||||
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;
|
||||
creators["purge"] = &ShamanATriggerFactoryInternal::purge;
|
||||
// creators["shaman weapon"] = &ShamanATriggerFactoryInternal::shaman_weapon;
|
||||
creators["main hand weapon no imbue"] = &ShamanATriggerFactoryInternal::main_hand_weapon_no_imbue;
|
||||
creators["off hand weapon no imbue"] = &ShamanATriggerFactoryInternal::off_hand_weapon_no_imbue;
|
||||
creators["water shield"] = &ShamanATriggerFactoryInternal::water_shield;
|
||||
@@ -109,15 +157,41 @@ public:
|
||||
creators["party member cure poison"] = &ShamanATriggerFactoryInternal::party_member_cure_poison;
|
||||
creators["cure disease"] = &ShamanATriggerFactoryInternal::cure_disease;
|
||||
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 3"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_3;
|
||||
creators["maelstrom weapon 4"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_4;
|
||||
creators["maelstrom weapon 5"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_5;
|
||||
creators["flame shock"] = &ShamanATriggerFactoryInternal::flame_shock;
|
||||
creators["wrath of air totem"] = &ShamanATriggerFactoryInternal::wrath_of_air_totem;
|
||||
creators["fire elemental totem"] = &ShamanATriggerFactoryInternal::fire_elemental_totem;
|
||||
creators["earth shock execute"] = &ShamanATriggerFactoryInternal::earth_shock_execute;
|
||||
creators["spirit walk ready"] = &ShamanATriggerFactoryInternal::spirit_walk_ready;
|
||||
creators["chain lightning no cd"] = &ShamanATriggerFactoryInternal::chain_lightning_no_cd;
|
||||
creators["call of the elements and enemy within melee"] = &ShamanATriggerFactoryInternal::call_of_the_elements_and_enemy_within_melee;
|
||||
creators["maelstrom weapon 5 and medium aoe"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_5_and_medium_aoe;
|
||||
creators["maelstrom weapon 4 and medium aoe"] = &ShamanATriggerFactoryInternal::maelstrom_weapon_4_and_medium_aoe;
|
||||
creators["call of the elements"] = &ShamanATriggerFactoryInternal::call_of_the_elements;
|
||||
creators["totemic recall"] = &ShamanATriggerFactoryInternal::totemic_recall;
|
||||
creators["no earth totem"] = &ShamanATriggerFactoryInternal::no_earth_totem;
|
||||
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["set strength of earth totem"] = &ShamanATriggerFactoryInternal::set_strength_of_earth_totem;
|
||||
creators["set stoneskin totem"] = &ShamanATriggerFactoryInternal::set_stoneskin_totem;
|
||||
creators["set tremor totem"] = &ShamanATriggerFactoryInternal::set_tremor_totem;
|
||||
creators["set earthbind totem"] = &ShamanATriggerFactoryInternal::set_earthbind_totem;
|
||||
creators["set searing totem"] = &ShamanATriggerFactoryInternal::set_searing_totem;
|
||||
creators["set magma totem"] = &ShamanATriggerFactoryInternal::set_magma_totem;
|
||||
creators["set flametongue totem"] = &ShamanATriggerFactoryInternal::set_flametongue_totem;
|
||||
creators["set totem of wrath"] = &ShamanATriggerFactoryInternal::set_totem_of_wrath;
|
||||
creators["set frost resistance totem"] = &ShamanATriggerFactoryInternal::set_frost_resistance_totem;
|
||||
creators["set healing stream totem"] = &ShamanATriggerFactoryInternal::set_healing_stream_totem;
|
||||
creators["set mana spring totem"] = &ShamanATriggerFactoryInternal::set_mana_spring_totem;
|
||||
creators["set cleansing totem"] = &ShamanATriggerFactoryInternal::set_cleansing_totem;
|
||||
creators["set fire resistance totem"] = &ShamanATriggerFactoryInternal::set_fire_resistance_totem;
|
||||
creators["set wrath of air totem"] = &ShamanATriggerFactoryInternal::set_wrath_of_air_totem;
|
||||
creators["set windfury totem"] = &ShamanATriggerFactoryInternal::set_windfury_totem;
|
||||
creators["set nature resistance totem"] = &ShamanATriggerFactoryInternal::set_nature_resistance_totem;
|
||||
creators["set grounding totem"] = &ShamanATriggerFactoryInternal::set_grounding_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -127,18 +201,9 @@ private:
|
||||
static Trigger* heroism(PlayerbotAI* botAI) { return new HeroismTrigger(botAI); }
|
||||
static Trigger* bloodlust(PlayerbotAI* botAI) { return new BloodlustTrigger(botAI); }
|
||||
static Trigger* elemental_mastery(PlayerbotAI* botAI) { return new ElementalMasteryTrigger(botAI); }
|
||||
static Trigger* party_member_cleanse_disease(PlayerbotAI* botAI)
|
||||
{
|
||||
return new PartyMemberCleanseSpiritDiseaseTrigger(botAI);
|
||||
}
|
||||
static Trigger* party_member_cleanse_curse(PlayerbotAI* botAI)
|
||||
{
|
||||
return new PartyMemberCleanseSpiritCurseTrigger(botAI);
|
||||
}
|
||||
static Trigger* party_member_cleanse_poison(PlayerbotAI* botAI)
|
||||
{
|
||||
return new PartyMemberCleanseSpiritPoisonTrigger(botAI);
|
||||
}
|
||||
static Trigger* party_member_cleanse_disease(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritDiseaseTrigger(botAI); }
|
||||
static Trigger* party_member_cleanse_curse(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritCurseTrigger(botAI); }
|
||||
static Trigger* party_member_cleanse_poison(PlayerbotAI* botAI) { return new PartyMemberCleanseSpiritPoisonTrigger(botAI); }
|
||||
static Trigger* cleanse_disease(PlayerbotAI* botAI) { return new CleanseSpiritDiseaseTrigger(botAI); }
|
||||
static Trigger* cleanse_curse(PlayerbotAI* botAI) { return new CleanseSpiritCurseTrigger(botAI); }
|
||||
static Trigger* cleanse_poison(PlayerbotAI* botAI) { return new CleanseSpiritPoisonTrigger(botAI); }
|
||||
@@ -146,37 +211,51 @@ private:
|
||||
static Trigger* water_walking(PlayerbotAI* botAI) { return new WaterWalkingTrigger(botAI); }
|
||||
static Trigger* water_breathing_on_party(PlayerbotAI* botAI) { return new WaterBreathingOnPartyTrigger(botAI); }
|
||||
static Trigger* water_walking_on_party(PlayerbotAI* botAI) { return new WaterWalkingOnPartyTrigger(botAI); }
|
||||
static Trigger* windfury_totem(PlayerbotAI* botAI) { return new WindfuryTotemTrigger(botAI); }
|
||||
static Trigger* grace_of_air_totem(PlayerbotAI* botAI) { return new GraceOfAirTotemTrigger(botAI); }
|
||||
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); }
|
||||
static Trigger* purge(PlayerbotAI* botAI) { return new PurgeTrigger(botAI); }
|
||||
// static Trigger* shaman_weapon(PlayerbotAI* botAI) { return new ShamanWeaponTrigger(botAI); }
|
||||
static Trigger* main_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new MainHandWeaponNoImbueTrigger(botAI); }
|
||||
static Trigger* off_hand_weapon_no_imbue(PlayerbotAI* botAI) { return new OffHandWeaponNoImbueTrigger(botAI); }
|
||||
static Trigger* water_shield(PlayerbotAI* botAI) { return new WaterShieldTrigger(botAI); }
|
||||
static Trigger* lightning_shield(PlayerbotAI* botAI) { return new LightningShieldTrigger(botAI); }
|
||||
static Trigger* shock(PlayerbotAI* botAI) { return new ShockTrigger(botAI); }
|
||||
static Trigger* frost_shock_snare(PlayerbotAI* botAI) { return new FrostShockSnareTrigger(botAI); }
|
||||
static Trigger* wind_shear_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new WindShearInterruptEnemyHealerSpellTrigger(botAI);
|
||||
}
|
||||
static Trigger* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new WindShearInterruptEnemyHealerSpellTrigger(botAI); }
|
||||
static Trigger* cure_poison(PlayerbotAI* botAI) { return new CurePoisonTrigger(botAI); }
|
||||
static Trigger* party_member_cure_poison(PlayerbotAI* botAI) { return new PartyMemberCurePoisonTrigger(botAI); }
|
||||
static Trigger* cure_disease(PlayerbotAI* botAI) { return new CureDiseaseTrigger(botAI); }
|
||||
static Trigger* party_member_cure_disease(PlayerbotAI* botAI) { return new PartyMemberCureDiseaseTrigger(botAI); }
|
||||
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* fire_elemental_totem(PlayerbotAI* botAI) { return new FireElementalTotemTrigger(botAI); }
|
||||
static Trigger* earth_shock_execute(PlayerbotAI* botAI) { return new EarthShockExecuteTrigger(botAI); }
|
||||
static Trigger* spirit_walk_ready(PlayerbotAI* ai) { return new SpiritWalkTrigger(ai); }
|
||||
static Trigger* chain_lightning_no_cd(PlayerbotAI* ai) { return new ChainLightningNoCdTrigger(ai); }
|
||||
static Trigger* call_of_the_elements_and_enemy_within_melee(PlayerbotAI* ai) { return new CallOfTheElementsAndEnemyWithinMeleeTrigger(ai); }
|
||||
static Trigger* maelstrom_weapon_5_and_medium_aoe(PlayerbotAI* ai) { return new MaelstromWeapon5AndMediumAoeTrigger(ai); }
|
||||
static Trigger* maelstrom_weapon_4_and_medium_aoe(PlayerbotAI* ai) { return new MaelstromWeapon4AndMediumAoeTrigger(ai); }
|
||||
static Trigger* call_of_the_elements(PlayerbotAI* ai) { return new CallOfTheElementsTrigger(ai); }
|
||||
static Trigger* totemic_recall(PlayerbotAI* ai) { return new TotemicRecallTrigger(ai); }
|
||||
static Trigger* no_earth_totem(PlayerbotAI* ai) { return new NoEarthTotemTrigger(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_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); }
|
||||
static Trigger* set_strength_of_earth_totem(PlayerbotAI* ai) { return new SetStrengthOfEarthTotemTrigger(ai); }
|
||||
static Trigger* set_stoneskin_totem(PlayerbotAI* ai) { return new SetStoneskinTotemTrigger(ai); }
|
||||
static Trigger* set_tremor_totem(PlayerbotAI* ai) { return new SetTremorTotemTrigger(ai); }
|
||||
static Trigger* set_earthbind_totem(PlayerbotAI* ai) { return new SetEarthbindTotemTrigger(ai); }
|
||||
static Trigger* set_searing_totem(PlayerbotAI* ai) { return new SetSearingTotemTrigger(ai); }
|
||||
static Trigger* set_magma_totem(PlayerbotAI* ai) { return new SetMagmaTotemTrigger(ai); }
|
||||
static Trigger* set_flametongue_totem(PlayerbotAI* ai) { return new SetFlametongueTotemTrigger(ai); }
|
||||
static Trigger* set_totem_of_wrath(PlayerbotAI* ai) { return new SetTotemOfWrathTrigger(ai); }
|
||||
static Trigger* set_frost_resistance_totem(PlayerbotAI* ai) { return new SetFrostResistanceTotemTrigger(ai); }
|
||||
static Trigger* set_healing_stream_totem(PlayerbotAI* ai) { return new SetHealingStreamTotemTrigger(ai); }
|
||||
static Trigger* set_mana_spring_totem(PlayerbotAI* ai) { return new SetManaSpringTotemTrigger(ai); }
|
||||
static Trigger* set_cleansing_totem(PlayerbotAI* ai) { return new SetCleansingTotemTrigger(ai); }
|
||||
static Trigger* set_fire_resistance_totem(PlayerbotAI* ai) { return new SetFireResistanceTotemTrigger(ai); }
|
||||
static Trigger* set_wrath_of_air_totem(PlayerbotAI* ai) { return new SetWrathOfAirTotemTrigger(ai); }
|
||||
static Trigger* set_windfury_totem(PlayerbotAI* ai) { return new SetWindfuryTotemTrigger(ai); }
|
||||
static Trigger* set_nature_resistance_totem(PlayerbotAI* ai) { return new SetNatureResistanceTotemTrigger(ai); }
|
||||
static Trigger* set_grounding_totem(PlayerbotAI* ai) { return new SetGroundingTotemTrigger(ai); }
|
||||
};
|
||||
|
||||
class ShamanAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
@@ -186,16 +265,6 @@ public:
|
||||
{
|
||||
creators["water shield"] = &ShamanAiObjectContextInternal::water_shield;
|
||||
creators["lightning shield"] = &ShamanAiObjectContextInternal::lightning_shield;
|
||||
creators["strength of earth totem"] = &ShamanAiObjectContextInternal::strength_of_earth_totem;
|
||||
creators["flametongue totem"] = &ShamanAiObjectContextInternal::flametongue_totem;
|
||||
creators["searing totem"] = &ShamanAiObjectContextInternal::searing_totem;
|
||||
creators["magma totem"] = &ShamanAiObjectContextInternal::magma_totem;
|
||||
creators["windfury totem"] = &ShamanAiObjectContextInternal::windfury_totem;
|
||||
creators["grace of air totem"] = &ShamanAiObjectContextInternal::grace_of_air_totem;
|
||||
creators["mana spring totem"] = &ShamanAiObjectContextInternal::mana_spring_totem;
|
||||
creators["mana tide totem"] = &ShamanAiObjectContextInternal::mana_tide_totem;
|
||||
creators["earthbind totem"] = &ShamanAiObjectContextInternal::earthbind_totem;
|
||||
creators["healing stream totem"] = &ShamanAiObjectContextInternal::healing_stream_totem;
|
||||
creators["wind shear"] = &ShamanAiObjectContextInternal::wind_shear;
|
||||
creators["wind shear on enemy healer"] = &ShamanAiObjectContextInternal::wind_shear_on_enemy_healer;
|
||||
creators["rockbiter weapon"] = &ShamanAiObjectContextInternal::rockbiter_weapon;
|
||||
@@ -240,12 +309,48 @@ public:
|
||||
creators["cure poison on party"] = &ShamanAiObjectContextInternal::cure_poison_on_party;
|
||||
creators["lava burst"] = &ShamanAiObjectContextInternal::lava_burst;
|
||||
creators["earth shield on main tank"] = &ShamanAiObjectContextInternal::earth_shield_on_main_tank;
|
||||
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
|
||||
creators["fire elemental totem melee"] = &ShamanAiObjectContextInternal::fire_elemental_totem_melee;
|
||||
creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath;
|
||||
creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem;
|
||||
creators["shamanistic rage"] = &ShamanAiObjectContextInternal::shamanistic_rage;
|
||||
creators["feral spirit"] = &ShamanAiObjectContextInternal::feral_spirit;
|
||||
creators["spirit walk"] = &ShamanAiObjectContextInternal::spirit_walk;
|
||||
creators["call of the elements"] = &ShamanAiObjectContextInternal::call_of_the_elements;
|
||||
creators["totemic recall"] = &ShamanAiObjectContextInternal::totemic_recall;
|
||||
creators["strength of earth totem"] = &ShamanAiObjectContextInternal::strength_of_earth_totem;
|
||||
creators["stoneskin totem"] = &ShamanAiObjectContextInternal::stoneskin_totem;
|
||||
creators["tremor totem"] = &ShamanAiObjectContextInternal::tremor_totem;
|
||||
creators["earthbind totem"] = &ShamanAiObjectContextInternal::earthbind_totem;
|
||||
creators["stoneclaw totem"] = &ShamanAiObjectContextInternal::stoneclaw_totem;
|
||||
creators["searing totem"] = &ShamanAiObjectContextInternal::searing_totem;
|
||||
creators["magma totem"] = &ShamanAiObjectContextInternal::magma_totem;
|
||||
creators["flametongue totem"] = &ShamanAiObjectContextInternal::flametongue_totem;
|
||||
creators["totem of wrath"] = &ShamanAiObjectContextInternal::totem_of_wrath;
|
||||
creators["frost resistance totem"] = &ShamanAiObjectContextInternal::frost_resistance_totem;
|
||||
creators["fire elemental totem"] = &ShamanAiObjectContextInternal::fire_elemental_totem;
|
||||
creators["fire elemental totem melee"] = &ShamanAiObjectContextInternal::fire_elemental_totem_melee;
|
||||
creators["healing stream totem"] = &ShamanAiObjectContextInternal::healing_stream_totem;
|
||||
creators["mana spring totem"] = &ShamanAiObjectContextInternal::mana_spring_totem;
|
||||
creators["cleansing totem"] = &ShamanAiObjectContextInternal::cleansing_totem;
|
||||
creators["mana tide totem"] = &ShamanAiObjectContextInternal::mana_tide_totem;
|
||||
creators["fire resistance totem"] = &ShamanAiObjectContextInternal::fire_resistance_totem;
|
||||
creators["wrath of air totem"] = &ShamanAiObjectContextInternal::wrath_of_air_totem;
|
||||
creators["windfury totem"] = &ShamanAiObjectContextInternal::windfury_totem;
|
||||
creators["nature resistance totem"] = &ShamanAiObjectContextInternal::nature_resistance_totem;
|
||||
creators["set strength of earth totem"] = &ShamanAiObjectContextInternal::set_strength_of_earth_totem;
|
||||
creators["set stoneskin totem"] = &ShamanAiObjectContextInternal::set_stoneskin_totem;
|
||||
creators["set tremor totem"] = &ShamanAiObjectContextInternal::set_tremor_totem;
|
||||
creators["set earthbind totem"] = &ShamanAiObjectContextInternal::set_earthbind_totem;
|
||||
creators["set searing totem"] = &ShamanAiObjectContextInternal::set_searing_totem;
|
||||
creators["set magma totem"] = &ShamanAiObjectContextInternal::set_magma_totem;
|
||||
creators["set flametongue totem"] = &ShamanAiObjectContextInternal::set_flametongue_totem;
|
||||
creators["set totem of wrath"] = &ShamanAiObjectContextInternal::set_totem_of_wrath;
|
||||
creators["set frost resistance totem"] = &ShamanAiObjectContextInternal::set_frost_resistance_totem;
|
||||
creators["set healing stream totem"] = &ShamanAiObjectContextInternal::set_healing_stream_totem;
|
||||
creators["set mana spring totem"] = &ShamanAiObjectContextInternal::set_mana_spring_totem;
|
||||
creators["set cleansing totem"] = &ShamanAiObjectContextInternal::set_cleansing_totem;
|
||||
creators["set fire resistance totem"] = &ShamanAiObjectContextInternal::set_fire_resistance_totem;
|
||||
creators["set wrath of air totem"] = &ShamanAiObjectContextInternal::set_wrath_of_air_totem;
|
||||
creators["set windfury totem"] = &ShamanAiObjectContextInternal::set_windfury_totem;
|
||||
creators["set nature resistance totem"] = &ShamanAiObjectContextInternal::set_nature_resistance_totem;
|
||||
creators["set grounding totem"] = &ShamanAiObjectContextInternal::set_grounding_totem;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -258,18 +363,9 @@ private:
|
||||
static Action* frost_shock(PlayerbotAI* botAI) { return new CastFrostShockAction(botAI); }
|
||||
static Action* earth_shock(PlayerbotAI* botAI) { return new CastEarthShockAction(botAI); }
|
||||
static Action* flame_shock(PlayerbotAI* botAI) { return new CastFlameShockAction(botAI); }
|
||||
static Action* cleanse_spirit_poison_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastCleanseSpiritPoisonOnPartyAction(botAI);
|
||||
}
|
||||
static Action* cleanse_spirit_disease_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastCleanseSpiritDiseaseOnPartyAction(botAI);
|
||||
}
|
||||
static Action* cleanse_spirit_curse_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastCleanseSpiritCurseOnPartyAction(botAI);
|
||||
}
|
||||
static Action* cleanse_spirit_poison_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritPoisonOnPartyAction(botAI); }
|
||||
static Action* cleanse_spirit_disease_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritDiseaseOnPartyAction(botAI); }
|
||||
static Action* cleanse_spirit_curse_on_party(PlayerbotAI* botAI) { return new CastCleanseSpiritCurseOnPartyAction(botAI); }
|
||||
static Action* cleanse_spirit(PlayerbotAI* botAI) { return new CastCleanseSpiritAction(botAI); }
|
||||
static Action* water_walking(PlayerbotAI* botAI) { return new CastWaterWalkingAction(botAI); }
|
||||
static Action* water_breathing(PlayerbotAI* botAI) { return new CastWaterBreathingAction(botAI); }
|
||||
@@ -277,17 +373,7 @@ private:
|
||||
static Action* water_breathing_on_party(PlayerbotAI* botAI) { return new CastWaterBreathingOnPartyAction(botAI); }
|
||||
static Action* water_shield(PlayerbotAI* botAI) { return new CastWaterShieldAction(botAI); }
|
||||
static Action* lightning_shield(PlayerbotAI* botAI) { return new CastLightningShieldAction(botAI); }
|
||||
static Action* strength_of_earth_totem(PlayerbotAI* botAI) { return new CastStrengthOfEarthTotemAction(botAI); }
|
||||
static Action* flametongue_totem(PlayerbotAI* botAI) { return new CastFlametongueTotemAction(botAI); }
|
||||
static Action* magma_totem(PlayerbotAI* botAI) { return new CastMagmaTotemAction(botAI); }
|
||||
static Action* searing_totem(PlayerbotAI* botAI) { return new CastSearingTotemAction(botAI); }
|
||||
static Action* fire_nova(PlayerbotAI* botAI) { return new CastFireNovaAction(botAI); }
|
||||
static Action* windfury_totem(PlayerbotAI* botAI) { return new CastWindfuryTotemAction(botAI); }
|
||||
static Action* grace_of_air_totem(PlayerbotAI* botAI) { return new CastGraceOfAirTotemAction(botAI); }
|
||||
static Action* mana_spring_totem(PlayerbotAI* botAI) { return new CastManaSpringTotemAction(botAI); }
|
||||
static Action* mana_tide_totem(PlayerbotAI* botAI) { return new CastManaTideTotemAction(botAI); }
|
||||
static Action* earthbind_totem(PlayerbotAI* botAI) { return new CastEarthbindTotemAction(botAI); }
|
||||
static Action* healing_stream_totem(PlayerbotAI* botAI) { return new CastHealingStreamTotemAction(botAI); }
|
||||
static Action* wind_shear(PlayerbotAI* botAI) { return new CastWindShearAction(botAI); }
|
||||
static Action* rockbiter_weapon(PlayerbotAI* botAI) { return new CastRockbiterWeaponAction(botAI); }
|
||||
static Action* flametongue_weapon(PlayerbotAI* botAI) { return new CastFlametongueWeaponAction(botAI); }
|
||||
@@ -298,10 +384,7 @@ private:
|
||||
static Action* healing_wave(PlayerbotAI* botAI) { return new CastHealingWaveAction(botAI); }
|
||||
static Action* lesser_healing_wave(PlayerbotAI* botAI) { return new CastLesserHealingWaveAction(botAI); }
|
||||
static Action* healing_wave_on_party(PlayerbotAI* botAI) { return new CastHealingWaveOnPartyAction(botAI); }
|
||||
static Action* lesser_healing_wave_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastLesserHealingWaveOnPartyAction(botAI);
|
||||
}
|
||||
static Action* lesser_healing_wave_on_party(PlayerbotAI* botAI) { return new CastLesserHealingWaveOnPartyAction(botAI); }
|
||||
static Action* earth_shield(PlayerbotAI* botAI) { return new CastEarthShieldAction(botAI); }
|
||||
static Action* earth_shield_on_party(PlayerbotAI* botAI) { return new CastEarthShieldOnPartyAction(botAI); }
|
||||
static Action* chain_heal(PlayerbotAI* botAI) { return new CastChainHealAction(botAI); }
|
||||
@@ -310,22 +393,55 @@ private:
|
||||
static Action* stormstrike(PlayerbotAI* botAI) { return new CastStormstrikeAction(botAI); }
|
||||
static Action* lava_lash(PlayerbotAI* botAI) { return new CastLavaLashAction(botAI); }
|
||||
static Action* ancestral_spirit(PlayerbotAI* botAI) { return new CastAncestralSpiritAction(botAI); }
|
||||
static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastWindShearOnEnemyHealerAction(botAI);
|
||||
}
|
||||
static Action* wind_shear_on_enemy_healer(PlayerbotAI* botAI) { return new CastWindShearOnEnemyHealerAction(botAI); }
|
||||
static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonActionSham(botAI); }
|
||||
static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyActionSham(botAI); }
|
||||
static Action* cure_disease(PlayerbotAI* botAI) { return new CastCureDiseaseActionSham(botAI); }
|
||||
static Action* cure_disease_on_party(PlayerbotAI* botAI) { return new CastCureDiseaseOnPartyActionSham(botAI); }
|
||||
static Action* lava_burst(PlayerbotAI* ai) { return new CastLavaBurstAction(ai); }
|
||||
static Action* earth_shield_on_main_tank(PlayerbotAI* ai) { return new CastEarthShieldOnMainTankAction(ai); }
|
||||
static Action* totem_of_wrath(PlayerbotAI* ai) { return new CastTotemOfWrathAction(ai); }
|
||||
static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); }
|
||||
static Action* fire_elemental_totem_melee(PlayerbotAI* ai) { return new CastFireElementalTotemMeleeAction(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); }
|
||||
static Action* spirit_walk(PlayerbotAI* ai) { return new CastSpiritWalkAction(ai); }
|
||||
static Action* call_of_the_elements(PlayerbotAI* ai) { return new CastCallOfTheElementsAction(ai); }
|
||||
static Action* totemic_recall(PlayerbotAI* ai) { return new CastTotemicRecallAction(ai); }
|
||||
static Action* strength_of_earth_totem(PlayerbotAI* ai) { return new CastStrengthOfEarthTotemAction(ai); }
|
||||
static Action* stoneskin_totem(PlayerbotAI* ai) { return new CastStoneskinTotemAction(ai); }
|
||||
static Action* tremor_totem(PlayerbotAI* ai) { return new CastTremorTotemAction(ai); }
|
||||
static Action* earthbind_totem(PlayerbotAI* ai) { return new CastEarthbindTotemAction(ai); }
|
||||
static Action* stoneclaw_totem(PlayerbotAI* ai) { return new CastStoneclawTotemAction(ai); }
|
||||
static Action* searing_totem(PlayerbotAI* ai) { return new CastSearingTotemAction(ai); }
|
||||
static Action* magma_totem(PlayerbotAI* ai) { return new CastMagmaTotemAction(ai); }
|
||||
static Action* flametongue_totem(PlayerbotAI* ai) { return new CastFlametongueTotemAction(ai); }
|
||||
static Action* totem_of_wrath(PlayerbotAI* ai) { return new CastTotemOfWrathAction(ai); }
|
||||
static Action* frost_resistance_totem(PlayerbotAI* ai) { return new CastFrostResistanceTotemAction(ai); }
|
||||
static Action* fire_elemental_totem(PlayerbotAI* ai) { return new CastFireElementalTotemAction(ai); }
|
||||
static Action* fire_elemental_totem_melee(PlayerbotAI* ai) { return new CastFireElementalTotemMeleeAction(ai); }
|
||||
static Action* healing_stream_totem(PlayerbotAI* ai) { return new CastHealingStreamTotemAction(ai); }
|
||||
static Action* mana_spring_totem(PlayerbotAI* ai) { return new CastManaSpringTotemAction(ai); }
|
||||
static Action* cleansing_totem(PlayerbotAI* ai) { return new CastCleansingTotemAction(ai); }
|
||||
static Action* mana_tide_totem(PlayerbotAI* ai) { return new CastManaTideTotemAction(ai); }
|
||||
static Action* fire_resistance_totem(PlayerbotAI* ai) { return new CastFireResistanceTotemAction(ai); }
|
||||
static Action* wrath_of_air_totem(PlayerbotAI* ai) { return new CastWrathOfAirTotemAction(ai); }
|
||||
static Action* windfury_totem(PlayerbotAI* ai) { return new CastWindfuryTotemAction(ai); }
|
||||
static Action* nature_resistance_totem(PlayerbotAI* ai) { return new CastNatureResistanceTotemAction(ai); }
|
||||
static Action* set_strength_of_earth_totem(PlayerbotAI* ai) { return new SetStrengthOfEarthTotemAction(ai); }
|
||||
static Action* set_stoneskin_totem(PlayerbotAI* ai) { return new SetStoneskinTotemAction(ai); }
|
||||
static Action* set_tremor_totem(PlayerbotAI* ai) { return new SetTremorTotemAction(ai); }
|
||||
static Action* set_earthbind_totem(PlayerbotAI* ai) { return new SetEarthbindTotemAction(ai); }
|
||||
static Action* set_searing_totem(PlayerbotAI* ai) { return new SetSearingTotemAction(ai); }
|
||||
static Action* set_magma_totem(PlayerbotAI* ai) { return new SetMagmaTotemAction(ai); }
|
||||
static Action* set_flametongue_totem(PlayerbotAI* ai) { return new SetFlametongueTotemAction(ai); }
|
||||
static Action* set_totem_of_wrath(PlayerbotAI* ai) { return new SetTotemOfWrathAction(ai); }
|
||||
static Action* set_frost_resistance_totem(PlayerbotAI* ai) { return new SetFrostResistanceTotemAction(ai); }
|
||||
static Action* set_healing_stream_totem(PlayerbotAI* ai) { return new SetHealingStreamTotemAction(ai); }
|
||||
static Action* set_mana_spring_totem(PlayerbotAI* ai) { return new SetManaSpringTotemAction(ai); }
|
||||
static Action* set_cleansing_totem(PlayerbotAI* ai) { return new SetCleansingTotemAction(ai); }
|
||||
static Action* set_fire_resistance_totem(PlayerbotAI* ai) { return new SetFireResistanceTotemAction(ai); }
|
||||
static Action* set_wrath_of_air_totem(PlayerbotAI* ai) { return new SetWrathOfAirTotemAction(ai); }
|
||||
static Action* set_windfury_totem(PlayerbotAI* ai) { return new SetWindfuryTotemAction(ai); }
|
||||
static Action* set_nature_resistance_totem(PlayerbotAI* ai) { return new SetNatureResistanceTotemAction(ai); }
|
||||
static Action* set_grounding_totem(PlayerbotAI* ai) { return new SetGroundingTotemAction(ai); }
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> ShamanAiObjectContext::sharedStrategyContexts;
|
||||
@@ -351,7 +467,10 @@ void ShamanAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContext
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new ShamanStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanCombatStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanBuffStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanEarthTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanFireTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanWaterTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanAirTotemStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
@@ -369,4 +488,4 @@ void ShamanAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextL
|
||||
void ShamanAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,55 +4,120 @@
|
||||
*/
|
||||
|
||||
#include "ShamanNonCombatStrategy.h"
|
||||
|
||||
#include "AiFactory.h"
|
||||
#include "Strategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class ShamanNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
ShamanNonCombatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["flametongue weapon"] = &flametongue_weapon;
|
||||
creators["frostbrand weapon"] = &frostbrand_weapon;
|
||||
creators["windfury weapon"] = &windfury_weapon;
|
||||
creators["earthliving weapon"] = &earthliving_weapon;
|
||||
creators["wind shear"] = &wind_shear;
|
||||
creators["purge"] = &purge;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* flametongue_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("flametongue weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("rockbiter weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* frostbrand_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frostbrand weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* windfury_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("windfury weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* earthliving_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("earthliving weapon",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("flametongue weapon"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", nullptr, nullptr, nullptr); }
|
||||
static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", nullptr, nullptr, nullptr); }
|
||||
};
|
||||
|
||||
ShamanNonCombatStrategy::ShamanNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new ShamanNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void ShamanNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member dead",
|
||||
NextAction::array(0, new NextAction("ancestral spirit", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("water breathing", NextAction::array(0, new NextAction("water breathing", 12.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("water walking", NextAction::array(0, new NextAction("water walking", 12.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"water breathing on party", NextAction::array(0, new NextAction("water breathing on party", 11.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water walking on party",
|
||||
NextAction::array(0, new NextAction("water walking on party", 11.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member critical health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 31.0f),
|
||||
new NextAction("healing wave on party", 30.0f), NULL)));
|
||||
// Totemic Recall
|
||||
triggers.push_back(new TriggerNode("totemic recall", NextAction::array(0, new NextAction("totemic recall", 60.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member low health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 29.0f),
|
||||
new NextAction("healing wave on party", 28.0f), NULL)));
|
||||
// Healing/Resurrect Triggers
|
||||
triggers.push_back(new TriggerNode("party member dead", NextAction::array(0, new NextAction("ancestral spirit", ACTION_CRITICAL_HEAL + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member critical health", NextAction::array(0,
|
||||
new NextAction("riptide on party", 31.0f),
|
||||
new NextAction("healing wave on party", 30.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member low health",NextAction::array(0,
|
||||
new NextAction("riptide on party", 29.0f),
|
||||
new NextAction("healing wave on party", 28.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member medium health",NextAction::array(0,
|
||||
new NextAction("riptide on party", 27.0f),
|
||||
new NextAction("healing wave on party", 26.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("party member almost full health",NextAction::array(0,
|
||||
new NextAction("riptide on party", 25.0f),
|
||||
new NextAction("lesser healing wave on party", 24.0f), NULL)));
|
||||
triggers.push_back(new TriggerNode("group heal setting",NextAction::array(0, new NextAction("chain heal on party", 27.0f), NULL)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member medium health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 27.0f),
|
||||
new NextAction("healing wave on party", 26.0f), NULL)));
|
||||
// Cure Triggers
|
||||
triggers.push_back(new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure disease", NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member almost full health",
|
||||
NextAction::array(0, new NextAction("riptide on party", 25.0f),
|
||||
new NextAction("lesser healing wave on party", 24.0f), NULL)));
|
||||
// Out of Combat Buff Triggers
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("group heal setting", NextAction::array(0, new NextAction("chain heal on party", 27.0f), NULL)));
|
||||
if (tab == 0) // Elemental
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 21.0f), nullptr)));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("windfury weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("off hand weapon no imbue", NextAction::array(0, new NextAction("flametongue weapon", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("lightning shield", NextAction::array(0, new NextAction("lightning shield", 20.0f), nullptr)));
|
||||
}
|
||||
else if (tab == 2) // Restoration
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water shield", NextAction::array(0, new NextAction("water shield", 20.0f), nullptr)));
|
||||
}
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure poison",
|
||||
NextAction::array(0, new NextAction("cure poison on party", 21.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("cure disease", NextAction::array(0, new NextAction("cure disease", 31.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("party member cure disease",
|
||||
NextAction::array(0, new NextAction("cure disease on party", 30.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
|
||||
// Buff Triggers while swimming
|
||||
triggers.push_back(new TriggerNode("water breathing", NextAction::array(0, new NextAction("water breathing", 12.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water walking", NextAction::array(0, new NextAction("water walking", 12.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water breathing on party", NextAction::array(0, new NextAction("water breathing on party", 11.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("water walking on party", NextAction::array(0, new NextAction("water walking on party", 11.0f), nullptr)));
|
||||
|
||||
// Pet Triggers
|
||||
triggers.push_back(new TriggerNode("has pet", NextAction::array(0, new NextAction("toggle pet spell", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("new pet", NextAction::array(0, new NextAction("set pet stance", 65.0f), nullptr)));
|
||||
}
|
||||
|
||||
void ShamanNonCombatStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
|
||||
@@ -13,7 +13,7 @@ class PlayerbotAI;
|
||||
class ShamanNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
ShamanNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {}
|
||||
ShamanNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
|
||||
@@ -4,37 +4,15 @@
|
||||
*/
|
||||
|
||||
#include "ShamanTriggers.h"
|
||||
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "ItemTemplate.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
/*
|
||||
std::vector<std::string> ShamanWeaponTrigger::spells;
|
||||
|
||||
bool ShamanWeaponTrigger::IsActive()
|
||||
{
|
||||
if (spells.empty())
|
||||
{
|
||||
spells.push_back("frostbrand weapon");
|
||||
spells.push_back("rockbiter weapon");
|
||||
spells.push_back("flametongue weapon");
|
||||
spells.push_back("earthliving weapon");
|
||||
spells.push_back("windfury weapon");
|
||||
}
|
||||
|
||||
for (std::vector<std::string>::iterator i = spells.begin(); i != spells.end(); ++i)
|
||||
{
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
|
||||
if (!spellId)
|
||||
continue;
|
||||
|
||||
if (AI_VALUE2(Item*, "item for spell", spellId))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Creature.h"
|
||||
#include "Unit.h"
|
||||
#include <ctime>
|
||||
|
||||
bool MainHandWeaponNoImbueTrigger::IsActive()
|
||||
{
|
||||
@@ -63,18 +41,30 @@ bool ShockTrigger::IsActive()
|
||||
!botAI->HasAura("frost shock", GetTarget(), false, true);
|
||||
}
|
||||
|
||||
// Checks if the target's health is above 25%/1500 hp. Returns false if either are true.
|
||||
// This logic exists to prevent the use of Earth Shock on bosses as an Elemental Shaman.
|
||||
bool EarthShockExecuteTrigger::IsActive()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
float percent = 100.0f * target->GetHealth() / target->GetMaxHealth();
|
||||
if (percent >= 25.0f)
|
||||
return false;
|
||||
|
||||
if (target->GetHealth() >= 1500)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TotemTrigger::IsActive()
|
||||
{
|
||||
return AI_VALUE(uint8, "attacker count") >= attackerCount && !AI_VALUE2(bool, "has totem", name) &&
|
||||
!botAI->HasAura(name, bot);
|
||||
}
|
||||
|
||||
bool ManaSpringTotemTrigger::IsActive()
|
||||
{
|
||||
return AI_VALUE(uint8, "attacker count") >= attackerCount && !AI_VALUE2(bool, "has totem", "mana tide totem") &&
|
||||
!AI_VALUE2(bool, "has totem", name);
|
||||
}
|
||||
|
||||
bool WaterWalkingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); }
|
||||
|
||||
bool WaterBreathingTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target"); }
|
||||
@@ -89,21 +79,352 @@ bool WaterBreathingOnPartyTrigger::IsActive()
|
||||
return BuffOnPartyTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
// Checks if Chain Lightning is on Cooldown, and prevents activation if it is.
|
||||
// This is to ensure that Elemental Mastery is used on Lava Burst (2.0 second cast),
|
||||
// and not on Chain Lightning (1.5 second cast with talents).
|
||||
bool ElementalMasteryTrigger::IsActive()
|
||||
{
|
||||
return bot->HasSpellCooldown(421);
|
||||
}
|
||||
|
||||
// Checks if Sprit Wolves are out/if Spirit Walk buff is not on the bot/if the cooldown for Spirit Walk is ready.
|
||||
// There is custom code for the Spirit Walk cooldown (32 seconds), since no working
|
||||
// code exists in the AC/Playerbots repo for checking if a guardian's spell is on cooldown.
|
||||
bool SpiritWalkTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
constexpr uint32 SPIRIT_WOLF = 29264;
|
||||
constexpr uint32 SPIRIT_WALK = 58875;
|
||||
constexpr int COOLDOWN_SECONDS = 32;
|
||||
|
||||
time_t now = time(nullptr);
|
||||
|
||||
if ((now - lastSpiritWalkTime) < COOLDOWN_SECONDS)
|
||||
return false;
|
||||
|
||||
for (Unit* unit : bot->m_Controlled)
|
||||
{
|
||||
Creature* wolf = dynamic_cast<Creature*>(unit);
|
||||
if (wolf && wolf->GetEntry() == SPIRIT_WOLF && wolf->IsAlive())
|
||||
{
|
||||
if (!bot->HasAura(SPIRIT_WALK))
|
||||
{
|
||||
lastSpiritWalkTime = now;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if the bot knows Call of the Elements, and prevents the trigger firing if it doesn't.
|
||||
// Fires the trigger if at least 2 of the totem slots are empty or out of range.
|
||||
bool CallOfTheElementsTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
if (!bot->HasSpell(66842))
|
||||
return false;
|
||||
|
||||
int emptyCount = 0;
|
||||
static const uint8 slots[] = {SUMMON_SLOT_TOTEM_EARTH, SUMMON_SLOT_TOTEM_FIRE, SUMMON_SLOT_TOTEM_WATER,
|
||||
SUMMON_SLOT_TOTEM_AIR};
|
||||
|
||||
for (uint8 slot : slots)
|
||||
{
|
||||
ObjectGuid guid = bot->m_SummonSlot[slot];
|
||||
if (guid.IsEmpty())
|
||||
{
|
||||
++emptyCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||
if (!totem || totem->GetDistance(bot) > 30.0f)
|
||||
{
|
||||
++emptyCount;
|
||||
}
|
||||
}
|
||||
|
||||
return emptyCount >= 2;
|
||||
}
|
||||
|
||||
// Totemic Recall - Prevents the trigger firing under the following circumstances:
|
||||
// 1. The bot does not have Totemic Recall (level 30).
|
||||
// 2. The bot is in an instance and any boss encounter is in progress.
|
||||
// 3. Any group member or their pet is in combat.
|
||||
// 4. If Mana Tide Totem or Fire Elemental Totem is active and within 30 yards of the bot.
|
||||
// 5. Finally, if any totem summon slot is not empty, the trigger will fire.
|
||||
bool TotemicRecallTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
if (!bot->HasSpell(SPELL_TOTEMIC_RECALL))
|
||||
return false;
|
||||
|
||||
Map* map = bot->GetMap();
|
||||
if (map->IsDungeon())
|
||||
{
|
||||
InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
|
||||
if (instance)
|
||||
{
|
||||
for (uint32 i = 0; i < instance->GetEncounterCount(); ++i)
|
||||
{
|
||||
if (instance->GetBossState(i) == IN_PROGRESS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (group)
|
||||
{
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
if (!member)
|
||||
continue;
|
||||
if (member->IsInCombat())
|
||||
return false;
|
||||
Pet* pet = member->GetPet();
|
||||
if (pet && pet->IsInCombat())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER];
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||
uint32 currentSpell = 0;
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
|
||||
for (size_t i = 0; i < MANA_TIDE_TOTEM_COUNT; ++i)
|
||||
{
|
||||
if (currentSpell == MANA_TIDE_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE];
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||
uint32 currentSpell = 0;
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
|
||||
for (size_t i = 0; i < FIRE_ELEMENTAL_TOTEM_COUNT; ++i)
|
||||
{
|
||||
if (currentSpell == FIRE_ELEMENTAL_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !bot->m_SummonSlot[SUMMON_SLOT_TOTEM_EARTH].IsEmpty() ||
|
||||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE].IsEmpty() ||
|
||||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER].IsEmpty() ||
|
||||
!bot->m_SummonSlot[SUMMON_SLOT_TOTEM_AIR].IsEmpty();
|
||||
}
|
||||
|
||||
// Find the active totem strategy for this slot, and return the highest-rank spellId the bot knows for it
|
||||
static uint32 GetRequiredTotemSpellId(PlayerbotAI* ai, const char* strategies[], const uint32* spellList[],
|
||||
const size_t spellCounts[], size_t numStrategies)
|
||||
{
|
||||
Player* bot = ai->GetBot();
|
||||
for (size_t i = 0; i < numStrategies; ++i)
|
||||
{
|
||||
if (ai->HasStrategy(strategies[i], BOT_STATE_COMBAT))
|
||||
{
|
||||
// Find the highest-rank spell the bot knows
|
||||
for (size_t j = 0; j < spellCounts[i]; ++j)
|
||||
{
|
||||
if (bot->HasSpell(spellList[i][j]))
|
||||
return spellList[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // No relevant strategy active, or bot doesn't know any rank
|
||||
}
|
||||
|
||||
// Get the spellId of the currently summoned totem in the slot
|
||||
static uint32 GetSummonedTotemSpellId(Player* bot, uint8 slot)
|
||||
{
|
||||
ObjectGuid guid = bot->m_SummonSlot[slot];
|
||||
if (guid.IsEmpty())
|
||||
return 0;
|
||||
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||
if (!totem)
|
||||
return 0;
|
||||
return totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
}
|
||||
|
||||
bool NoEarthTotemTrigger::IsActive()
|
||||
{
|
||||
// Check if the bot has Stoneskin Totem (required level 4) and prevents the trigger firing if it doesn't
|
||||
if (!bot->HasSpell(SPELL_STONESKIN_TOTEM_RANK_1))
|
||||
return false;
|
||||
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_EARTH];
|
||||
Creature* totem = nullptr;
|
||||
uint32 currentSpell = 0;
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
totem = bot->GetMap()->GetCreature(guid);
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
}
|
||||
|
||||
// Define supported earth totem strategies for this slot:
|
||||
static const char* names[] = {"strength of earth", "stoneskin", "tremor", "earthbind"};
|
||||
static const uint32* spells[] = {STRENGTH_OF_EARTH_TOTEM, STONESKIN_TOTEM, TREMOR_TOTEM, EARTHBIND_TOTEM};
|
||||
static const size_t counts[] = {STRENGTH_OF_EARTH_TOTEM_COUNT, STONESKIN_TOTEM_COUNT, TREMOR_TOTEM_COUNT,
|
||||
EARTHBIND_TOTEM_COUNT};
|
||||
|
||||
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 4);
|
||||
|
||||
// EXCEPTION: If Stoneclaw Totem is out and in range, consider the slot "occupied" (do not fire the trigger)
|
||||
for (size_t i = 0; i < STONECLAW_TOTEM_COUNT; ++i)
|
||||
if (currentSpell == STONECLAW_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
|
||||
return false;
|
||||
|
||||
// If no relevant strategy, only care if the slot is empty or totem is too far away
|
||||
if (!requiredSpell)
|
||||
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
|
||||
// Fire if slot is empty or wrong totem or totem is too far away
|
||||
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
}
|
||||
|
||||
bool NoFireTotemTrigger::IsActive()
|
||||
{
|
||||
return !AI_VALUE2(bool, "has totem", "magma totem") && !AI_VALUE2(bool, "has totem", "flametongue totem") &&
|
||||
!AI_VALUE2(bool, "has totem", "searing totem") && !AI_VALUE2(bool, "has totem", "fire elemental totem") &&
|
||||
!AI_VALUE2(bool, "has totem", "frost resistance totem") && !AI_VALUE2(bool, "has totem", "totem of wrath");
|
||||
// Check if the bot has Searing Totem (required level 10) and prevents the trigger firing if it doesn't
|
||||
if (!bot->HasSpell(SPELL_SEARING_TOTEM_RANK_1))
|
||||
return false;
|
||||
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_FIRE];
|
||||
Creature* totem = nullptr;
|
||||
uint32 currentSpell = 0;
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
totem = bot->GetMap()->GetCreature(guid);
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
}
|
||||
|
||||
// Define supported fire totem strategies for this slot:
|
||||
static const char* names[] = {"searing", "magma", "flametongue", "wrath", "frost resistance"};
|
||||
static const uint32* spells[] = {SEARING_TOTEM, MAGMA_TOTEM, FLAMETONGUE_TOTEM, TOTEM_OF_WRATH,
|
||||
FROST_RESISTANCE_TOTEM};
|
||||
static const size_t counts[] = {SEARING_TOTEM_COUNT, MAGMA_TOTEM_COUNT, FLAMETONGUE_TOTEM_COUNT, TOTEM_OF_WRATH_COUNT,
|
||||
FROST_RESISTANCE_TOTEM_COUNT};
|
||||
|
||||
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 5);
|
||||
|
||||
// EXCEPTION: If Fire Elemental is out and in range, consider the slot "occupied" (do not fire the trigger)
|
||||
for (size_t i = 0; i < FIRE_ELEMENTAL_TOTEM_COUNT; ++i)
|
||||
if (currentSpell == FIRE_ELEMENTAL_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
|
||||
return false;
|
||||
|
||||
// If no relevant strategy, only care if the slot is empty or totem is too far away
|
||||
if (!requiredSpell)
|
||||
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
|
||||
// Fire if slot is empty or wrong totem or totem is too far away
|
||||
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
}
|
||||
|
||||
bool NoWaterTotemTrigger::IsActive()
|
||||
{
|
||||
return !AI_VALUE2(bool, "has totem", "fire resistance totem") && !AI_VALUE2(bool, "has totem", "mana tide totem") &&
|
||||
!AI_VALUE2(bool, "has totem", "cleansing totem") && !AI_VALUE2(bool, "has totem", "mana spring totem") &&
|
||||
!AI_VALUE2(bool, "has totem", "healing stream totem");
|
||||
// Check if the bot has Healing Stream Totem (required level 20) and prevents the trigger firing if it doesn't
|
||||
if (!bot->HasSpell(SPELL_HEALING_STREAM_TOTEM_RANK_1))
|
||||
return false;
|
||||
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_WATER];
|
||||
Creature* totem = nullptr;
|
||||
uint32 currentSpell = 0;
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
totem = bot->GetMap()->GetCreature(guid);
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
}
|
||||
|
||||
// Define supported water totem strategies for this slot:
|
||||
static const char* names[] = {"healing stream", "mana spring", "cleansing", "fire resistance"};
|
||||
static const uint32* spells[] = {HEALING_STREAM_TOTEM, MANA_SPRING_TOTEM, CLEANSING_TOTEM, FIRE_RESISTANCE_TOTEM};
|
||||
static const size_t counts[] = {HEALING_STREAM_TOTEM_COUNT, MANA_SPRING_TOTEM_COUNT, CLEANSING_TOTEM_COUNT,
|
||||
FIRE_RESISTANCE_TOTEM_COUNT};
|
||||
|
||||
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 4);
|
||||
|
||||
// EXCEPTION: If Mana Tide is out and in range, consider the slot "occupied" (do not fire the trigger)
|
||||
for (size_t i = 0; i < MANA_TIDE_TOTEM_COUNT; ++i)
|
||||
if (currentSpell == MANA_TIDE_TOTEM[i] && totem && totem->GetDistance(bot) <= 30.0f)
|
||||
return false;
|
||||
|
||||
// If no relevant strategy, only care if the slot is empty or totem is too far away
|
||||
if (!requiredSpell)
|
||||
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
|
||||
// Fire if slot is empty or wrong totem or totem is too far away
|
||||
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
}
|
||||
|
||||
bool NoAirTotemTrigger::IsActive()
|
||||
{
|
||||
return !AI_VALUE2(bool, "has totem", "wrath of air totem") && !AI_VALUE2(bool, "has totem", "windfury totem");
|
||||
// Check if the bot has Nature Resistance Totem (required level 30) and prevents the trigger firing if it doesn't
|
||||
if (!bot->HasSpell(SPELL_NATURE_RESISTANCE_TOTEM_RANK_1))
|
||||
return false;
|
||||
|
||||
ObjectGuid guid = bot->m_SummonSlot[SUMMON_SLOT_TOTEM_AIR];
|
||||
Creature* totem = nullptr;
|
||||
uint32 currentSpell = 0;
|
||||
if (!guid.IsEmpty())
|
||||
{
|
||||
totem = bot->GetMap()->GetCreature(guid);
|
||||
if (totem)
|
||||
currentSpell = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
|
||||
}
|
||||
|
||||
// Define supported air totem strategies for this slot:
|
||||
static const char* names[] = {"wrath of air", "windfury", "nature resistance", "grounding totem"};
|
||||
static const uint32* spells[] = {WRATH_OF_AIR_TOTEM, WINDFURY_TOTEM, NATURE_RESISTANCE_TOTEM, GROUNDING_TOTEM};
|
||||
static const size_t counts[] = {WRATH_OF_AIR_TOTEM_COUNT, WINDFURY_TOTEM_COUNT, NATURE_RESISTANCE_TOTEM_COUNT,
|
||||
GROUNDING_TOTEM_COUNT};
|
||||
|
||||
uint32 requiredSpell = GetRequiredTotemSpellId(botAI, names, spells, counts, 3);
|
||||
|
||||
// If no relevant strategy, only care if the slot is empty or totem is too far away
|
||||
if (!requiredSpell)
|
||||
return guid.IsEmpty() || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
|
||||
// Fire if slot is empty or wrong totem or totem is too far away
|
||||
return !currentSpell || currentSpell != requiredSpell || !totem || totem->GetDistance(bot) > 30.0f;
|
||||
}
|
||||
|
||||
bool SetTotemTrigger::IsActive()
|
||||
{
|
||||
if (!bot->HasSpell(66842))
|
||||
return false;
|
||||
if (!bot->HasSpell(requiredSpellId))
|
||||
return false;
|
||||
|
||||
ActionButton const* button = bot->GetActionButton(actionButtonId);
|
||||
if (!button || button->GetType() != ACTION_BUTTON_SPELL || button->GetAction() == 0)
|
||||
return true;
|
||||
|
||||
size_t totemSpellIdsCount = sizeof(totemSpellIds) / sizeof(uint32);
|
||||
for (size_t i = 0; i < totemSpellIdsCount; ++i)
|
||||
{
|
||||
if (button->GetAction() == totemSpellIds[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,21 +9,35 @@
|
||||
#include "CureTriggers.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Trigger.h"
|
||||
#include <set>
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include <ctime>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
/*
|
||||
class ShamanWeaponTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
ShamanWeaponTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rockbiter weapon", 2 * 2000) { }
|
||||
// Buff and Out of Combat Triggers
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
static std::vector<std::string> spells;
|
||||
};
|
||||
*/
|
||||
const uint32 SPELL_EARTHBIND_TOTEM_RANK_1 = 2484;
|
||||
const uint32 SPELL_SEARING_TOTEM_RANK_1 = 3599;
|
||||
const uint32 SPELL_WRATH_OF_AIR_TOTEM_RANK_1 = 3738;
|
||||
const uint32 SPELL_HEALING_STREAM_TOTEM_RANK_1 = 5394;
|
||||
const uint32 SPELL_MANA_SPRING_TOTEM_RANK_1 = 5675;
|
||||
const uint32 SPELL_STONESKIN_TOTEM_RANK_1 = 8071;
|
||||
const uint32 SPELL_STRENGTH_OF_EARTH_TOTEM_RANK_1 = 8075;
|
||||
const uint32 SPELL_TREMOR_TOTEM_RANK_1 = 8143;
|
||||
const uint32 SPELL_CLEANSING_TOTEM_RANK_1 = 8170;
|
||||
const uint32 SPELL_GROUNDING_TOTEM_RANK_1 = 8177;
|
||||
const uint32 SPELL_FROST_RESISTANCE_TOTEM_RANK_1 = 8181;
|
||||
const uint32 SPELL_FIRE_RESISTANCE_TOTEM_RANK_1 = 8184;
|
||||
const uint32 SPELL_MAGMA_TOTEM_RANK_1 = 8190;
|
||||
const uint32 SPELL_FLAMETONGUE_TOTEM_RANK_1 = 8227;
|
||||
const uint32 SPELL_WINDFURY_TOTEM_RANK_1 = 8512;
|
||||
const uint32 SPELL_NATURE_RESISTANCE_TOTEM_RANK_1 = 10595;
|
||||
const uint32 SPELL_TOTEM_OF_WRATH_RANK_1 = 30706;
|
||||
const uint32 SPELL_TOTEMIC_RECALL = 36936;
|
||||
|
||||
class MainHandWeaponNoImbueTrigger : public BuffTrigger
|
||||
{
|
||||
@@ -39,76 +53,6 @@ public:
|
||||
virtual bool IsActive();
|
||||
};
|
||||
|
||||
class TotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
TotemTrigger(PlayerbotAI* botAI, std::string const spell, uint32 attackerCount = 0)
|
||||
: Trigger(botAI, spell), attackerCount(attackerCount)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
uint32 attackerCount;
|
||||
};
|
||||
|
||||
class WindfuryTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
WindfuryTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "windfury totem") {}
|
||||
};
|
||||
|
||||
class GraceOfAirTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
GraceOfAirTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "grace of air totem") {}
|
||||
};
|
||||
|
||||
class ManaSpringTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
ManaSpringTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "mana spring totem") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FlametongueTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
FlametongueTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "flametongue totem") {}
|
||||
};
|
||||
|
||||
class StrengthOfEarthTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
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:
|
||||
MagmaTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "magma totem", 3) {}
|
||||
};
|
||||
|
||||
class SearingTotemTrigger : public TotemTrigger
|
||||
{
|
||||
public:
|
||||
SearingTotemTrigger(PlayerbotAI* botAI) : TotemTrigger(botAI, "searing totem", 1) {}
|
||||
};
|
||||
|
||||
class WindShearInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
WindShearInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class WaterShieldTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
@@ -121,12 +65,6 @@ public:
|
||||
LightningShieldTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "lightning shield") {}
|
||||
};
|
||||
|
||||
class PurgeTrigger : public TargetAuraDispelTrigger
|
||||
{
|
||||
public:
|
||||
PurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "purge", DISPEL_MAGIC) {}
|
||||
};
|
||||
|
||||
class WaterWalkingTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
@@ -154,13 +92,70 @@ public:
|
||||
class WaterBreathingOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2 * 2000)
|
||||
{
|
||||
}
|
||||
WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
// Boost Triggers
|
||||
|
||||
class HeroismTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
HeroismTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "heroism") {}
|
||||
};
|
||||
|
||||
class BloodlustTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
BloodlustTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "bloodlust") {}
|
||||
};
|
||||
|
||||
class ElementalMasteryTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
ElementalMasteryTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "elemental mastery") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class SpiritWalkTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
SpiritWalkTrigger(PlayerbotAI* ai) : Trigger(ai, "spirit walk ready") {}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
time_t lastSpiritWalkTime = 0;
|
||||
};
|
||||
|
||||
class FireElementalTotemTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
FireElementalTotemTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "fire elemental totem") {}
|
||||
};
|
||||
|
||||
// CC, Interrupt, and Dispel Triggers
|
||||
|
||||
class WindShearInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
WindShearInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class WindShearInterruptEnemyHealerSpellTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
WindShearInterruptEnemyHealerSpellTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "wind shear") {}
|
||||
};
|
||||
|
||||
class PurgeTrigger : public TargetAuraDispelTrigger
|
||||
{
|
||||
public:
|
||||
PurgeTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "purge", DISPEL_MAGIC) {}
|
||||
};
|
||||
|
||||
class CleanseSpiritPoisonTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
@@ -206,6 +201,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CurePoisonTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CurePoisonTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {}
|
||||
};
|
||||
|
||||
class PartyMemberCurePoisonTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCurePoisonTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {}
|
||||
};
|
||||
|
||||
class CureDiseaseTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CureDiseaseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {}
|
||||
};
|
||||
|
||||
class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCureDiseaseTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {}
|
||||
};
|
||||
|
||||
// Damage and Debuff Triggers
|
||||
|
||||
class ShockTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
@@ -220,63 +242,88 @@ public:
|
||||
FrostShockSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "frost shock") {}
|
||||
};
|
||||
|
||||
class HeroismTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
HeroismTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "heroism") {}
|
||||
};
|
||||
|
||||
class BloodlustTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
BloodlustTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "bloodlust") {}
|
||||
};
|
||||
|
||||
class ElementalMasteryTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
ElementalMasteryTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "elemental mastery") {}
|
||||
};
|
||||
|
||||
class MaelstromWeaponTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
MaelstromWeaponTrigger(PlayerbotAI* botAI, int stack = 5) : HasAuraStackTrigger(botAI, "maelstrom weapon", stack) {}
|
||||
};
|
||||
|
||||
class WindShearInterruptEnemyHealerSpellTrigger : public InterruptEnemyHealerTrigger
|
||||
class FlameShockTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
WindShearInterruptEnemyHealerSpellTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "wind shear") {}
|
||||
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class CurePoisonTrigger : public NeedCureTrigger
|
||||
class EarthShockExecuteTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
CurePoisonTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure poison", DISPEL_POISON) {}
|
||||
EarthShockExecuteTrigger(PlayerbotAI* botAI) : Trigger(botAI, "earth shock execute") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class PartyMemberCurePoisonTrigger : public PartyMemberNeedCureTrigger
|
||||
class MaelstromWeapon5AndMediumAoeTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
PartyMemberCurePoisonTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "cure poison", DISPEL_POISON)
|
||||
MaelstromWeapon5AndMediumAoeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "maelstrom weapon 5", "medium aoe") {}
|
||||
};
|
||||
|
||||
class MaelstromWeapon4AndMediumAoeTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
MaelstromWeapon4AndMediumAoeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "maelstrom weapon 4", "medium aoe") {}
|
||||
};
|
||||
|
||||
class ChainLightningNoCdTrigger : public SpellNoCooldownTrigger
|
||||
{
|
||||
public:
|
||||
ChainLightningNoCdTrigger(PlayerbotAI* ai) : SpellNoCooldownTrigger(ai, "chain lightning") {}
|
||||
};
|
||||
|
||||
// Healing Triggers
|
||||
|
||||
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
{
|
||||
public:
|
||||
EarthShieldOnMainTankTrigger(PlayerbotAI* botAI) : BuffOnMainTankTrigger(botAI, "earth shield", false) {}
|
||||
};
|
||||
|
||||
// Totem Triggers
|
||||
|
||||
class TotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
TotemTrigger(PlayerbotAI* botAI, std::string const spell, uint32 attackerCount = 0)
|
||||
: Trigger(botAI, spell), attackerCount(attackerCount)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
uint32 attackerCount;
|
||||
};
|
||||
|
||||
class CureDiseaseTrigger : public NeedCureTrigger
|
||||
class CallOfTheElementsTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
CureDiseaseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE) {}
|
||||
CallOfTheElementsTrigger(PlayerbotAI* ai) : Trigger(ai, "call of the elements") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class PartyMemberCureDiseaseTrigger : public PartyMemberNeedCureTrigger
|
||||
class TotemicRecallTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCureDiseaseTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cure disease", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
TotemicRecallTrigger(PlayerbotAI* ai) : Trigger(ai, "totemic recall") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoEarthTotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoEarthTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no earth totem") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoFireTotemTrigger : public Trigger
|
||||
@@ -293,28 +340,155 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class EarthShieldOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
class NoAirTotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
EarthShieldOnMainTankTrigger(PlayerbotAI* botAI) : BuffOnMainTankTrigger(botAI, "earth shield", false) {}
|
||||
};
|
||||
|
||||
class FlameShockTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
|
||||
};
|
||||
|
||||
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") {}
|
||||
NoAirTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no air totem") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class CallOfTheElementsAndEnemyWithinMeleeTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
CallOfTheElementsAndEnemyWithinMeleeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "call of the elements", "enemy within melee") {}
|
||||
};
|
||||
|
||||
// Set Strategy Assigned Totems
|
||||
|
||||
class SetTotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
SetTotemTrigger(PlayerbotAI* ai, std::string const spellName, const uint32 requiredSpellId,
|
||||
const uint32 totemSpellIds[], int actionButtonId)
|
||||
: Trigger(ai, "set " + spellName),
|
||||
requiredSpellId(requiredSpellId),
|
||||
totemSpellIds(totemSpellIds),
|
||||
actionButtonId(actionButtonId) {}
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
uint32 requiredSpellId;
|
||||
uint32 const* totemSpellIds;
|
||||
int actionButtonId;
|
||||
};
|
||||
|
||||
class SetStrengthOfEarthTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetStrengthOfEarthTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "strength of earth totem", SPELL_STRENGTH_OF_EARTH_TOTEM_RANK_1, STRENGTH_OF_EARTH_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetStoneskinTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetStoneskinTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "stoneskin totem", SPELL_STONESKIN_TOTEM_RANK_1, STONESKIN_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetTremorTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetTremorTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "tremor totem", SPELL_TREMOR_TOTEM_RANK_1, TREMOR_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetEarthbindTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetEarthbindTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "earthbind totem", SPELL_EARTHBIND_TOTEM_RANK_1, EARTHBIND_TOTEM, TOTEM_BAR_SLOT_EARTH) {}
|
||||
};
|
||||
|
||||
class SetSearingTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetSearingTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "searing totem", SPELL_SEARING_TOTEM_RANK_1, SEARING_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetMagmaTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetMagmaTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "magma totem", SPELL_MAGMA_TOTEM_RANK_1, MAGMA_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetFlametongueTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetFlametongueTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "flametongue totem", SPELL_FLAMETONGUE_TOTEM_RANK_1, FLAMETONGUE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetTotemOfWrathTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetTotemOfWrathTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "totem of wrath", SPELL_TOTEM_OF_WRATH_RANK_1, TOTEM_OF_WRATH, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetFrostResistanceTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetFrostResistanceTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "frost resistance totem", SPELL_FROST_RESISTANCE_TOTEM_RANK_1, FROST_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_FIRE) {}
|
||||
};
|
||||
|
||||
class SetHealingStreamTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetHealingStreamTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "healing stream totem", SPELL_HEALING_STREAM_TOTEM_RANK_1, HEALING_STREAM_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetManaSpringTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetManaSpringTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "mana spring totem", SPELL_MANA_SPRING_TOTEM_RANK_1, MANA_SPRING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetCleansingTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetCleansingTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "cleansing totem", SPELL_CLEANSING_TOTEM_RANK_1, CLEANSING_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetFireResistanceTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetFireResistanceTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "fire resistance totem", SPELL_FIRE_RESISTANCE_TOTEM_RANK_1, FIRE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_WATER) {}
|
||||
};
|
||||
|
||||
class SetWrathOfAirTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetWrathOfAirTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "wrath of air totem", SPELL_WRATH_OF_AIR_TOTEM_RANK_1, WRATH_OF_AIR_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetWindfuryTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetWindfuryTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "windfury totem", SPELL_WINDFURY_TOTEM_RANK_1, WINDFURY_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetNatureResistanceTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetNatureResistanceTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "nature resistance totem", SPELL_NATURE_RESISTANCE_TOTEM_RANK_1, NATURE_RESISTANCE_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
class SetGroundingTotemTrigger : public SetTotemTrigger
|
||||
{
|
||||
public:
|
||||
SetGroundingTotemTrigger(PlayerbotAI* ai)
|
||||
: SetTotemTrigger(ai, "grounding totem", SPELL_GROUNDING_TOTEM_RANK_1, GROUNDING_TOTEM, TOTEM_BAR_SLOT_AIR) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,22 +4,185 @@
|
||||
*/
|
||||
|
||||
#include "TotemsShamanStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
TotemsShamanStrategy::TotemsShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
// These combat strategies are used to set the corresponding totems on the bar, and cast the totem when it's missing.
|
||||
// There are special cases for Totem of Wrath, Windfury Totem, Wrath of Air totem, and Cleansing totem - these totems
|
||||
// aren't learned at level 30, and have fallbacks in order to prevent the trigger from continuously firing.
|
||||
|
||||
void TotemsShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// Earth Totems
|
||||
StrengthOfEarthTotemStrategy::StrengthOfEarthTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void StrengthOfEarthTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("no air totem", NextAction::array(0, new NextAction("wrath of air totem", 8.0f), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("no water totem", NextAction::array(0, new NextAction("mana spring totem", 7.0f),
|
||||
new NextAction("healing stream totem", 6.0f), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("strength of earth totem",
|
||||
NextAction::array(0, new NextAction("strength of earth totem", 6.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("set strength of earth totem", NextAction::array(0, new NextAction("set strength of earth totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("strength of earth totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
StoneclawTotemStrategy::StoneclawTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void StoneclawTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set stoneskin totem", NextAction::array(0, new NextAction("set stoneskin totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("stoneskin totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
EarthTotemStrategy::EarthTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void EarthTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set tremor totem", NextAction::array(0, new NextAction("set tremor totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("tremor totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
EarthbindTotemStrategy::EarthbindTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void EarthbindTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set earthbind totem", NextAction::array(0, new NextAction("set earthbind totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no earth totem", NextAction::array(0, new NextAction("earthbind totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
// Fire Totems
|
||||
SearingTotemStrategy::SearingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void SearingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set searing totem", NextAction::array(0, new NextAction("set searing totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("searing totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
MagmaTotemStrategy::MagmaTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void MagmaTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set magma totem", NextAction::array(0, new NextAction("set magma totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("magma totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
FlametongueTotemStrategy::FlametongueTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void FlametongueTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set flametongue totem", NextAction::array(0, new NextAction("set flametongue totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("flametongue totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
TotemOfWrathStrategy::TotemOfWrathStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void TotemOfWrathStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
// If the bot hasn't learned Totem of Wrath yet, set Flametongue Totem instead.
|
||||
Player* bot = botAI->GetBot();
|
||||
if (bot->HasSpell(30706))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set totem of wrath", NextAction::array(0, new NextAction("set totem of wrath", 60.0f), nullptr)));
|
||||
}
|
||||
else if (bot->HasSpell(8227))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set flametongue totem", NextAction::array(0, new NextAction("set flametongue totem", 60.0f), nullptr)));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("totem of wrath", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
FrostResistanceTotemStrategy::FrostResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void FrostResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set frost resistance totem", NextAction::array(0, new NextAction("set frost resistance totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no fire totem", NextAction::array(0, new NextAction("frost resistance totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
// Water Totems
|
||||
HealingStreamTotemStrategy::HealingStreamTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void HealingStreamTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set healing stream totem", NextAction::array(0, new NextAction("set healing stream totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("healing stream totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
ManaSpringTotemStrategy::ManaSpringTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void ManaSpringTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set mana spring totem", NextAction::array(0, new NextAction("set mana spring totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("mana spring totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
CleansingTotemStrategy::CleansingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void CleansingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
// If the bot hasn't learned Cleansing Totem yet, set Mana Spring Totem instead.
|
||||
Player* bot = botAI->GetBot();
|
||||
if (bot->HasSpell(8170))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set cleansing totem", NextAction::array(0, new NextAction("set cleansing totem", 60.0f), nullptr)));
|
||||
}
|
||||
else if (bot->HasSpell(5675))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set mana spring totem", NextAction::array(0, new NextAction("set mana spring totem", 60.0f), nullptr)));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("cleansing totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
FireResistanceTotemStrategy::FireResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void FireResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set fire resistance totem", NextAction::array(0, new NextAction("set fire resistance totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no water totem", NextAction::array(0, new NextAction("fire resistance totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
// Air Totems
|
||||
WrathOfAirTotemStrategy::WrathOfAirTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void WrathOfAirTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
// If the bot hasn't learned Wrath of Air Totem yet, set Grounding Totem instead.
|
||||
Player* bot = botAI->GetBot();
|
||||
if (bot->HasSpell(3738))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set wrath of air totem", NextAction::array(0, new NextAction("set wrath of air totem", 60.0f), nullptr)));
|
||||
}
|
||||
else if (bot->HasSpell(8177))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
|
||||
}
|
||||
triggers.push_back(
|
||||
new TriggerNode("no air totem", NextAction::array(0, new NextAction("wrath of air totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
WindfuryTotemStrategy::WindfuryTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void WindfuryTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
// If the bot hasn't learned Windfury Totem yet, set Grounding Totem instead.
|
||||
Player* bot = botAI->GetBot();
|
||||
if (bot->HasSpell(8512))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set windfury totem", NextAction::array(0, new NextAction("set windfury totem", 60.0f), nullptr)));
|
||||
}
|
||||
else if (bot->HasSpell(8177))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("windfury totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
NatureResistanceTotemStrategy::NatureResistanceTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void NatureResistanceTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set nature resistance totem", NextAction::array(0, new NextAction("set nature resistance totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("nature resistance totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
GroundingTotemStrategy::GroundingTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void GroundingTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set grounding totem", NextAction::array(0, new NextAction("set grounding totem", 60.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("no air totem", NextAction::array(0, new NextAction("grounding totem", 55.0f), nullptr)));
|
||||
}
|
||||
|
||||
@@ -7,16 +7,358 @@
|
||||
#define _PLAYERBOT_TOTEMSSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// This is the header with all of the totem-related constants and arrays used in the Shaman strategies.
|
||||
|
||||
// Totem Bar Slot Constants
|
||||
#define TOTEM_BAR_SLOT_FIRE 132
|
||||
#define TOTEM_BAR_SLOT_EARTH 133
|
||||
#define TOTEM_BAR_SLOT_WATER 134
|
||||
#define TOTEM_BAR_SLOT_AIR 135
|
||||
|
||||
// Strength of Earth Totem
|
||||
static const uint32 STRENGTH_OF_EARTH_TOTEM[] = {
|
||||
58643, // Rank 8
|
||||
57622, // Rank 7
|
||||
25528, // Rank 6
|
||||
25361, // Rank 5
|
||||
10442, // Rank 4
|
||||
8161, // Rank 3
|
||||
8160, // Rank 2
|
||||
8075 // Rank 1
|
||||
};
|
||||
static const size_t STRENGTH_OF_EARTH_TOTEM_COUNT = sizeof(STRENGTH_OF_EARTH_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Stoneskin Totem
|
||||
static const uint32 STONESKIN_TOTEM[] = {
|
||||
58753, // Rank 10
|
||||
58751, // Rank 9
|
||||
25509, // Rank 8
|
||||
25508, // Rank 7
|
||||
10408, // Rank 6
|
||||
10407, // Rank 5
|
||||
10406, // Rank 4
|
||||
8155, // Rank 3
|
||||
8154, // Rank 2
|
||||
8071 // Rank 1
|
||||
};
|
||||
static const size_t STONESKIN_TOTEM_COUNT = sizeof(STONESKIN_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Tremor Totem
|
||||
static const uint32 TREMOR_TOTEM[] = {
|
||||
8143 // Rank 1
|
||||
};
|
||||
static const size_t TREMOR_TOTEM_COUNT = sizeof(TREMOR_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Earthbind Totem
|
||||
static const uint32 EARTHBIND_TOTEM[] = {
|
||||
2484 // Rank 1
|
||||
};
|
||||
static const size_t EARTHBIND_TOTEM_COUNT = sizeof(EARTHBIND_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Stoneclaw Totem
|
||||
static const uint32 STONECLAW_TOTEM[] = {
|
||||
58582, // Rank 10
|
||||
58581, // Rank 9
|
||||
58580, // Rank 8
|
||||
25525, // Rank 7
|
||||
10428, // Rank 6
|
||||
10427, // Rank 5
|
||||
6392, // Rank 4
|
||||
6391, // Rank 3
|
||||
6390, // Rank 2
|
||||
5730 // Rank 1
|
||||
};
|
||||
static const size_t STONECLAW_TOTEM_COUNT = sizeof(STONECLAW_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Searing Totem
|
||||
static const uint32 SEARING_TOTEM[] = {
|
||||
58704, // Rank 10
|
||||
58703, // Rank 9
|
||||
58699, // Rank 8
|
||||
25533, // Rank 7
|
||||
10438, // Rank 6
|
||||
10437, // Rank 5
|
||||
6365, // Rank 4
|
||||
6364, // Rank 3
|
||||
6363, // Rank 2
|
||||
3599 // Rank 1
|
||||
};
|
||||
static const size_t SEARING_TOTEM_COUNT = sizeof(SEARING_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Magma Totem
|
||||
static const uint32 MAGMA_TOTEM[] = {
|
||||
58734, // Rank 7
|
||||
58731, // Rank 6
|
||||
25552, // Rank 5
|
||||
10587, // Rank 4
|
||||
10586, // Rank 3
|
||||
10585, // Rank 2
|
||||
8190 // Rank 1
|
||||
};
|
||||
static const size_t MAGMA_TOTEM_COUNT = sizeof(MAGMA_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Flametongue Totem
|
||||
static const uint32 FLAMETONGUE_TOTEM[] = {
|
||||
58656, // Rank 8
|
||||
58652, // Rank 7
|
||||
58649, // Rank 6
|
||||
25557, // Rank 5
|
||||
16387, // Rank 4
|
||||
10526, // Rank 3
|
||||
8249, // Rank 2
|
||||
8227 // Rank 1
|
||||
};
|
||||
static const size_t FLAMETONGUE_TOTEM_COUNT = sizeof(FLAMETONGUE_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Totem of Wrath
|
||||
static const uint32 TOTEM_OF_WRATH[] = {
|
||||
57722, // Rank 4
|
||||
57721, // Rank 3
|
||||
57720, // Rank 2
|
||||
30706 // Rank 1
|
||||
};
|
||||
static const size_t TOTEM_OF_WRATH_COUNT = sizeof(TOTEM_OF_WRATH) / sizeof(uint32);
|
||||
|
||||
// Frost Resistance Totem
|
||||
static const uint32 FROST_RESISTANCE_TOTEM[] = {
|
||||
58745, // Rank 6
|
||||
58741, // Rank 5
|
||||
25560, // Rank 4
|
||||
10479, // Rank 3
|
||||
10478, // Rank 2
|
||||
8181 // Rank 1
|
||||
};
|
||||
static const size_t FROST_RESISTANCE_TOTEM_COUNT = sizeof(FROST_RESISTANCE_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Fire Elemental Totem
|
||||
static const uint32 FIRE_ELEMENTAL_TOTEM[] = {
|
||||
2894 // Rank 1
|
||||
};
|
||||
static const size_t FIRE_ELEMENTAL_TOTEM_COUNT = sizeof(FIRE_ELEMENTAL_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Healing Stream Totem
|
||||
static const uint32 HEALING_STREAM_TOTEM[] = {
|
||||
58757, // Rank 9
|
||||
58756, // Rank 8
|
||||
58755, // Rank 7
|
||||
25567, // Rank 6
|
||||
10463, // Rank 5
|
||||
10462, // Rank 4
|
||||
6377, // Rank 3
|
||||
6375, // Rank 2
|
||||
5394 // Rank 1
|
||||
};
|
||||
static const size_t HEALING_STREAM_TOTEM_COUNT = sizeof(HEALING_STREAM_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Mana Spring Totem
|
||||
static const uint32 MANA_SPRING_TOTEM[] = {
|
||||
58774, // Rank 8
|
||||
58773, // Rank 7
|
||||
58771, // Rank 6
|
||||
25570, // Rank 5
|
||||
10497, // Rank 4
|
||||
10496, // Rank 3
|
||||
10495, // Rank 2
|
||||
5675 // Rank 1
|
||||
};
|
||||
static const size_t MANA_SPRING_TOTEM_COUNT = sizeof(MANA_SPRING_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Cleansing Totem
|
||||
static const uint32 CLEANSING_TOTEM[] = {
|
||||
8170 // Rank 1
|
||||
};
|
||||
static const size_t CLEANSING_TOTEM_COUNT = sizeof(CLEANSING_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Fire Resistance Totem
|
||||
static const uint32 FIRE_RESISTANCE_TOTEM[] = {
|
||||
58739, // Rank 6
|
||||
58737, // Rank 5
|
||||
25563, // Rank 4
|
||||
10538, // Rank 3
|
||||
10537, // Rank 2
|
||||
8184 // Rank 1
|
||||
};
|
||||
static const size_t FIRE_RESISTANCE_TOTEM_COUNT = sizeof(FIRE_RESISTANCE_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Mana Tide Totem
|
||||
static const uint32 MANA_TIDE_TOTEM[] = {
|
||||
16190 // Rank 1
|
||||
};
|
||||
static const size_t MANA_TIDE_TOTEM_COUNT = sizeof(MANA_TIDE_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Wrath of Air Totem
|
||||
static const uint32 WRATH_OF_AIR_TOTEM[] = {
|
||||
3738 // Rank 1
|
||||
};
|
||||
static const size_t WRATH_OF_AIR_TOTEM_COUNT = sizeof(WRATH_OF_AIR_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Windfury Totem
|
||||
static const uint32 WINDFURY_TOTEM[] = {
|
||||
8512 // Rank 1
|
||||
};
|
||||
static const size_t WINDFURY_TOTEM_COUNT = sizeof(WINDFURY_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Nature Resistance Totem
|
||||
static const uint32 NATURE_RESISTANCE_TOTEM[] = {
|
||||
58749, // Rank 6
|
||||
58746, // Rank 5
|
||||
25574, // Rank 4
|
||||
10601, // Rank 3
|
||||
10600, // Rank 2
|
||||
10595 // Rank 1
|
||||
};
|
||||
static const size_t NATURE_RESISTANCE_TOTEM_COUNT = sizeof(NATURE_RESISTANCE_TOTEM) / sizeof(uint32);
|
||||
|
||||
// Grounding Totem
|
||||
static const uint32 GROUNDING_TOTEM[] = {
|
||||
8177 // Rank 1
|
||||
};
|
||||
static const size_t GROUNDING_TOTEM_COUNT = sizeof(GROUNDING_TOTEM) / sizeof(uint32);
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class TotemsShamanStrategy : public GenericShamanStrategy
|
||||
// Earth Totem Strategies
|
||||
class StrengthOfEarthTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
TotemsShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
StrengthOfEarthTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "totems"; }
|
||||
std::string const getName() override { return "strength of earth"; }
|
||||
};
|
||||
|
||||
class StoneclawTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
StoneclawTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "stoneskin"; }
|
||||
};
|
||||
|
||||
class EarthTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
EarthTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "tremor"; }
|
||||
};
|
||||
|
||||
class EarthbindTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
EarthbindTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "earthbind"; }
|
||||
};
|
||||
|
||||
// Fire Totem Strategies
|
||||
class SearingTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
SearingTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "searing"; }
|
||||
};
|
||||
|
||||
class MagmaTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
MagmaTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "magma"; }
|
||||
};
|
||||
|
||||
class FlametongueTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
FlametongueTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "flametongue"; }
|
||||
};
|
||||
|
||||
class TotemOfWrathStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
TotemOfWrathStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "wrath"; }
|
||||
};
|
||||
|
||||
class FrostResistanceTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
FrostResistanceTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "frost resistance"; }
|
||||
};
|
||||
|
||||
// Water Totem Strategies
|
||||
class HealingStreamTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
HealingStreamTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "healing stream"; }
|
||||
};
|
||||
|
||||
class ManaSpringTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
ManaSpringTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "mana spring"; }
|
||||
};
|
||||
|
||||
class CleansingTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
CleansingTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cleansing"; }
|
||||
};
|
||||
|
||||
class FireResistanceTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
FireResistanceTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "fire resistance"; }
|
||||
};
|
||||
|
||||
// Air Totem Strategies
|
||||
class WrathOfAirTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
WrathOfAirTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "wrath of air"; }
|
||||
};
|
||||
|
||||
class WindfuryTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
WindfuryTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "windfury"; }
|
||||
};
|
||||
|
||||
class NatureResistanceTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
NatureResistanceTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "nature resistance"; }
|
||||
};
|
||||
|
||||
class GroundingTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
GroundingTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "grounding"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user