mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
* 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>
663 lines
19 KiB
C++
663 lines
19 KiB
C++
/*
|
|
* 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_SHAMANACTIONS_H
|
|
#define _PLAYERBOT_SHAMANACTIONS_H
|
|
|
|
#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:
|
|
CastLesserHealingWaveAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "lesser healing wave") {}
|
|
};
|
|
|
|
class CastLesserHealingWaveOnPartyAction : public HealPartyMemberAction
|
|
{
|
|
public:
|
|
CastLesserHealingWaveOnPartyAction(PlayerbotAI* botAI)
|
|
: HealPartyMemberAction(botAI, "lesser healing wave", 25.0f, HealingManaEfficiency::LOW)
|
|
{
|
|
}
|
|
};
|
|
|
|
class CastHealingWaveAction : public CastHealingSpellAction
|
|
{
|
|
public:
|
|
CastHealingWaveAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "healing wave") {}
|
|
};
|
|
|
|
class CastHealingWaveOnPartyAction : public HealPartyMemberAction
|
|
{
|
|
public:
|
|
CastHealingWaveOnPartyAction(PlayerbotAI* botAI)
|
|
: HealPartyMemberAction(botAI, "healing wave", 50.0f, HealingManaEfficiency::MEDIUM)
|
|
{
|
|
}
|
|
};
|
|
|
|
class CastChainHealAction : public HealPartyMemberAction
|
|
{
|
|
public:
|
|
CastChainHealAction(PlayerbotAI* botAI)
|
|
: HealPartyMemberAction(botAI, "chain heal", 15.0f, HealingManaEfficiency::HIGH)
|
|
{
|
|
}
|
|
};
|
|
|
|
class CastRiptideAction : public CastHealingSpellAction
|
|
{
|
|
public:
|
|
CastRiptideAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "riptide") {}
|
|
};
|
|
|
|
class CastRiptideOnPartyAction : public HealPartyMemberAction
|
|
{
|
|
public:
|
|
CastRiptideOnPartyAction(PlayerbotAI* botAI)
|
|
: HealPartyMemberAction(botAI, "riptide", 15.0f, HealingManaEfficiency::VERY_HIGH)
|
|
{
|
|
}
|
|
};
|
|
|
|
class CastEarthShieldAction : public CastBuffSpellAction
|
|
{
|
|
public:
|
|
CastEarthShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "earth shield") {}
|
|
};
|
|
|
|
class CastEarthShieldOnPartyAction : public BuffOnPartyAction
|
|
{
|
|
public:
|
|
CastEarthShieldOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "earth shield") {}
|
|
};
|
|
|
|
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* 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", "") {}
|
|
virtual std::string const GetTargetName() override { return "self target"; }
|
|
virtual bool isUseful() override { return CastTotemAction::isUseful(); }
|
|
};
|
|
|
|
class CastFireElementalTotemMeleeAction : public CastTotemAction
|
|
{
|
|
public:
|
|
CastFireElementalTotemMeleeAction(PlayerbotAI* ai) : CastTotemAction(ai, "fire elemental totem", "") {}
|
|
virtual std::string const GetTargetName() override { return "self target"; }
|
|
virtual bool isUseful() override
|
|
{
|
|
Unit* target = AI_VALUE(Unit*, "current target");
|
|
if (!target || !bot->IsWithinMeleeRange(target))
|
|
return false;
|
|
return CastTotemAction::isUseful();
|
|
}
|
|
};
|
|
|
|
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 CastWindfuryTotemAction : public CastTotemAction
|
|
{
|
|
public:
|
|
CastWindfuryTotemAction(PlayerbotAI* botAI) : CastTotemAction(botAI, "windfury totem", "windfury totem") {}
|
|
};
|
|
|
|
class CastNatureResistanceTotemAction : public CastTotemAction
|
|
{
|
|
public:
|
|
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
|