mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-26 06:56:24 +00:00
[HOT FIX] MS build issues regarding folder / command lenght usage or rc.exe (#2038)
This commit is contained in:
123
src/Ai/Class/Shaman/Action/ShamanActions.cpp
Normal file
123
src/Ai/Class/Shaman/Action/ShamanActions.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "ShamanActions.h"
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Totem.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Action.h"
|
||||
|
||||
bool CastTotemAction::isUseful()
|
||||
{
|
||||
return CastBuffSpellAction::isUseful()
|
||||
&& !AI_VALUE2(bool, "has totem", name)
|
||||
&& !botAI->HasAura(buff, bot);
|
||||
}
|
||||
|
||||
bool CastMagmaTotemAction::isUseful() {
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target || !bot->IsWithinMeleeRange(target))
|
||||
return false;
|
||||
|
||||
return CastTotemAction::isUseful() && !AI_VALUE2(bool, "has totem", name);
|
||||
}
|
||||
|
||||
bool CastFireNovaAction::isUseful() {
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Creature* fireTotem = bot->GetMap()->GetCreature(bot->m_SummonSlot[1]);
|
||||
if (!fireTotem)
|
||||
return false;
|
||||
|
||||
if (target->GetDistance(fireTotem) > 8.0f)
|
||||
return false;
|
||||
|
||||
return CastMeleeSpellAction::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 !bot->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_SPELL_IDS[] = {8050, 8052, 8053, 10447, 10448, 29228, 25457, 49232, 49233};
|
||||
|
||||
ObjectGuid botGuid = bot->GetGUID();
|
||||
for (uint32 spellId : FLAME_SHOCK_SPELL_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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
uint32 totemSpell = 0;
|
||||
for (size_t i = 0; i < totemSpellIdsCount; ++i)
|
||||
{
|
||||
if (bot->HasSpell(totemSpellIds[i]))
|
||||
{
|
||||
totemSpell = totemSpellIds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!totemSpell)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const ActionButton* button = bot->GetActionButton(actionButtonId))
|
||||
{
|
||||
if (button->GetType() == ACTION_BUTTON_SPELL && button->GetAction() == totemSpell)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bot->addActionButton(actionButtonId, totemSpell, ACTION_BUTTON_SPELL);
|
||||
return true;
|
||||
}
|
||||
667
src/Ai/Class/Shaman/Action/ShamanActions.h
Normal file
667
src/Ai/Class/Shaman/Action/ShamanActions.h
Normal file
@@ -0,0 +1,667 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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:
|
||||
// Template constructor: infers N (size of the id array) at compile time
|
||||
template <size_t N>
|
||||
SetTotemAction(PlayerbotAI* botAI, std::string const& totemName, const uint32 (&ids)[N], int actionButtonId)
|
||||
: Action(botAI, "set " + totemName)
|
||||
, totemSpellIds(ids)
|
||||
, totemSpellIdsCount(N)
|
||||
, actionButtonId(actionButtonId)
|
||||
{}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
uint32 const* totemSpellIds;
|
||||
size_t totemSpellIdsCount;
|
||||
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
|
||||
496
src/Ai/Class/Shaman/ShamanAiObjectContext.cpp
Normal file
496
src/Ai/Class/Shaman/ShamanAiObjectContext.cpp
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "ShamanAiObjectContext.h"
|
||||
|
||||
#include "ElementalShamanStrategy.h"
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "RestoShamanStrategy.h"
|
||||
#include "EnhancementShamanStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ShamanActions.h"
|
||||
#include "ShamanNonCombatStrategy.h"
|
||||
#include "ShamanTriggers.h"
|
||||
#include "TotemsShamanStrategy.h"
|
||||
|
||||
class ShamanStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &ShamanStrategyFactoryInternal::nc;
|
||||
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* 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); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new ShamanBoostStrategy(botAI); }
|
||||
};
|
||||
|
||||
class ShamanCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
ShamanCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["heal"] = &ShamanCombatStrategyFactoryInternal::resto;
|
||||
creators["melee"] = &ShamanCombatStrategyFactoryInternal::enh;
|
||||
creators["dps"] = &ShamanCombatStrategyFactoryInternal::enh;
|
||||
creators["caster"] = &ShamanCombatStrategyFactoryInternal::ele;
|
||||
//creators["offheal"] = &ShamanCombatStrategyFactoryInternal::offheal;
|
||||
creators["resto"] = &ShamanCombatStrategyFactoryInternal::resto;
|
||||
creators["enh"] = &ShamanCombatStrategyFactoryInternal::enh;
|
||||
creators["ele"] = &ShamanCombatStrategyFactoryInternal::ele;
|
||||
}
|
||||
|
||||
private:
|
||||
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>
|
||||
{
|
||||
public:
|
||||
ShamanATriggerFactoryInternal()
|
||||
{
|
||||
creators["wind shear"] = &ShamanATriggerFactoryInternal::wind_shear;
|
||||
creators["purge"] = &ShamanATriggerFactoryInternal::purge;
|
||||
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;
|
||||
creators["lightning shield"] = &ShamanATriggerFactoryInternal::lightning_shield;
|
||||
creators["water breathing"] = &ShamanATriggerFactoryInternal::water_breathing;
|
||||
creators["water walking"] = &ShamanATriggerFactoryInternal::water_walking;
|
||||
creators["water breathing on party"] = &ShamanATriggerFactoryInternal::water_breathing_on_party;
|
||||
creators["water walking on party"] = &ShamanATriggerFactoryInternal::water_walking_on_party;
|
||||
creators["cleanse spirit poison"] = &ShamanATriggerFactoryInternal::cleanse_poison;
|
||||
creators["cleanse spirit curse"] = &ShamanATriggerFactoryInternal::cleanse_curse;
|
||||
creators["cleanse spirit disease"] = &ShamanATriggerFactoryInternal::cleanse_disease;
|
||||
creators["party member cleanse spirit poison"] = &ShamanATriggerFactoryInternal::party_member_cleanse_poison;
|
||||
creators["party member cleanse spirit curse"] = &ShamanATriggerFactoryInternal::party_member_cleanse_curse;
|
||||
creators["party member cleanse spirit disease"] = &ShamanATriggerFactoryInternal::party_member_cleanse_disease;
|
||||
creators["shock"] = &ShamanATriggerFactoryInternal::shock;
|
||||
creators["frost shock snare"] = &ShamanATriggerFactoryInternal::frost_shock_snare;
|
||||
creators["heroism"] = &ShamanATriggerFactoryInternal::heroism;
|
||||
creators["bloodlust"] = &ShamanATriggerFactoryInternal::bloodlust;
|
||||
creators["elemental mastery"] = &ShamanATriggerFactoryInternal::elemental_mastery;
|
||||
creators["wind shear on enemy healer"] = &ShamanATriggerFactoryInternal::wind_shear_on_enemy_healer;
|
||||
creators["cure poison"] = &ShamanATriggerFactoryInternal::cure_poison;
|
||||
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["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["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:
|
||||
static Trigger* maelstrom_weapon_3(PlayerbotAI* botAI) { return new MaelstromWeaponTrigger(botAI, 3); }
|
||||
static Trigger* maelstrom_weapon_4(PlayerbotAI* botAI) { return new MaelstromWeaponTrigger(botAI, 4); }
|
||||
static Trigger* maelstrom_weapon_5(PlayerbotAI* botAI) { return new MaelstromWeaponTrigger(botAI, 5); }
|
||||
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* 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); }
|
||||
static Trigger* water_breathing(PlayerbotAI* botAI) { return new WaterBreathingTrigger(botAI); }
|
||||
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* wind_shear(PlayerbotAI* botAI) { return new WindShearInterruptSpellTrigger(botAI); }
|
||||
static Trigger* purge(PlayerbotAI* botAI) { return new PurgeTrigger(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* 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* 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>
|
||||
{
|
||||
public:
|
||||
ShamanAiObjectContextInternal()
|
||||
{
|
||||
creators["water shield"] = &ShamanAiObjectContextInternal::water_shield;
|
||||
creators["lightning shield"] = &ShamanAiObjectContextInternal::lightning_shield;
|
||||
creators["wind shear"] = &ShamanAiObjectContextInternal::wind_shear;
|
||||
creators["wind shear on enemy healer"] = &ShamanAiObjectContextInternal::wind_shear_on_enemy_healer;
|
||||
creators["rockbiter weapon"] = &ShamanAiObjectContextInternal::rockbiter_weapon;
|
||||
creators["flametongue weapon"] = &ShamanAiObjectContextInternal::flametongue_weapon;
|
||||
creators["frostbrand weapon"] = &ShamanAiObjectContextInternal::frostbrand_weapon;
|
||||
creators["windfury weapon"] = &ShamanAiObjectContextInternal::windfury_weapon;
|
||||
creators["earthliving weapon"] = &ShamanAiObjectContextInternal::earthliving_weapon;
|
||||
creators["purge"] = &ShamanAiObjectContextInternal::purge;
|
||||
creators["healing wave"] = &ShamanAiObjectContextInternal::healing_wave;
|
||||
creators["lesser healing wave"] = &ShamanAiObjectContextInternal::lesser_healing_wave;
|
||||
creators["healing wave on party"] = &ShamanAiObjectContextInternal::healing_wave_on_party;
|
||||
creators["lesser healing wave on party"] = &ShamanAiObjectContextInternal::lesser_healing_wave_on_party;
|
||||
creators["earth shield"] = &ShamanAiObjectContextInternal::earth_shield;
|
||||
creators["earth shield on party"] = &ShamanAiObjectContextInternal::earth_shield_on_party;
|
||||
creators["chain heal on party"] = &ShamanAiObjectContextInternal::chain_heal;
|
||||
creators["riptide"] = &ShamanAiObjectContextInternal::riptide;
|
||||
creators["riptide on party"] = &ShamanAiObjectContextInternal::riptide_on_party;
|
||||
creators["stormstrike"] = &ShamanAiObjectContextInternal::stormstrike;
|
||||
creators["lava lash"] = &ShamanAiObjectContextInternal::lava_lash;
|
||||
creators["fire nova"] = &ShamanAiObjectContextInternal::fire_nova;
|
||||
creators["ancestral spirit"] = &ShamanAiObjectContextInternal::ancestral_spirit;
|
||||
creators["water walking"] = &ShamanAiObjectContextInternal::water_walking;
|
||||
creators["water breathing"] = &ShamanAiObjectContextInternal::water_breathing;
|
||||
creators["water walking on party"] = &ShamanAiObjectContextInternal::water_walking_on_party;
|
||||
creators["water breathing on party"] = &ShamanAiObjectContextInternal::water_breathing_on_party;
|
||||
creators["cleanse spirit"] = &ShamanAiObjectContextInternal::cleanse_spirit;
|
||||
creators["cleanse spirit poison on party"] = &ShamanAiObjectContextInternal::cleanse_spirit_poison_on_party;
|
||||
creators["cleanse spirit disease on party"] = &ShamanAiObjectContextInternal::cleanse_spirit_disease_on_party;
|
||||
creators["cleanse spirit curse on party"] = &ShamanAiObjectContextInternal::cleanse_spirit_curse_on_party;
|
||||
creators["flame shock"] = &ShamanAiObjectContextInternal::flame_shock;
|
||||
creators["earth shock"] = &ShamanAiObjectContextInternal::earth_shock;
|
||||
creators["frost shock"] = &ShamanAiObjectContextInternal::frost_shock;
|
||||
creators["chain lightning"] = &ShamanAiObjectContextInternal::chain_lightning;
|
||||
creators["lightning bolt"] = &ShamanAiObjectContextInternal::lightning_bolt;
|
||||
creators["thunderstorm"] = &ShamanAiObjectContextInternal::thunderstorm;
|
||||
creators["heroism"] = &ShamanAiObjectContextInternal::heroism;
|
||||
creators["bloodlust"] = &ShamanAiObjectContextInternal::bloodlust;
|
||||
creators["elemental mastery"] = &ShamanAiObjectContextInternal::elemental_mastery;
|
||||
creators["cure disease"] = &ShamanAiObjectContextInternal::cure_disease;
|
||||
creators["cure disease on party"] = &ShamanAiObjectContextInternal::cure_disease_on_party;
|
||||
creators["cure poison"] = &ShamanAiObjectContextInternal::cure_poison;
|
||||
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["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:
|
||||
static Action* heroism(PlayerbotAI* botAI) { return new CastHeroismAction(botAI); }
|
||||
static Action* bloodlust(PlayerbotAI* botAI) { return new CastBloodlustAction(botAI); }
|
||||
static Action* elemental_mastery(PlayerbotAI* botAI) { return new CastElementalMasteryAction(botAI); }
|
||||
static Action* thunderstorm(PlayerbotAI* botAI) { return new CastThunderstormAction(botAI); }
|
||||
static Action* lightning_bolt(PlayerbotAI* botAI) { return new CastLightningBoltAction(botAI); }
|
||||
static Action* chain_lightning(PlayerbotAI* botAI) { return new CastChainLightningAction(botAI); }
|
||||
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(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); }
|
||||
static Action* water_walking_on_party(PlayerbotAI* botAI) { return new CastWaterWalkingOnPartyAction(botAI); }
|
||||
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* fire_nova(PlayerbotAI* botAI) { return new CastFireNovaAction(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); }
|
||||
static Action* frostbrand_weapon(PlayerbotAI* botAI) { return new CastFrostbrandWeaponAction(botAI); }
|
||||
static Action* windfury_weapon(PlayerbotAI* botAI) { return new CastWindfuryWeaponAction(botAI); }
|
||||
static Action* earthliving_weapon(PlayerbotAI* botAI) { return new CastEarthlivingWeaponAction(botAI); }
|
||||
static Action* purge(PlayerbotAI* botAI) { return new CastPurgeAction(botAI); }
|
||||
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* 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); }
|
||||
static Action* riptide(PlayerbotAI* botAI) { return new CastRiptideAction(botAI); }
|
||||
static Action* riptide_on_party(PlayerbotAI* botAI) { return new CastRiptideOnPartyAction(botAI); }
|
||||
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* 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* 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;
|
||||
SharedNamedObjectContextList<Action> ShamanAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> ShamanAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> ShamanAiObjectContext::sharedValueContexts;
|
||||
|
||||
ShamanAiObjectContext::ShamanAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new ShamanStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanCombatStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanEarthTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanFireTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanWaterTotemStrategyFactoryInternal());
|
||||
strategyContexts.Add(new ShamanAirTotemStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new ShamanAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new ShamanATriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void ShamanAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Shaman/ShamanAiObjectContext.h
Normal file
30
src/Ai/Class/Shaman/ShamanAiObjectContext.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_SHAMANAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_SHAMANAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ShamanAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
ShamanAiObjectContext(PlayerbotAI* botAI);
|
||||
|
||||
static void BuildSharedContexts();
|
||||
static void BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts);
|
||||
static void BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts);
|
||||
static void BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts);
|
||||
static void BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts);
|
||||
|
||||
static SharedNamedObjectContextList<Strategy> sharedStrategyContexts;
|
||||
static SharedNamedObjectContextList<Action> sharedActionContexts;
|
||||
static SharedNamedObjectContextList<Trigger> sharedTriggerContexts;
|
||||
static SharedNamedObjectContextList<UntypedValue> sharedValueContexts;
|
||||
};
|
||||
|
||||
#endif
|
||||
132
src/Ai/Class/Shaman/Strategy/ElementalShamanStrategy.cpp
Normal file
132
src/Ai/Class/Shaman/Strategy/ElementalShamanStrategy.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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", {}, {}, {}); }
|
||||
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", {}, {}, {}); }
|
||||
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", {}, {}, {}); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", {}, {}, {}); }
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", {}, {}, {}); }
|
||||
static ActionNode* elemental_mastery(PlayerbotAI*) { return new ActionNode("elemental mastery", {}, {}, {}); }
|
||||
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", {}, {}, {}); }
|
||||
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", {}, {}, {}); }
|
||||
static ActionNode* thunderstorm(PlayerbotAI*) { return new ActionNode("thunderstorm", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
ElementalShamanStrategy::ElementalShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new ElementalShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> ElementalShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("lava burst", 5.2f),
|
||||
NextAction("lightning bolt", 5.0f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void ElementalShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
|
||||
// Totem Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"call of the elements",
|
||||
{
|
||||
NextAction("call of the elements", 60.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("stoneclaw totem", 40.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Cooldown Trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"elemental mastery",
|
||||
{
|
||||
NextAction("elemental mastery", 29.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Damage Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"earth shock execute",
|
||||
{
|
||||
NextAction("earth shock", 5.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"flame shock",
|
||||
{
|
||||
NextAction("flame shock", 5.3f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Mana Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"water shield",
|
||||
{
|
||||
NextAction("water shield", 19.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"high mana",
|
||||
{
|
||||
NextAction("thunderstorm", 19.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Range Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy is close",
|
||||
{
|
||||
NextAction("thunderstorm", 19.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Shaman/Strategy/ElementalShamanStrategy.h
Normal file
24
src/Ai/Class/Shaman/Strategy/ElementalShamanStrategy.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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;
|
||||
std::vector<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
|
||||
149
src/Ai/Class/Shaman/Strategy/EnhancementShamanStrategy.cpp
Normal file
149
src/Ai/Class/Shaman/Strategy/EnhancementShamanStrategy.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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", {}, {}, {}); }
|
||||
static ActionNode* lava_lash([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"lava lash",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* feral_spirit(PlayerbotAI*) { return new ActionNode("feral spirit", {}, {}, {}); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", {}, {}, {}); }
|
||||
static ActionNode* earth_shock(PlayerbotAI*) { return new ActionNode("earth shock", {}, {}, {}); }
|
||||
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", {}, {}, {}); }
|
||||
static ActionNode* shamanistic_rage(PlayerbotAI*) { return new ActionNode("shamanistic rage", {}, {}, {}); }
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", {}, {}, {}); }
|
||||
static ActionNode* lightning_shield(PlayerbotAI*) { return new ActionNode("lightning shield", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
EnhancementShamanStrategy::EnhancementShamanStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new EnhancementShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> EnhancementShamanStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("stormstrike", 5.5f),
|
||||
NextAction("feral spirit", 5.4f),
|
||||
NextAction("earth shock", 5.3f),
|
||||
NextAction("lava lash", 5.2f),
|
||||
NextAction("melee", 5.0f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== 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("call of the elements", 60.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Spirit Walk Trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"spirit walk ready",
|
||||
{
|
||||
NextAction("spirit walk", 50.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Damage Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("reach melee", 40.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"maelstrom weapon 5",
|
||||
{
|
||||
NextAction("lightning bolt", 20.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"maelstrom weapon 4",
|
||||
{
|
||||
NextAction("lightning bolt", 19.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"flame shock",
|
||||
{
|
||||
NextAction("flame shock", 19.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lightning shield",
|
||||
{
|
||||
NextAction("lightning shield", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Health/Mana Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium mana",
|
||||
{
|
||||
NextAction("shamanistic rage", 23.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("shamanistic rage", 23.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Shaman/Strategy/EnhancementShamanStrategy.h
Normal file
24
src/Ai/Class/Shaman/Strategy/EnhancementShamanStrategy.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_ENHANCEMENTSHAMANSTRATEGY_H
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class EnhancementShamanStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
EnhancementShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
std::string const getName() override { return "enh"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
171
src/Ai/Class/Shaman/Strategy/GenericShamanStrategy.cpp
Normal file
171
src/Ai/Class/Shaman/Strategy/GenericShamanStrategy.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "GenericShamanStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericShamanStrategyActionNodeFactory()
|
||||
{
|
||||
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:
|
||||
// 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*/ {},
|
||||
/*A*/ { NextAction("flametongue totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* flametongue_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("flametongue totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("searing totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* magma_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("magma totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("searing totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* searing_totem(PlayerbotAI*) { return new ActionNode("searing totem", {}, {}, {}); }
|
||||
static ActionNode* strength_of_earth_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("strength of earth totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("stoneskin totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* stoneskin_totem(PlayerbotAI*) { return new ActionNode("stoneskin totem", {}, {}, {}); }
|
||||
static ActionNode* cleansing_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cleansing totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("mana spring totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* mana_spring_totem(PlayerbotAI*) { return new ActionNode("mana spring totem", {}, {}, {}); }
|
||||
static ActionNode* healing_stream_totem(PlayerbotAI*) { return new ActionNode("healing stream totem", {}, {}, {}); }
|
||||
static ActionNode* wrath_of_air_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("wrath of air totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("windfury totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* windfury_totem([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("windfury totem",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("grounding totem") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* grounding_totem(PlayerbotAI*) { return new ActionNode("grounding totem", {}, {}, {}); }
|
||||
static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", {}, {}, {}); }
|
||||
static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", {}, {}, {}); }
|
||||
};
|
||||
|
||||
GenericShamanStrategy::GenericShamanStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericShamanStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("wind shear", { NextAction("wind shear", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("wind shear on enemy healer", { NextAction("wind shear on enemy healer", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("purge", { NextAction("purge", ACTION_DISPEL), }));
|
||||
triggers.push_back(new TriggerNode("medium mana", { NextAction("mana potion", ACTION_DISPEL), }));
|
||||
triggers.push_back(new TriggerNode("new pet", { NextAction("set pet stance", 65.0f), }));
|
||||
}
|
||||
|
||||
void ShamanCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("cure poison", { NextAction("cure poison", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", { NextAction("cure poison on party", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit poison", { NextAction("cleanse spirit", 24.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit poison", { NextAction("cleanse spirit poison on party", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("cure disease", { NextAction("cure disease", 31.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cure disease", { NextAction("cure disease on party", 30.0f), }));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit disease", { NextAction("cleanse spirit", 24.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit disease", { NextAction("cleanse spirit disease on party", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("cleanse spirit curse", { NextAction("cleanse spirit", 24.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit curse", { NextAction("cleanse spirit curse on party", 23.0f), }));
|
||||
}
|
||||
|
||||
void ShamanBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("heroism", { NextAction("heroism", 30.0f), }));
|
||||
triggers.push_back(new TriggerNode("bloodlust", { NextAction("bloodlust", 30.0f), }));
|
||||
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Elemental
|
||||
{
|
||||
triggers.push_back(new TriggerNode("fire elemental totem", { NextAction("fire elemental totem", 23.0f), }));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("fire elemental totem", { NextAction("fire elemental totem melee", 24.0f), }));
|
||||
}
|
||||
}
|
||||
|
||||
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("fire nova", 23.0f), }));
|
||||
triggers.push_back(new TriggerNode("chain lightning no cd", { NextAction("chain lightning", 5.6f), }));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("medium aoe",{
|
||||
NextAction("magma totem", 24.0f),
|
||||
NextAction("fire nova", 23.0f), }));
|
||||
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 5 and medium aoe", { NextAction("chain lightning", 22.0f), }));
|
||||
triggers.push_back(new TriggerNode("maelstrom weapon 4 and medium aoe", { NextAction("chain lightning", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("enemy within melee", { NextAction("fire nova", 5.1f), }));
|
||||
}
|
||||
else if (tab == 2) // Restoration
|
||||
{
|
||||
// Handled by "Healer DPS" Strategy
|
||||
}
|
||||
}
|
||||
48
src/Ai/Class/Shaman/Strategy/GenericShamanStrategy.h
Normal file
48
src/Ai/Class/Shaman/Strategy/GenericShamanStrategy.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_GENERICSHAMANSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICSHAMANSTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericShamanStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericShamanStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class ShamanCureStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanCureStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cure"; }
|
||||
};
|
||||
|
||||
class ShamanBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ShamanBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
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
|
||||
124
src/Ai/Class/Shaman/Strategy/RestoShamanStrategy.cpp
Normal file
124
src/Ai/Class/Shaman/Strategy/RestoShamanStrategy.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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*/ {},
|
||||
/*A*/ { NextAction("mana potion") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* call_of_the_elements(PlayerbotAI*) { return new ActionNode("call of the elements", {}, {}, {}); }
|
||||
static ActionNode* stoneclaw_totem(PlayerbotAI*) { return new ActionNode("stoneclaw totem", {}, {}, {}); }
|
||||
static ActionNode* riptide_on_party(PlayerbotAI*) { return new ActionNode("riptide on party", {}, {}, {}); }
|
||||
static ActionNode* chain_heal_on_party(PlayerbotAI*) { return new ActionNode("chain heal on party", {}, {}, {}); }
|
||||
static ActionNode* healing_wave_on_party(PlayerbotAI*) { return new ActionNode("healing wave on party", {}, {}, {}); }
|
||||
static ActionNode* lesser_healing_wave_on_party(PlayerbotAI*) { return new ActionNode("lesser healing wave on party", {}, {}, {}); }
|
||||
static ActionNode* earth_shield_on_main_tank(PlayerbotAI*) { return new ActionNode("earth shield on main tank", {}, {}, {}); }
|
||||
static ActionNode* cleanse_spirit_poison_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit poison on party", {}, {}, {}); }
|
||||
static ActionNode* cleanse_spirit_disease_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit disease on party", {}, {}, {}); }
|
||||
static ActionNode* cleanse_spirit_curse_on_party(PlayerbotAI*) { return new ActionNode("cleanse spirit curse on party", {}, {}, {}); }
|
||||
static ActionNode* cleansing_totem(PlayerbotAI*) { return new ActionNode("cleansing totem", {}, {}, {}); }
|
||||
static ActionNode* water_shield(PlayerbotAI*) { return new ActionNode("water shield", {}, {}, {}); }
|
||||
static ActionNode* flame_shock(PlayerbotAI*) { return new ActionNode("flame shock", {}, {}, {}); }
|
||||
static ActionNode* lava_burst(PlayerbotAI*) { return new ActionNode("lava burst", {}, {}, {}); }
|
||||
static ActionNode* lightning_bolt(PlayerbotAI*) { return new ActionNode("lightning bolt", {}, {}, {}); }
|
||||
static ActionNode* chain_lightning(PlayerbotAI*) { return new ActionNode("chain lightning", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== 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("call of the elements", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("low health", { NextAction("stoneclaw totem", 40.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium mana", { NextAction("mana tide totem", ACTION_HIGH + 5) }));
|
||||
|
||||
// Healing Triggers
|
||||
triggers.push_back(new TriggerNode("group heal setting", {
|
||||
NextAction("riptide on party", 27.0f),
|
||||
NextAction("chain heal on party", 26.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member critical health", {
|
||||
NextAction("riptide on party", 25.0f),
|
||||
NextAction("healing wave on party", 24.0f),
|
||||
NextAction("lesser healing wave on party", 23.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member low health", {
|
||||
NextAction("riptide on party", 19.0f),
|
||||
NextAction("healing wave on party", 18.0f),
|
||||
NextAction("lesser healing wave on party", 17.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member medium health", {
|
||||
NextAction("riptide on party", 16.0f),
|
||||
NextAction("healing wave on party", 15.0f),
|
||||
NextAction("lesser healing wave on party", 14.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member almost full health", {
|
||||
NextAction("riptide on party", 12.0f),
|
||||
NextAction("lesser healing wave on party", 11.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("earth shield on main tank", { NextAction("earth shield on main tank", ACTION_HIGH + 7) }));
|
||||
|
||||
// Dispel Triggers
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit poison", { NextAction("cleanse spirit poison on party", ACTION_DISPEL + 2) }));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit disease", { NextAction("cleanse spirit disease on party", ACTION_DISPEL + 2) }));
|
||||
triggers.push_back(new TriggerNode("party member cleanse spirit curse",{ NextAction("cleanse spirit curse on party", ACTION_DISPEL + 2) }));
|
||||
|
||||
// Range/Mana Triggers
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell", { NextAction("flee", ACTION_MOVE + 9) }));
|
||||
triggers.push_back(new TriggerNode("party member to heal out of spell range", { NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 1) }));
|
||||
triggers.push_back(new TriggerNode("water shield", { NextAction("water shield", 19.5f) }));
|
||||
}
|
||||
|
||||
void ShamanHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("healer should attack",
|
||||
{ NextAction("flame shock", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("lava burst", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("lightning bolt", ACTION_DEFAULT) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe and healer should attack",
|
||||
{ NextAction("chain lightning", ACTION_DEFAULT + 0.3f) }));
|
||||
}
|
||||
33
src/Ai/Class/Shaman/Strategy/RestoShamanStrategy.h
Normal file
33
src/Ai/Class/Shaman/Strategy/RestoShamanStrategy.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 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
|
||||
126
src/Ai/Class/Shaman/Strategy/ShamanNonCombatStrategy.cpp
Normal file
126
src/Ai/Class/Shaman/Strategy/ShamanNonCombatStrategy.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#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*/ {},
|
||||
/*A*/ { NextAction("rockbiter weapon") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* frostbrand_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frostbrand weapon",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("flametongue weapon") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* windfury_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("windfury weapon",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("flametongue weapon") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* earthliving_weapon([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("earthliving weapon",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("flametongue weapon") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* wind_shear(PlayerbotAI*) { return new ActionNode("wind shear", {}, {}, {}); }
|
||||
static ActionNode* purge(PlayerbotAI*) { return new ActionNode("purge", {}, {}, {}); }
|
||||
};
|
||||
|
||||
ShamanNonCombatStrategy::ShamanNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new ShamanNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void ShamanNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
// Totemic Recall
|
||||
triggers.push_back(new TriggerNode("totemic recall", { NextAction("totemic recall", 60.0f), }));
|
||||
|
||||
// Healing/Resurrect Triggers
|
||||
triggers.push_back(new TriggerNode("party member dead", { NextAction("ancestral spirit", ACTION_CRITICAL_HEAL + 10), }));
|
||||
triggers.push_back(new TriggerNode("party member critical health", {
|
||||
NextAction("riptide on party", 31.0f),
|
||||
NextAction("healing wave on party", 30.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member low health",{
|
||||
NextAction("riptide on party", 29.0f),
|
||||
NextAction("healing wave on party", 28.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member medium health",{
|
||||
NextAction("riptide on party", 27.0f),
|
||||
NextAction("healing wave on party", 26.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member almost full health",{
|
||||
NextAction("riptide on party", 25.0f),
|
||||
NextAction("lesser healing wave on party", 24.0f) }));
|
||||
triggers.push_back(new TriggerNode("group heal setting",{ NextAction("chain heal on party", 27.0f) }));
|
||||
|
||||
// Cure Triggers
|
||||
triggers.push_back(new TriggerNode("cure poison", { NextAction("cure poison", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", { NextAction("cure poison on party", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("cure disease", { NextAction("cure disease", 31.0f), }));
|
||||
triggers.push_back(new TriggerNode("party member cure disease", { NextAction("cure disease on party", 30.0f), }));
|
||||
|
||||
// Out of Combat Buff Triggers
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Elemental
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue", { NextAction("flametongue weapon", 22.0f), }));
|
||||
triggers.push_back(new TriggerNode("water shield", { NextAction("water shield", 21.0f), }));
|
||||
}
|
||||
else if (tab == 1) // Enhancement
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue", { NextAction("windfury weapon", 22.0f), }));
|
||||
triggers.push_back(new TriggerNode("off hand weapon no imbue", { NextAction("flametongue weapon", 21.0f), }));
|
||||
triggers.push_back(new TriggerNode("lightning shield", { NextAction("lightning shield", 20.0f), }));
|
||||
}
|
||||
else if (tab == 2) // Restoration
|
||||
{
|
||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",{ NextAction("earthliving weapon", 22.0f), }));
|
||||
triggers.push_back(new TriggerNode("water shield", { NextAction("water shield", 20.0f), }));
|
||||
}
|
||||
|
||||
// Buff Triggers while swimming
|
||||
triggers.push_back(new TriggerNode("water breathing", { NextAction("water breathing", 12.0f), }));
|
||||
triggers.push_back(new TriggerNode("water walking", { NextAction("water walking", 12.0f), }));
|
||||
triggers.push_back(new TriggerNode("water breathing on party", { NextAction("water breathing on party", 11.0f), }));
|
||||
triggers.push_back(new TriggerNode("water walking on party", { NextAction("water walking on party", 11.0f), }));
|
||||
|
||||
// Pet Triggers
|
||||
triggers.push_back(new TriggerNode("has pet", { NextAction("toggle pet spell", 60.0f), }));
|
||||
triggers.push_back(new TriggerNode("new pet", { NextAction("set pet stance", 65.0f), }));
|
||||
}
|
||||
|
||||
void ShamanNonCombatStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
{
|
||||
NonCombatStrategy::InitMultipliers(multipliers);
|
||||
}
|
||||
23
src/Ai/Class/Shaman/Strategy/ShamanNonCombatStrategy.h
Normal file
23
src/Ai/Class/Shaman/Strategy/ShamanNonCombatStrategy.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_SHAMANNONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_SHAMANNONCOMBATSTRATEGY_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ShamanNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
ShamanNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
std::string const getName() override { return "nc"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
188
src/Ai/Class/Shaman/Strategy/TotemsShamanStrategy.cpp
Normal file
188
src/Ai/Class/Shaman/Strategy/TotemsShamanStrategy.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// 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.
|
||||
|
||||
// Earth Totems
|
||||
StrengthOfEarthTotemStrategy::StrengthOfEarthTotemStrategy(PlayerbotAI* botAI) : GenericShamanStrategy(botAI) {}
|
||||
void StrengthOfEarthTotemStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericShamanStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(new TriggerNode("set strength of earth totem", { NextAction("set strength of earth totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no earth totem", { NextAction("strength of earth totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set stoneskin totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no earth totem", { NextAction("stoneskin totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set tremor totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no earth totem", { NextAction("tremor totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set earthbind totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no earth totem", { NextAction("earthbind totem", 55.0f) }));
|
||||
}
|
||||
|
||||
// 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("set searing totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no fire totem", { NextAction("searing totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set magma totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no fire totem", { NextAction("magma totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set flametongue totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no fire totem", { NextAction("flametongue totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set totem of wrath", 60.0f) }));
|
||||
}
|
||||
else if (bot->HasSpell(8227))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set flametongue totem", { NextAction("set flametongue totem", 60.0f) }));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no fire totem", { NextAction("totem of wrath", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set frost resistance totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no fire totem", { NextAction("frost resistance totem", 55.0f) }));
|
||||
}
|
||||
|
||||
// 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("set healing stream totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no water totem", { NextAction("healing stream totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set mana spring totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no water totem", { NextAction("mana spring totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set cleansing totem", 60.0f) }));
|
||||
}
|
||||
else if (bot->HasSpell(5675))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set mana spring totem", { NextAction("set mana spring totem", 60.0f) }));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no water totem", { NextAction("cleansing totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set fire resistance totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no water totem", { NextAction("fire resistance totem", 55.0f) }));
|
||||
}
|
||||
|
||||
// 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("set wrath of air totem", 60.0f) }));
|
||||
}
|
||||
else if (bot->HasSpell(8177))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set grounding totem", { NextAction("set grounding totem", 60.0f) }));
|
||||
}
|
||||
triggers.push_back(
|
||||
new TriggerNode("no air totem", { NextAction("wrath of air totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set windfury totem", 60.0f) }));
|
||||
}
|
||||
else if (bot->HasSpell(8177))
|
||||
{
|
||||
triggers.push_back(new TriggerNode("set grounding totem", { NextAction("set grounding totem", 60.0f) }));
|
||||
}
|
||||
triggers.push_back(new TriggerNode("no air totem", { NextAction("windfury totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set nature resistance totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no air totem", { NextAction("nature resistance totem", 55.0f) }));
|
||||
}
|
||||
|
||||
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("set grounding totem", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("no air totem", { NextAction("grounding totem", 55.0f) }));
|
||||
}
|
||||
364
src/Ai/Class/Shaman/Strategy/TotemsShamanStrategy.h
Normal file
364
src/Ai/Class/Shaman/Strategy/TotemsShamanStrategy.h
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_TOTEMSSHAMANSTRATEGY_H
|
||||
#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;
|
||||
|
||||
// Earth Totem Strategies
|
||||
class StrengthOfEarthTotemStrategy : public GenericShamanStrategy
|
||||
{
|
||||
public:
|
||||
StrengthOfEarthTotemStrategy(PlayerbotAI* botAI);
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
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
|
||||
486
src/Ai/Class/Shaman/Trigger/ShamanTriggers.cpp
Normal file
486
src/Ai/Class/Shaman/Trigger/ShamanTriggers.cpp
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "ShamanTriggers.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "ItemTemplate.h"
|
||||
#include "Playerbots.h"
|
||||
#include "TotemsShamanStrategy.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Creature.h"
|
||||
#include "Unit.h"
|
||||
#include <ctime>
|
||||
|
||||
bool MainHandWeaponNoImbueTrigger::IsActive()
|
||||
{
|
||||
Item* const itemForSpell = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
|
||||
if (!itemForSpell || itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OffHandWeaponNoImbueTrigger::IsActive()
|
||||
{
|
||||
Item* const itemForSpell = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
|
||||
if (!itemForSpell)
|
||||
return false;
|
||||
|
||||
uint32 invType = itemForSpell->GetTemplate()->InventoryType;
|
||||
bool allowedType = (invType == INVTYPE_WEAPON) || (invType == INVTYPE_WEAPONOFFHAND);
|
||||
if (itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) || !allowedType)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShockTrigger::IsActive()
|
||||
{
|
||||
return SpellTrigger::IsActive() &&
|
||||
!botAI->HasAura("flame shock", GetTarget(), false, true) &&
|
||||
!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 WaterWalkingTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
bool WaterBreathingTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
bool WaterWalkingOnPartyTrigger::IsActive()
|
||||
{
|
||||
return BuffOnPartyTrigger::IsActive() && AI_VALUE2(bool, "swimming", "self target");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
constexpr uint32 SPIRIT_WOLF = 29264u;
|
||||
constexpr uint32 SPIRIT_WALK_SPELL_ID = 58875u;
|
||||
constexpr int COOLDOWN_IN_SECONDS = 32;
|
||||
|
||||
time_t now = time(nullptr);
|
||||
|
||||
if ((now - lastSpiritWalkTime) < COOLDOWN_IN_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_SPELL_ID))
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (!botAI->CanCastSpell(SPELL_CALL_OF_THE_ELEMENTS, bot, true))
|
||||
{
|
||||
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];
|
||||
bool possibleEmpty = false;
|
||||
|
||||
if (guid.IsEmpty())
|
||||
{
|
||||
possibleEmpty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Creature* totem = bot->GetMap()->GetCreature(guid);
|
||||
if (!totem || totem->GetDistance(bot) > 30.0f)
|
||||
{
|
||||
possibleEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!possibleEmpty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((slot == SUMMON_SLOT_TOTEM_EARTH && bot->HasSpell(SPELL_STONESKIN_TOTEM_RANK_1)) ||
|
||||
(slot == SUMMON_SLOT_TOTEM_FIRE && bot->HasSpell(SPELL_SEARING_TOTEM_RANK_1)) ||
|
||||
(slot == SUMMON_SLOT_TOTEM_WATER && bot->HasSpell(SPELL_HEALING_STREAM_TOTEM_RANK_1)) ||
|
||||
(slot == SUMMON_SLOT_TOTEM_AIR && bot->HasSpell(SPELL_NATURE_RESISTANCE_TOTEM_RANK_1)))
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (!bot->HasSpell(SPELL_TOTEMIC_RECALL))
|
||||
return false;
|
||||
|
||||
Map* map = bot->GetMap();
|
||||
if (map && 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;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
uint32 highestKnownSpell = 0;
|
||||
for (size_t i = 0; i < totemSpellIdsCount; ++i)
|
||||
{
|
||||
const uint32 spellId = totemSpellIds[i];
|
||||
if (bot->HasSpell(spellId))
|
||||
{
|
||||
highestKnownSpell = spellId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!highestKnownSpell)
|
||||
return false;
|
||||
|
||||
ActionButton const* button = bot->GetActionButton(actionButtonId);
|
||||
if (!button || button->GetType() != ACTION_BUTTON_SPELL || button->GetAction() == 0)
|
||||
return true;
|
||||
|
||||
if (button->GetAction() != highestKnownSpell)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
500
src/Ai/Class/Shaman/Trigger/ShamanTriggers.h
Normal file
500
src/Ai/Class/Shaman/Trigger/ShamanTriggers.h
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
||||
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_SHAMANTRIGGERS_H
|
||||
#define _PLAYERBOT_SHAMANTRIGGERS_H
|
||||
|
||||
#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;
|
||||
|
||||
// Buff and Out of Combat Triggers
|
||||
|
||||
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;
|
||||
const uint32 SPELL_CALL_OF_THE_ELEMENTS = 66842;
|
||||
|
||||
class MainHandWeaponNoImbueTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
MainHandWeaponNoImbueTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "main hand", 1) {}
|
||||
virtual bool IsActive();
|
||||
};
|
||||
|
||||
class OffHandWeaponNoImbueTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
OffHandWeaponNoImbueTrigger(PlayerbotAI* ai) : BuffTrigger(ai, "off hand", 1) {}
|
||||
virtual bool IsActive();
|
||||
};
|
||||
|
||||
class WaterShieldTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
WaterShieldTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "water shield") {}
|
||||
};
|
||||
|
||||
class LightningShieldTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
LightningShieldTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "lightning shield") {}
|
||||
};
|
||||
|
||||
class WaterWalkingTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
WaterWalkingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "water walking", 7) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class WaterBreathingTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
WaterBreathingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "water breathing", 5 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class WaterWalkingOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
WaterWalkingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water walking on party", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class WaterBreathingOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
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:
|
||||
CleanseSpiritPoisonTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cleanse spirit", DISPEL_POISON) {}
|
||||
};
|
||||
|
||||
class PartyMemberCleanseSpiritPoisonTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCleanseSpiritPoisonTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse spirit", DISPEL_POISON)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CleanseSpiritCurseTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CleanseSpiritCurseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cleanse spirit", DISPEL_CURSE) {}
|
||||
};
|
||||
|
||||
class PartyMemberCleanseSpiritCurseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCleanseSpiritCurseTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse spirit", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CleanseSpiritDiseaseTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CleanseSpiritDiseaseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "cleanse spirit", DISPEL_DISEASE) {}
|
||||
};
|
||||
|
||||
class PartyMemberCleanseSpiritDiseaseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberCleanseSpiritDiseaseTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse spirit", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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:
|
||||
ShockTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "earth shock", 1, true) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FrostShockSnareTrigger : public SnareTargetTrigger
|
||||
{
|
||||
public:
|
||||
FrostShockSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "frost shock") {}
|
||||
};
|
||||
|
||||
class MaelstromWeaponTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
MaelstromWeaponTrigger(PlayerbotAI* botAI, int stack = 5) : HasAuraStackTrigger(botAI, "maelstrom weapon", stack) {}
|
||||
};
|
||||
|
||||
class FlameShockTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class EarthShockExecuteTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
EarthShockExecuteTrigger(PlayerbotAI* botAI) : Trigger(botAI, "earth shock execute") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MaelstromWeapon5AndMediumAoeTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
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 CallOfTheElementsTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
CallOfTheElementsTrigger(PlayerbotAI* ai) : Trigger(ai, "call of the elements") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class TotemicRecallTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
NoFireTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no fire totem") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoWaterTotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoWaterTotemTrigger(PlayerbotAI* ai) : Trigger(ai, "no water totem") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoAirTotemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
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:
|
||||
// Template constructor: infers N (size of the id array) at compile time
|
||||
template <size_t N>
|
||||
SetTotemTrigger(PlayerbotAI* ai, std::string const& spellName, uint32 requiredSpellId,
|
||||
const uint32 (&ids)[N], int actionButtonId)
|
||||
: Trigger(ai, "set " + spellName)
|
||||
, requiredSpellId(requiredSpellId)
|
||||
, totemSpellIds(ids)
|
||||
, totemSpellIdsCount(N)
|
||||
, actionButtonId(actionButtonId)
|
||||
{}
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
uint32 requiredSpellId;
|
||||
uint32 const* totemSpellIds;
|
||||
size_t totemSpellIdsCount;
|
||||
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
|
||||
Reference in New Issue
Block a user