mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-25 22:46:25 +00:00
[HOT FIX] MS build issues regarding folder / command lenght usage or rc.exe (#2038)
This commit is contained in:
50
src/Ai/Class/Dk/Action/DKActions.cpp
Normal file
50
src/Ai/Class/Dk/Action/DKActions.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 "DKActions.h"
|
||||
|
||||
#include "Duration.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
std::vector<NextAction> CastDeathchillAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("frost presence") },
|
||||
CastSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastUnholyMeleeSpellAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("unholy presence") },
|
||||
CastMeleeSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastFrostMeleeSpellAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("frost presence") },
|
||||
CastMeleeSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastBloodMeleeSpellAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("blood presence") },
|
||||
CastMeleeSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
bool CastRaiseDeadAction::Execute(Event event)
|
||||
{
|
||||
const bool result = CastBuffSpellAction::Execute(event);
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
const uint32_t spellId = AI_VALUE2(uint32_t, "spell id", spell);
|
||||
|
||||
bot->AddSpellCooldown(spellId, 0, 3 * 60 * 1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
343
src/Ai/Class/Dk/Action/DKActions.h
Normal file
343
src/Ai/Class/Dk/Action/DKActions.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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_DKACTIONS_H
|
||||
#define _PLAYERBOT_DKACTIONS_H
|
||||
|
||||
#include "Event.h"
|
||||
#include "GenericSpellActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CastBloodPresenceAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodPresenceAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "blood presence") {}
|
||||
};
|
||||
|
||||
class CastFrostPresenceAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostPresenceAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "frost presence") {}
|
||||
};
|
||||
|
||||
class CastUnholyPresenceAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastUnholyPresenceAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "unholy presence") {}
|
||||
};
|
||||
|
||||
class CastDeathchillAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathchillAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "deathchill") {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
class CastDarkCommandAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDarkCommandAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dark command") {}
|
||||
};
|
||||
|
||||
BEGIN_RANGED_SPELL_ACTION(CastDeathGripAction, "death grip")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
// Unholy presence
|
||||
class CastUnholyMeleeSpellAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastUnholyMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastMeleeSpellAction(botAI, spell) {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
// Frost presence
|
||||
class CastFrostMeleeSpellAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastMeleeSpellAction(botAI, spell) {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
// Blood presence
|
||||
class CastBloodMeleeSpellAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastMeleeSpellAction(botAI, spell) {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
class CastRuneStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastRuneStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "rune strike") {}
|
||||
};
|
||||
|
||||
class CastPestilenceAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastPestilenceAction(PlayerbotAI* ai) : CastSpellAction(ai, "pestilence") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::None; }
|
||||
};
|
||||
|
||||
class CastHowlingBlastAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHowlingBlastAction(PlayerbotAI* ai) : CastSpellAction(ai, "howling blast") {}
|
||||
};
|
||||
|
||||
class CastIcyTouchAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastIcyTouchAction(PlayerbotAI* ai) : CastSpellAction(ai, "icy touch") {}
|
||||
};
|
||||
|
||||
class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastIcyTouchOnAttackerAction(PlayerbotAI* botAI)
|
||||
: CastDebuffSpellOnAttackerAction(botAI, "icy touch", true, .0f)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// debuff ps
|
||||
|
||||
class CastPlagueStrikeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastPlagueStrikeAction(PlayerbotAI* ai) : CastSpellAction(ai, "plague strike") {}
|
||||
};
|
||||
|
||||
class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction
|
||||
{
|
||||
public:
|
||||
CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI)
|
||||
: CastDebuffSpellOnMeleeAttackerAction(botAI, "plague strike", true, .0f)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// debuff
|
||||
BEGIN_DEBUFF_ACTION(CastMarkOfBloodAction, "mark of blood")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
class CastMarkOfBloodOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastMarkOfBloodOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "mark of blood", true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastUnholyBlightAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastUnholyBlightAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "unholy blight") {}
|
||||
};
|
||||
|
||||
class CastSummonGargoyleAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastSummonGargoyleAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "summon gargoyle") {}
|
||||
};
|
||||
|
||||
class CastGhoulFrenzyAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastGhoulFrenzyAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ghoul frenzy", false, 5000) {}
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
BEGIN_MELEE_SPELL_ACTION(CastCorpseExplosionAction, "corpse explosion")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
BEGIN_MELEE_SPELL_ACTION(CastAntiMagicShellAction, "anti magic shell")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
BEGIN_MELEE_SPELL_ACTION(CastAntiMagicZoneAction, "anti magic zone")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
class CastChainsOfIceAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastChainsOfIceAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chains of ice") {}
|
||||
};
|
||||
|
||||
class CastHungeringColdAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastHungeringColdAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "hungering cold") {}
|
||||
};
|
||||
|
||||
class CastHeartStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastHeartStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "heart strike") {}
|
||||
};
|
||||
|
||||
class CastBloodStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "blood strike") {}
|
||||
};
|
||||
|
||||
class CastFrostStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "frost strike") {}
|
||||
};
|
||||
|
||||
class CastObliterateAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastObliterateAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "obliterate") {}
|
||||
};
|
||||
|
||||
class CastDeathStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "death strike") {}
|
||||
};
|
||||
|
||||
class CastScourgeStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastScourgeStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "scourge strike") {}
|
||||
};
|
||||
|
||||
class CastDeathCoilAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathCoilAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "death coil") {}
|
||||
};
|
||||
|
||||
class CastBloodBoilAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodBoilAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "blood boil") {}
|
||||
};
|
||||
|
||||
class CastDeathAndDecayAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathAndDecayAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "death and decay") {}
|
||||
// ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastHornOfWinterAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHornOfWinterAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "horn of winter") {}
|
||||
};
|
||||
|
||||
class CastImprovedIcyTalonsAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastImprovedIcyTalonsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "improved icy talons") {}
|
||||
};
|
||||
|
||||
class CastBoneShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBoneShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bone shield") {}
|
||||
};
|
||||
|
||||
class CastDeathPactAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathPactAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "death pact") {}
|
||||
};
|
||||
|
||||
class CastDeathRuneMasteryAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeathRuneMasteryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "death rune mastery") {}
|
||||
};
|
||||
|
||||
class CastDancingRuneWeaponAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDancingRuneWeaponAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dancing rune weapon") {}
|
||||
};
|
||||
|
||||
class CastEmpowerRuneWeaponAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastEmpowerRuneWeaponAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "empower rune weapon") {}
|
||||
};
|
||||
|
||||
class CastArmyOfTheDeadAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastArmyOfTheDeadAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "army of the dead") {}
|
||||
};
|
||||
|
||||
class CastRaiseDeadAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastRaiseDeadAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "raise dead") {}
|
||||
virtual bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastKillingMachineAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastKillingMachineAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "killing machine") {}
|
||||
};
|
||||
|
||||
class CastIceboundFortitudeAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceboundFortitudeAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "icebound fortitude") {}
|
||||
};
|
||||
|
||||
class CastUnbreakableArmorAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastUnbreakableArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "unbreakable armor") {}
|
||||
};
|
||||
|
||||
class CastVampiricBloodAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastVampiricBloodAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "vampiric blood") {}
|
||||
};
|
||||
|
||||
class CastMindFreezeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastMindFreezeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "mind freeze") {}
|
||||
};
|
||||
|
||||
class CastStrangulateAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastStrangulateAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "strangulate") {}
|
||||
};
|
||||
|
||||
class CastMindFreezeOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastMindFreezeOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "mind freeze") {}
|
||||
};
|
||||
|
||||
class CastRuneTapAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastRuneTapAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "rune tap") {}
|
||||
};
|
||||
|
||||
class CastBloodTapAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastBloodTapAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "blood tap") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
318
src/Ai/Class/Dk/DKAiObjectContext.cpp
Normal file
318
src/Ai/Class/Dk/DKAiObjectContext.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* 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 "DKAiObjectContext.h"
|
||||
|
||||
#include "BloodDKStrategy.h"
|
||||
#include "DKActions.h"
|
||||
#include "DKTriggers.h"
|
||||
#include "FrostDKStrategy.h"
|
||||
#include "GenericDKNonCombatStrategy.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PullStrategy.h"
|
||||
#include "UnholyDKStrategy.h"
|
||||
|
||||
class DeathKnightStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
DeathKnightStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &DeathKnightStrategyFactoryInternal::nc;
|
||||
creators["pull"] = &DeathKnightStrategyFactoryInternal::pull;
|
||||
creators["frost aoe"] = &DeathKnightStrategyFactoryInternal::frost_aoe;
|
||||
creators["unholy aoe"] = &DeathKnightStrategyFactoryInternal::unholy_aoe;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericDKNonCombatStrategy(botAI); }
|
||||
static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "icy touch"); }
|
||||
static Strategy* frost_aoe(PlayerbotAI* botAI) { return new FrostDKAoeStrategy(botAI); }
|
||||
static Strategy* unholy_aoe(PlayerbotAI* botAI) { return new UnholyDKAoeStrategy(botAI); }
|
||||
};
|
||||
|
||||
class DeathKnightCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
DeathKnightCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["tank"] = &DeathKnightCombatStrategyFactoryInternal::blood;
|
||||
creators["blood"] = &DeathKnightCombatStrategyFactoryInternal::blood;
|
||||
creators["frost"] = &DeathKnightCombatStrategyFactoryInternal::frost_dps;
|
||||
creators["unholy"] = &DeathKnightCombatStrategyFactoryInternal::unholy_dps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* frost_dps(PlayerbotAI* botAI) { return new FrostDKStrategy(botAI); }
|
||||
static Strategy* unholy_dps(PlayerbotAI* botAI) { return new UnholyDKStrategy(botAI); }
|
||||
static Strategy* tank(PlayerbotAI* botAI) { return new BloodDKStrategy(botAI); }
|
||||
static Strategy* blood(PlayerbotAI* botAI) { return new BloodDKStrategy(botAI); }
|
||||
};
|
||||
|
||||
class DeathKnightDKBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
DeathKnightDKBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bdps"] = &DeathKnightDKBuffStrategyFactoryInternal::bdps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bdps(PlayerbotAI* botAI) { return new DKBuffDpsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class DeathKnightTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
DeathKnightTriggerFactoryInternal()
|
||||
{
|
||||
creators["bone shield"] = &DeathKnightTriggerFactoryInternal::bone_shield;
|
||||
creators["pestilence glyph"] = &DeathKnightTriggerFactoryInternal::pestilence_glyph;
|
||||
creators["blood strike"] = &DeathKnightTriggerFactoryInternal::blood_strike;
|
||||
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
||||
creators["plague strike on attacker"] = &DeathKnightTriggerFactoryInternal::plague_strike_on_attacker;
|
||||
creators["icy touch"] = &DeathKnightTriggerFactoryInternal::icy_touch;
|
||||
creators["icy touch 3s"] = &DeathKnightTriggerFactoryInternal::icy_touch_3s;
|
||||
creators["dd cd and icy touch 3s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_icy_touch_3s;
|
||||
creators["death coil"] = &DeathKnightTriggerFactoryInternal::death_coil;
|
||||
creators["icy touch on attacker"] = &DeathKnightTriggerFactoryInternal::icy_touch_on_attacker;
|
||||
creators["improved icy talons"] = &DeathKnightTriggerFactoryInternal::improved_icy_talons;
|
||||
creators["plague strike"] = &DeathKnightTriggerFactoryInternal::plague_strike;
|
||||
creators["plague strike 3s"] = &DeathKnightTriggerFactoryInternal::plague_strike_3s;
|
||||
creators["dd cd and plague strike 3s"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_plague_strike_3s;
|
||||
creators["horn of winter"] = &DeathKnightTriggerFactoryInternal::horn_of_winter;
|
||||
creators["mind freeze"] = &DeathKnightTriggerFactoryInternal::mind_freeze;
|
||||
creators["mind freeze on enemy healer"] = &DeathKnightTriggerFactoryInternal::mind_freeze_on_enemy_healer;
|
||||
creators["strangulate"] = &DeathKnightTriggerFactoryInternal::strangulate;
|
||||
creators["strangulate on enemy healer"] = &DeathKnightTriggerFactoryInternal::strangulate_on_enemy_healer;
|
||||
creators["blood tap"] = &DeathKnightTriggerFactoryInternal::blood_tap;
|
||||
creators["raise dead"] = &DeathKnightTriggerFactoryInternal::raise_dead;
|
||||
creators["chains of ice"] = &DeathKnightTriggerFactoryInternal::chains_of_ice;
|
||||
creators["unbreakable armor"] = &DeathKnightTriggerFactoryInternal::unbreakable_armor;
|
||||
creators["high blood rune"] = &DeathKnightTriggerFactoryInternal::high_blood_rune;
|
||||
creators["high frost rune"] = &DeathKnightTriggerFactoryInternal::high_frost_rune;
|
||||
creators["high unholy rune"] = &DeathKnightTriggerFactoryInternal::high_unholy_rune;
|
||||
creators["no rune"] = &DeathKnightTriggerFactoryInternal::no_rune;
|
||||
creators["freezing fog"] = &DeathKnightTriggerFactoryInternal::freezing_fog;
|
||||
creators["no desolation"] = &DeathKnightTriggerFactoryInternal::no_desolation;
|
||||
creators["dd cd and no desolation"] = &DeathKnightTriggerFactoryInternal::dd_cd_and_no_desolation;
|
||||
creators["death and decay cooldown"] = &DeathKnightTriggerFactoryInternal::death_and_decay_cooldown;
|
||||
creators["army of the dead"] = &DeathKnightTriggerFactoryInternal::army_of_the_dead;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* bone_shield(PlayerbotAI* botAI) { return new BoneShieldTrigger(botAI); }
|
||||
static Trigger* pestilence_glyph(PlayerbotAI* botAI) { return new PestilenceGlyphTrigger(botAI); }
|
||||
static Trigger* blood_strike(PlayerbotAI* botAI) { return new BloodStrikeTrigger(botAI); }
|
||||
static Trigger* plague_strike(PlayerbotAI* botAI) { return new PlagueStrikeDebuffTrigger(botAI); }
|
||||
static Trigger* plague_strike_3s(PlayerbotAI* botAI) { return new PlagueStrike3sDebuffTrigger(botAI); }
|
||||
static Trigger* dd_cd_and_plague_strike_3s(PlayerbotAI* botAI)
|
||||
{
|
||||
return new TwoTriggers(botAI, "death and decay cooldown", "plague strike 3s");
|
||||
}
|
||||
static Trigger* plague_strike_on_attacker(PlayerbotAI* botAI)
|
||||
{
|
||||
return new PlagueStrikeDebuffOnAttackerTrigger(botAI);
|
||||
}
|
||||
static Trigger* icy_touch(PlayerbotAI* botAI) { return new IcyTouchDebuffTrigger(botAI); }
|
||||
static Trigger* icy_touch_3s(PlayerbotAI* botAI) { return new IcyTouch3sDebuffTrigger(botAI); }
|
||||
static Trigger* dd_cd_and_icy_touch_3s(PlayerbotAI* botAI)
|
||||
{
|
||||
return new TwoTriggers(botAI, "death and decay cooldown", "icy touch 3s");
|
||||
}
|
||||
static Trigger* death_coil(PlayerbotAI* botAI) { return new DeathCoilTrigger(botAI); }
|
||||
static Trigger* icy_touch_on_attacker(PlayerbotAI* botAI) { return new IcyTouchDebuffOnAttackerTrigger(botAI); }
|
||||
static Trigger* improved_icy_talons(PlayerbotAI* botAI) { return new ImprovedIcyTalonsTrigger(botAI); }
|
||||
static Trigger* horn_of_winter(PlayerbotAI* botAI) { return new HornOfWinterTrigger(botAI); }
|
||||
static Trigger* mind_freeze(PlayerbotAI* botAI) { return new MindFreezeInterruptSpellTrigger(botAI); }
|
||||
static Trigger* mind_freeze_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new MindFreezeOnEnemyHealerTrigger(botAI);
|
||||
}
|
||||
static Trigger* strangulate(PlayerbotAI* botAI) { return new StrangulateInterruptSpellTrigger(botAI); }
|
||||
static Trigger* strangulate_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new StrangulateOnEnemyHealerTrigger(botAI);
|
||||
}
|
||||
static Trigger* blood_tap(PlayerbotAI* botAI) { return new BloodTapTrigger(botAI); }
|
||||
static Trigger* raise_dead(PlayerbotAI* botAI) { return new RaiseDeadTrigger(botAI); }
|
||||
static Trigger* chains_of_ice(PlayerbotAI* botAI) { return new ChainsOfIceSnareTrigger(botAI); }
|
||||
static Trigger* unbreakable_armor(PlayerbotAI* botAI) { return new UnbreakableArmorTrigger(botAI); }
|
||||
static Trigger* high_blood_rune(PlayerbotAI* botAI) { return new HighBloodRuneTrigger(botAI); }
|
||||
static Trigger* high_frost_rune(PlayerbotAI* botAI) { return new HighFrostRuneTrigger(botAI); }
|
||||
static Trigger* high_unholy_rune(PlayerbotAI* botAI) { return new HighUnholyRuneTrigger(botAI); }
|
||||
static Trigger* no_rune(PlayerbotAI* botAI) { return new NoRuneTrigger(botAI); }
|
||||
static Trigger* freezing_fog(PlayerbotAI* botAI) { return new FreezingFogTrigger(botAI); }
|
||||
static Trigger* no_desolation(PlayerbotAI* botAI) { return new DesolationTrigger(botAI); }
|
||||
static Trigger* dd_cd_and_no_desolation(PlayerbotAI* botAI)
|
||||
{
|
||||
return new TwoTriggers(botAI, "death and decay cooldown", "no desolation");
|
||||
}
|
||||
static Trigger* death_and_decay_cooldown(PlayerbotAI* botAI) { return new DeathAndDecayCooldownTrigger(botAI); }
|
||||
static Trigger* army_of_the_dead(PlayerbotAI* botAI) { return new ArmyOfTheDeadTrigger(botAI); }
|
||||
};
|
||||
|
||||
class DeathKnightAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
DeathKnightAiObjectContextInternal()
|
||||
{
|
||||
// Unholy
|
||||
creators["bone shield"] = &DeathKnightAiObjectContextInternal::bone_shield;
|
||||
creators["plague strike"] = &DeathKnightAiObjectContextInternal::plague_strike;
|
||||
creators["plague strike on attacker"] = &DeathKnightAiObjectContextInternal::plague_strike_on_attacker;
|
||||
creators["death grip"] = &DeathKnightAiObjectContextInternal::death_grip;
|
||||
creators["death coil"] = &DeathKnightAiObjectContextInternal::death_coil;
|
||||
creators["death strike"] = &DeathKnightAiObjectContextInternal::death_strike;
|
||||
creators["unholy blight"] = &DeathKnightAiObjectContextInternal::unholy_blight;
|
||||
creators["scourge strike"] = &DeathKnightAiObjectContextInternal::scourge_strike;
|
||||
creators["death and decay"] = &DeathKnightAiObjectContextInternal::death_and_decay;
|
||||
creators["unholy presence"] = &DeathKnightAiObjectContextInternal::unholy_presence;
|
||||
creators["raise dead"] = &DeathKnightAiObjectContextInternal::raise_dead;
|
||||
creators["army of the dead"] = &DeathKnightAiObjectContextInternal::army_of_the_dead;
|
||||
creators["summon gargoyle"] = &DeathKnightAiObjectContextInternal::summon_gargoyle;
|
||||
creators["anti magic shell"] = &DeathKnightAiObjectContextInternal::anti_magic_shell;
|
||||
creators["anti magic zone"] = &DeathKnightAiObjectContextInternal::anti_magic_zone;
|
||||
creators["ghoul frenzy"] = &DeathKnightAiObjectContextInternal::ghoul_frenzy;
|
||||
creators["corpse explosion"] = &DeathKnightAiObjectContextInternal::corpse_explosion;
|
||||
// Frost
|
||||
creators["icy touch"] = &DeathKnightAiObjectContextInternal::icy_touch;
|
||||
creators["icy touch on attacker"] = &DeathKnightAiObjectContextInternal::icy_touch_on_attacker;
|
||||
creators["obliterate"] = &DeathKnightAiObjectContextInternal::obliterate;
|
||||
creators["howling blast"] = &DeathKnightAiObjectContextInternal::howling_blast;
|
||||
creators["frost strike"] = &DeathKnightAiObjectContextInternal::frost_strike;
|
||||
creators["chains of ice"] = &DeathKnightAiObjectContextInternal::chains_of_ice;
|
||||
creators["rune strike"] = &DeathKnightAiObjectContextInternal::rune_strike;
|
||||
// creators["icy clutch"] = &DeathKnightAiObjectContextInternal::icy_clutch;
|
||||
creators["horn of winter"] = &DeathKnightAiObjectContextInternal::horn_of_winter;
|
||||
creators["killing machine"] = &DeathKnightAiObjectContextInternal::killing_machine;
|
||||
creators["frost presence"] = &DeathKnightAiObjectContextInternal::frost_presence;
|
||||
creators["deathchill"] = &DeathKnightAiObjectContextInternal::deathchill;
|
||||
creators["icebound fortitude"] = &DeathKnightAiObjectContextInternal::icebound_fortitude;
|
||||
creators["mind freeze"] = &DeathKnightAiObjectContextInternal::mind_freeze;
|
||||
creators["empower rune weapon"] = &DeathKnightAiObjectContextInternal::empower_rune_weapon;
|
||||
creators["hungering cold"] = &DeathKnightAiObjectContextInternal::hungering_cold;
|
||||
creators["unbreakable armor"] = &DeathKnightAiObjectContextInternal::unbreakable_armor;
|
||||
creators["improved icy talons"] = &DeathKnightAiObjectContextInternal::improved_icy_talons;
|
||||
// blood
|
||||
creators["blood strike"] = &DeathKnightAiObjectContextInternal::blood_strike;
|
||||
creators["blood tap"] = &DeathKnightAiObjectContextInternal::blood_tap;
|
||||
creators["pestilence"] = &DeathKnightAiObjectContextInternal::pestilence;
|
||||
creators["strangulate"] = &DeathKnightAiObjectContextInternal::strangulate;
|
||||
creators["blood boil"] = &DeathKnightAiObjectContextInternal::blood_boil;
|
||||
creators["heart strike"] = &DeathKnightAiObjectContextInternal::heart_strike;
|
||||
creators["mark of_blood"] = &DeathKnightAiObjectContextInternal::mark_of_blood;
|
||||
creators["blood presence"] = &DeathKnightAiObjectContextInternal::blood_presence;
|
||||
creators["rune tap"] = &DeathKnightAiObjectContextInternal::rune_tap;
|
||||
creators["vampiric blood"] = &DeathKnightAiObjectContextInternal::vampiric_blood;
|
||||
creators["death pact"] = &DeathKnightAiObjectContextInternal::death_pact;
|
||||
creators["death rune_mastery"] = &DeathKnightAiObjectContextInternal::death_rune_mastery;
|
||||
// creators["hysteria"] = &DeathKnightAiObjectContextInternal::hysteria;
|
||||
creators["dancing rune weapon"] = &DeathKnightAiObjectContextInternal::dancing_rune_weapon;
|
||||
creators["dark command"] = &DeathKnightAiObjectContextInternal::dark_command;
|
||||
}
|
||||
|
||||
private:
|
||||
// Unholy
|
||||
static Action* bone_shield(PlayerbotAI* botAI) { return new CastBoneShieldAction(botAI); }
|
||||
static Action* plague_strike(PlayerbotAI* botAI) { return new CastPlagueStrikeAction(botAI); }
|
||||
static Action* plague_strike_on_attacker(PlayerbotAI* botAI) { return new CastPlagueStrikeOnAttackerAction(botAI); }
|
||||
static Action* death_grip(PlayerbotAI* botAI) { return new CastDeathGripAction(botAI); }
|
||||
static Action* death_coil(PlayerbotAI* botAI) { return new CastDeathCoilAction(botAI); }
|
||||
static Action* death_strike(PlayerbotAI* botAI) { return new CastDeathStrikeAction(botAI); }
|
||||
static Action* unholy_blight(PlayerbotAI* botAI) { return new CastUnholyBlightAction(botAI); }
|
||||
static Action* scourge_strike(PlayerbotAI* botAI) { return new CastScourgeStrikeAction(botAI); }
|
||||
static Action* death_and_decay(PlayerbotAI* botAI) { return new CastDeathAndDecayAction(botAI); }
|
||||
static Action* unholy_presence(PlayerbotAI* botAI) { return new CastUnholyPresenceAction(botAI); }
|
||||
static Action* raise_dead(PlayerbotAI* botAI) { return new CastRaiseDeadAction(botAI); }
|
||||
static Action* army_of_the_dead(PlayerbotAI* botAI) { return new CastArmyOfTheDeadAction(botAI); }
|
||||
static Action* summon_gargoyle(PlayerbotAI* botAI) { return new CastSummonGargoyleAction(botAI); }
|
||||
static Action* anti_magic_shell(PlayerbotAI* botAI) { return new CastAntiMagicShellAction(botAI); }
|
||||
static Action* anti_magic_zone(PlayerbotAI* botAI) { return new CastAntiMagicZoneAction(botAI); }
|
||||
static Action* ghoul_frenzy(PlayerbotAI* botAI) { return new CastGhoulFrenzyAction(botAI); }
|
||||
static Action* corpse_explosion(PlayerbotAI* botAI) { return new CastCorpseExplosionAction(botAI); }
|
||||
// Frost
|
||||
static Action* icy_touch(PlayerbotAI* botAI) { return new CastIcyTouchAction(botAI); }
|
||||
static Action* icy_touch_on_attacker(PlayerbotAI* botAI) { return new CastIcyTouchOnAttackerAction(botAI); }
|
||||
static Action* obliterate(PlayerbotAI* botAI) { return new CastObliterateAction(botAI); }
|
||||
static Action* howling_blast(PlayerbotAI* botAI) { return new CastHowlingBlastAction(botAI); }
|
||||
static Action* frost_strike(PlayerbotAI* botAI) { return new CastFrostStrikeAction(botAI); }
|
||||
static Action* chains_of_ice(PlayerbotAI* botAI) { return new CastChainsOfIceAction(botAI); }
|
||||
static Action* rune_strike(PlayerbotAI* botAI) { return new CastRuneStrikeAction(botAI); }
|
||||
// static Action* icy_clutch(PlayerbotAI* botAI) { return new CastIcyClutchAction(botAI); }
|
||||
static Action* horn_of_winter(PlayerbotAI* botAI) { return new CastHornOfWinterAction(botAI); }
|
||||
static Action* killing_machine(PlayerbotAI* botAI) { return new CastKillingMachineAction(botAI); }
|
||||
static Action* frost_presence(PlayerbotAI* botAI) { return new CastFrostPresenceAction(botAI); }
|
||||
static Action* deathchill(PlayerbotAI* botAI) { return new CastDeathchillAction(botAI); }
|
||||
static Action* icebound_fortitude(PlayerbotAI* botAI) { return new CastIceboundFortitudeAction(botAI); }
|
||||
static Action* mind_freeze(PlayerbotAI* botAI) { return new CastMindFreezeAction(botAI); }
|
||||
static Action* empower_rune_weapon(PlayerbotAI* botAI) { return new CastEmpowerRuneWeaponAction(botAI); }
|
||||
static Action* hungering_cold(PlayerbotAI* botAI) { return new CastHungeringColdAction(botAI); }
|
||||
static Action* unbreakable_armor(PlayerbotAI* botAI) { return new CastUnbreakableArmorAction(botAI); }
|
||||
static Action* improved_icy_talons(PlayerbotAI* botAI) { return new CastImprovedIcyTalonsAction(botAI); }
|
||||
// blood
|
||||
static Action* blood_strike(PlayerbotAI* botAI) { return new CastBloodStrikeAction(botAI); }
|
||||
static Action* blood_tap(PlayerbotAI* botAI) { return new CastBloodTapAction(botAI); }
|
||||
static Action* pestilence(PlayerbotAI* botAI) { return new CastPestilenceAction(botAI); }
|
||||
static Action* strangulate(PlayerbotAI* botAI) { return new CastStrangulateAction(botAI); }
|
||||
static Action* blood_boil(PlayerbotAI* botAI) { return new CastBloodBoilAction(botAI); }
|
||||
static Action* heart_strike(PlayerbotAI* botAI) { return new CastHeartStrikeAction(botAI); }
|
||||
static Action* mark_of_blood(PlayerbotAI* botAI) { return new CastMarkOfBloodAction(botAI); }
|
||||
static Action* blood_presence(PlayerbotAI* botAI) { return new CastBloodPresenceAction(botAI); }
|
||||
static Action* rune_tap(PlayerbotAI* botAI) { return new CastRuneTapAction(botAI); }
|
||||
static Action* vampiric_blood(PlayerbotAI* botAI) { return new CastVampiricBloodAction(botAI); }
|
||||
static Action* death_pact(PlayerbotAI* botAI) { return new CastDeathPactAction(botAI); }
|
||||
static Action* death_rune_mastery(PlayerbotAI* botAI) { return new CastDeathRuneMasteryAction(botAI); }
|
||||
// static Action* hysteria(PlayerbotAI* botAI) { return new CastHysteriaAction(botAI); }
|
||||
static Action* dancing_rune_weapon(PlayerbotAI* botAI) { return new CastDancingRuneWeaponAction(botAI); }
|
||||
static Action* dark_command(PlayerbotAI* botAI) { return new CastDarkCommandAction(botAI); }
|
||||
static Action* mind_freeze_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastMindFreezeOnEnemyHealerAction(botAI);
|
||||
}
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> DKAiObjectContext::sharedStrategyContexts;
|
||||
SharedNamedObjectContextList<Action> DKAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> DKAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> DKAiObjectContext::sharedValueContexts;
|
||||
|
||||
DKAiObjectContext::DKAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void DKAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void DKAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new DeathKnightStrategyFactoryInternal());
|
||||
strategyContexts.Add(new DeathKnightCombatStrategyFactoryInternal());
|
||||
strategyContexts.Add(new DeathKnightDKBuffStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void DKAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new DeathKnightAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void DKAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new DeathKnightTriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void DKAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Dk/DKAiObjectContext.h
Normal file
30
src/Ai/Class/Dk/DKAiObjectContext.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_DKAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_DKAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class DKAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
DKAiObjectContext(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
|
||||
165
src/Ai/Class/Dk/Strategy/BloodDKStrategy.cpp
Normal file
165
src/Ai/Class/Dk/Strategy/BloodDKStrategy.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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 "BloodDKStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class BloodDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
BloodDKStrategyActionNodeFactory()
|
||||
{
|
||||
creators["rune strike"] = &rune_strike;
|
||||
creators["heart strike"] = &heart_strike;
|
||||
creators["death strike"] = &death_strike;
|
||||
creators["icy touch"] = &icy_touch;
|
||||
creators["dark command"] = &dark_command;
|
||||
creators["taunt spell"] = &dark_command;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* rune_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rune strike",
|
||||
{
|
||||
NextAction("frost presence")
|
||||
},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* icy_touch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"icy touch",
|
||||
{
|
||||
NextAction("frost presence")
|
||||
},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* heart_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"heart strike",
|
||||
{
|
||||
NextAction("frost presence")
|
||||
},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* death_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"death strike",
|
||||
{
|
||||
NextAction("frost presence")
|
||||
},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* dark_command([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"dark command",
|
||||
{
|
||||
NextAction("frost presence")
|
||||
},
|
||||
/*A*/ {
|
||||
NextAction("death grip")
|
||||
},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BloodDKStrategy::BloodDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new BloodDKStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> BloodDKStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("rune strike", ACTION_DEFAULT + 0.8f),
|
||||
NextAction("icy touch", ACTION_DEFAULT + 0.7f),
|
||||
NextAction("heart strike", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("blood strike", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("dancing rune weapon", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("death coil", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("plague strike", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("horn of winter", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void BloodDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDKStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"rune strike",
|
||||
{
|
||||
NextAction("rune strike", ACTION_NORMAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"blood tap",
|
||||
{
|
||||
NextAction("blood tap", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lose aggro",
|
||||
{
|
||||
NextAction("dark command", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("army of the dead", ACTION_HIGH + 4),
|
||||
NextAction("death strike", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"critical health",
|
||||
{
|
||||
NextAction("vampiric blood", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"icy touch",
|
||||
{
|
||||
NextAction("icy touch", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"plague strike",
|
||||
{
|
||||
NextAction("plague strike", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Dk/Strategy/BloodDKStrategy.h
Normal file
24
src/Ai/Class/Dk/Strategy/BloodDKStrategy.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_BLOODDKSTRATEGY_H
|
||||
#define _PLAYERBOT_BLOODDKSTRATEGY_H
|
||||
|
||||
#include "GenericDKStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class BloodDKStrategy : public GenericDKStrategy
|
||||
{
|
||||
public:
|
||||
BloodDKStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "blood"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_TANK | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
169
src/Ai/Class/Dk/Strategy/FrostDKStrategy.cpp
Normal file
169
src/Ai/Class/Dk/Strategy/FrostDKStrategy.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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 "FrostDKStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class FrostDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FrostDKStrategyActionNodeFactory()
|
||||
{
|
||||
creators["icy touch"] = &icy_touch;
|
||||
creators["obliterate"] = &obliterate;
|
||||
creators["howling blast"] = &howling_blast;
|
||||
creators["frost strike"] = &frost_strike;
|
||||
creators["rune strike"] = &rune_strike;
|
||||
creators["unbreakable armor"] = &unbreakable_armor;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* icy_touch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"icy touch",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* obliterate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"obliterate",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rune_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rune strike",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* frost_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"frost strike",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* howling_blast([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"howling blast",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* unbreakable_armor([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"unbreakable armor",
|
||||
/*P*/ { NextAction("blood tap") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
FrostDKStrategy::FrostDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FrostDKStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> FrostDKStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("obliterate", ACTION_DEFAULT + 0.7f),
|
||||
NextAction("frost strike", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("empower rune weapon", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("horn of winter", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void FrostDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDKStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"unbreakable armor",
|
||||
{
|
||||
NextAction("unbreakable armor", ACTION_DEFAULT + 0.6f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"freezing fog",
|
||||
{
|
||||
NextAction("howling blast", ACTION_DEFAULT + 0.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"high blood rune",
|
||||
{
|
||||
NextAction("blood strike", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"army of the dead",
|
||||
{
|
||||
NextAction("army of the dead", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"icy touch",
|
||||
{
|
||||
NextAction("icy touch", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"plague strike",
|
||||
{
|
||||
NextAction("plague strike", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void FrostDKAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("howling blast", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
33
src/Ai/Class/Dk/Strategy/FrostDKStrategy.h
Normal file
33
src/Ai/Class/Dk/Strategy/FrostDKStrategy.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_FROSTDKSTRATEGY_H
|
||||
#define _PLAYERBOT_FROSTDKSTRATEGY_H
|
||||
|
||||
#include "GenericDKStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class FrostDKStrategy : public GenericDKStrategy
|
||||
{
|
||||
public:
|
||||
FrostDKStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "frost"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
class FrostDKAoeStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
FrostDKAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "frost aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
61
src/Ai/Class/Dk/Strategy/GenericDKNonCombatStrategy.cpp
Normal file
61
src/Ai/Class/Dk/Strategy/GenericDKNonCombatStrategy.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 "GenericDKNonCombatStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class GenericDKNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericDKNonCombatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["bone shield"] = &bone_shield;
|
||||
creators["horn of winter"] = &horn_of_winter;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* bone_shield([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("bone shield",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* horn_of_winter([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("horn of winter",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericDKNonCombatStrategy::GenericDKNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericDKNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericDKNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("no pet", { NextAction("raise dead", ACTION_NORMAL + 1) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("horn of winter", { NextAction("horn of winter", 21.0f) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("bone shield", { NextAction("bone shield", 21.0f) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("has pet", { NextAction("toggle pet spell", 60.0f) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", { NextAction("set pet stance", 60.0f) }));
|
||||
}
|
||||
|
||||
void DKBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
|
||||
}
|
||||
32
src/Ai/Class/Dk/Strategy/GenericDKNonCombatStrategy.h
Normal file
32
src/Ai/Class/Dk/Strategy/GenericDKNonCombatStrategy.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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_GENERICDKNONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICDKNONCOMBATSTRATEGY_H
|
||||
|
||||
#include "GenericDKStrategy.h"
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericDKNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericDKNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "nc"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class DKBuffDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
DKBuffDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bdps"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
193
src/Ai/Class/Dk/Strategy/GenericDKStrategy.cpp
Normal file
193
src/Ai/Class/Dk/Strategy/GenericDKStrategy.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#/*
|
||||
* 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 "GenericDKStrategy.h"
|
||||
|
||||
#include "DKAiObjectContext.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class GenericDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericDKStrategyActionNodeFactory()
|
||||
{
|
||||
// blood
|
||||
// creators["rune tap"] = &rune_tap; cd
|
||||
// creators["vampiric blood"] = &vampiric_blood;
|
||||
// creators["death pact"] = &death_pact;
|
||||
// creators["hysteria"] = &hysteria; boost party
|
||||
// creators["dancing rune weapon"] = &dancing_rune_weapon; //cd
|
||||
// creators["dark command"] = &dark_command; taunt
|
||||
|
||||
// frost
|
||||
// creators["chains of ice"] = &chains_of_ice;
|
||||
// creators["icy clutch"] = &icy_clutch;
|
||||
creators["horn of winter"] = &horn_of_winter;
|
||||
creators["killing machine"] = &killing_machine; // buff
|
||||
// creators["deathchill"] = &deathchill; //boost
|
||||
creators["icebound fortitude"] = &icebound_fortitude;
|
||||
// creators["mind freeze"] = &mind_freeze; interrupt
|
||||
// creators["empower rune weapon"] = &empower_rune_weapon; boost
|
||||
// creators["hungering cold"] = &hungering_cold; snare
|
||||
// creators["unbreakable armor"] = &unbreakable_armor; boost +cd
|
||||
// creators["improved icy talons"] = &improved_icy_talons; boost party
|
||||
|
||||
// unholy
|
||||
creators["death and decay"] = &death_and_decay;
|
||||
// creators["raise dead"] = &raise_dead;
|
||||
// creators["army of the dead"] = &army of the dead;
|
||||
// creators["summon gargoyle"] = &army of the dead;
|
||||
// creators["anti magic shell"] = &anti_magic_shell; cd
|
||||
creators["anti magic zone"] = &anti_magic_zone;
|
||||
// creators["ghoul frenzy"] = &ghoul_frenzy;
|
||||
creators["corpse explosion"] = &corpse_explosion;
|
||||
creators["bone shield"] = &bone_shield;
|
||||
creators["heart strike"] = &heart_strike;
|
||||
creators["death grip"] = &death_grip;
|
||||
creators["plague strike"] = &plague_strike;
|
||||
creators["pestilence"] = &pestilence;
|
||||
creators["icy touch"] = &icy_touch;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* death_coil([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("death coil",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* death_grip([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("death grip",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("icy touch") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* plague_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("plague strike",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* icy_touch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("icy touch",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* heart_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("heart strike",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* pestilence([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("pestilence",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* horn_of_winter([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("horn of winter",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* bone_shield([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("bone shield",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* killing_machine([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("killing machine",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("improved icy talons") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* corpse_explosion([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("corpse explosion",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* death_and_decay([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("death and decay",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* anti_magic_zone([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("anti magic zone",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("anti magic shell") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* icebound_fortitude([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("icebound fortitude",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericDKStrategy::GenericDKStrategy(PlayerbotAI* botAI) : MeleeCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericDKStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
MeleeCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("no pet", { NextAction("raise dead", ACTION_NORMAL + 5) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("has pet", { NextAction("toggle pet spell", 60.0f) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", { NextAction("set pet stance", 60.0f) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("mind freeze", { NextAction("mind freeze", ACTION_HIGH + 1) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("mind freeze on enemy healer",
|
||||
{ NextAction("mind freeze on enemy healer", ACTION_HIGH + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"horn of winter", { NextAction("horn of winter", ACTION_NORMAL + 1) }));
|
||||
triggers.push_back(new TriggerNode("critical health",
|
||||
{ NextAction("death pact", ACTION_HIGH + 5) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("low health", { NextAction("icebound fortitude", ACTION_HIGH + 5),
|
||||
NextAction("rune tap", ACTION_HIGH + 4) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe", { NextAction("death and decay", ACTION_HIGH + 9),
|
||||
NextAction("pestilence", ACTION_NORMAL + 4),
|
||||
NextAction("blood boil", ACTION_NORMAL + 3) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("pestilence glyph", { NextAction("pestilence", ACTION_HIGH + 9) }));
|
||||
}
|
||||
22
src/Ai/Class/Dk/Strategy/GenericDKStrategy.h
Normal file
22
src/Ai/Class/Dk/Strategy/GenericDKStrategy.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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_GENERICDKSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICDKSTRATEGY_H
|
||||
|
||||
#include "MeleeCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericDKStrategy : public MeleeCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericDKStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "DK"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
192
src/Ai/Class/Dk/Strategy/UnholyDKStrategy.cpp
Normal file
192
src/Ai/Class/Dk/Strategy/UnholyDKStrategy.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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 "UnholyDKStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class UnholyDKStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
UnholyDKStrategyActionNodeFactory()
|
||||
{
|
||||
creators["death strike"] = &death_strike;
|
||||
creators["scourge strike"] = &scourge_strike;
|
||||
creators["ghoul frenzy"] = &ghoul_frenzy;
|
||||
creators["corpse explosion"] = &corpse_explosion;
|
||||
creators["icy touch"] = &icy_touch;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* death_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"death strike",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* ghoul_frenzy([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"ghoul frenzy",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* corpse_explosion([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"corpse explosion",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* scourge_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"scourge strike",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* icy_touch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"icy touch",
|
||||
/*P*/ { NextAction("blood presence") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
UnholyDKStrategy::UnholyDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new UnholyDKStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> UnholyDKStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("death and decay", ACTION_HIGH + 5),
|
||||
NextAction("summon gargoyle", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("horn of winter", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("death coil", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void UnholyDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDKStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"death and decay cooldown",
|
||||
{
|
||||
NextAction("ghoul frenzy", ACTION_DEFAULT + 0.9f),
|
||||
NextAction("scourge strike", ACTION_DEFAULT + 0.8f),
|
||||
NextAction("icy touch", ACTION_DEFAULT + 0.7f),
|
||||
NextAction("blood strike", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("plague strike", ACTION_DEFAULT + 0.5f),
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"dd cd and no desolation",
|
||||
{
|
||||
NextAction("blood strike", ACTION_DEFAULT + 0.75f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"high frost rune",
|
||||
{
|
||||
NextAction("icy touch", ACTION_NORMAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"high blood rune",
|
||||
{
|
||||
NextAction("blood strike", ACTION_NORMAL + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"high unholy rune",
|
||||
{
|
||||
NextAction("plague strike", ACTION_NORMAL + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode("dd cd and plague strike 3s",
|
||||
{
|
||||
NextAction("plague strike", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode("dd cd and icy touch 3s",
|
||||
{
|
||||
NextAction("icy touch", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode("no rune",
|
||||
{
|
||||
NextAction("empower rune weapon", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"army of the dead",
|
||||
{
|
||||
NextAction("army of the dead", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode("bone shield",
|
||||
{
|
||||
NextAction("bone shield", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void UnholyDKAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"loot available",
|
||||
{
|
||||
NextAction("corpse explosion", ACTION_NORMAL + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("death and decay", ACTION_NORMAL + 3),
|
||||
NextAction("corpse explosion", ACTION_NORMAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
33
src/Ai/Class/Dk/Strategy/UnholyDKStrategy.h
Normal file
33
src/Ai/Class/Dk/Strategy/UnholyDKStrategy.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_UNHOLYDKSTRATEGY_H
|
||||
#define _PLAYERBOT_UNHOLYDKSTRATEGY_H
|
||||
|
||||
#include "GenericDKStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class UnholyDKStrategy : public GenericDKStrategy
|
||||
{
|
||||
public:
|
||||
UnholyDKStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "unholy"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
class UnholyDKAoeStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
UnholyDKAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "unholy aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
78
src/Ai/Class/Dk/Trigger/DKTriggers.cpp
Normal file
78
src/Ai/Class/Dk/Trigger/DKTriggers.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 "DKTriggers.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "GenericTriggers.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
bool DKPresenceTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
return !botAI->HasAura("blood presence", target) && !botAI->HasAura("unholy presence", target) &&
|
||||
!botAI->HasAura("frost presence", target);
|
||||
}
|
||||
|
||||
bool PestilenceGlyphTrigger::IsActive()
|
||||
{
|
||||
if (!SpellTrigger::IsActive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!bot->HasAura(63334))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Aura* blood_plague = botAI->GetAura("blood plague", GetTarget(), true, true);
|
||||
Aura* frost_fever = botAI->GetAura("frost fever", GetTarget(), true, true);
|
||||
if ((blood_plague && blood_plague->GetDuration() <= 3000) || (frost_fever && frost_fever->GetDuration() <= 3000))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Based on runeSlotTypes
|
||||
bool HighBloodRuneTrigger::IsActive()
|
||||
{
|
||||
return bot->GetRuneCooldown(0) <= 2000 && bot->GetRuneCooldown(1) <= 2000;
|
||||
}
|
||||
|
||||
bool HighFrostRuneTrigger::IsActive()
|
||||
{
|
||||
return bot->GetRuneCooldown(4) <= 2000 && bot->GetRuneCooldown(5) <= 2000;
|
||||
}
|
||||
|
||||
bool HighUnholyRuneTrigger::IsActive()
|
||||
{
|
||||
return bot->GetRuneCooldown(2) <= 2000 && bot->GetRuneCooldown(3) <= 2000;
|
||||
}
|
||||
|
||||
bool NoRuneTrigger::IsActive()
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
if (!bot->GetRuneCooldown(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DesolationTrigger::IsActive()
|
||||
{
|
||||
return bot->HasAura(66817) && BuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
bool DeathAndDecayCooldownTrigger::IsActive()
|
||||
{
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", name);
|
||||
if (!spellId)
|
||||
return true;
|
||||
|
||||
return bot->GetSpellCooldownDelay(spellId) >= 2000;
|
||||
}
|
||||
201
src/Ai/Class/Dk/Trigger/DKTriggers.h
Normal file
201
src/Ai/Class/Dk/Trigger/DKTriggers.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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_DKTRIGGERS_H
|
||||
#define _PLAYERBOT_DKTRIGGERS_H
|
||||
|
||||
#include "GenericTriggers.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
BUFF_TRIGGER(HornOfWinterTrigger, "horn of winter");
|
||||
BUFF_TRIGGER(BoneShieldTrigger, "bone shield");
|
||||
BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons");
|
||||
// DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "blood plague");
|
||||
class PlagueStrikeDebuffTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
PlagueStrikeDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f) {}
|
||||
};
|
||||
|
||||
class PlagueStrike3sDebuffTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
PlagueStrike3sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood plague", 1, true, .0f, 3000) {}
|
||||
};
|
||||
|
||||
// DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever");
|
||||
class IcyTouchDebuffTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
IcyTouchDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f) {}
|
||||
};
|
||||
|
||||
class IcyTouch3sDebuffTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
IcyTouch3sDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost fever", 1, true, .0f, 3000) {}
|
||||
};
|
||||
|
||||
BUFF_TRIGGER(UnbreakableArmorTrigger, "unbreakable armor");
|
||||
class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
|
||||
{
|
||||
public:
|
||||
PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI)
|
||||
: DebuffOnMeleeAttackerTrigger(botAI, "blood plague", true, .0f)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class IcyTouchDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
|
||||
{
|
||||
public:
|
||||
IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "frost fever", true, .0f)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class DKPresenceTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
DKPresenceTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "blood presence") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class BloodTapTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
BloodTapTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "blood tap") {}
|
||||
};
|
||||
|
||||
class RaiseDeadTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
RaiseDeadTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "raise dead") {}
|
||||
};
|
||||
|
||||
class RuneStrikeTrigger : public SpellCanBeCastTrigger
|
||||
{
|
||||
public:
|
||||
RuneStrikeTrigger(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, "rune strike") {}
|
||||
};
|
||||
|
||||
class DeathCoilTrigger : public SpellCanBeCastTrigger
|
||||
{
|
||||
public:
|
||||
DeathCoilTrigger(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, "death coil") {}
|
||||
};
|
||||
|
||||
class PestilenceGlyphTrigger : public SpellTrigger
|
||||
{
|
||||
public:
|
||||
PestilenceGlyphTrigger(PlayerbotAI* botAI) : SpellTrigger(botAI, "pestilence") {}
|
||||
virtual bool IsActive() override;
|
||||
};
|
||||
|
||||
class BloodStrikeTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
BloodStrikeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood strike", 1, true) {}
|
||||
};
|
||||
|
||||
class HowlingBlastTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
HowlingBlastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "howling blast", 1, true) {}
|
||||
};
|
||||
|
||||
class MindFreezeInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
MindFreezeInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "mind freeze") {}
|
||||
};
|
||||
|
||||
class StrangulateInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
StrangulateInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "strangulate") {}
|
||||
};
|
||||
|
||||
class KillingMachineTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
KillingMachineTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "killing machine") {}
|
||||
};
|
||||
|
||||
class MindFreezeOnEnemyHealerTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
MindFreezeOnEnemyHealerTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "mind freeze") {}
|
||||
};
|
||||
|
||||
class ChainsOfIceSnareTrigger : public SnareTargetTrigger
|
||||
{
|
||||
public:
|
||||
ChainsOfIceSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "chains of ice") {}
|
||||
};
|
||||
|
||||
class StrangulateOnEnemyHealerTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
StrangulateOnEnemyHealerTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "strangulate") {}
|
||||
};
|
||||
|
||||
class HighBloodRuneTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
HighBloodRuneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "high blood rune") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HighFrostRuneTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
HighFrostRuneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "high frost rune") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HighUnholyRuneTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
HighUnholyRuneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "high unholy rune") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoRuneTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoRuneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no rune") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FreezingFogTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
FreezingFogTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "freezing fog") {}
|
||||
};
|
||||
|
||||
class DesolationTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
DesolationTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "desolation", 1, false, true, 10000) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class DeathAndDecayCooldownTrigger : public SpellCooldownTrigger
|
||||
{
|
||||
public:
|
||||
DeathAndDecayCooldownTrigger(PlayerbotAI* botAI) : SpellCooldownTrigger(botAI, "death and decay") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class ArmyOfTheDeadTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
ArmyOfTheDeadTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "army of the dead") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
110
src/Ai/Class/Druid/Action/DruidActions.cpp
Normal file
110
src/Ai/Class/Druid/Action/DruidActions.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 "DruidActions.h"
|
||||
|
||||
#include "Event.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "AoeValues.h"
|
||||
#include "TargetValue.h"
|
||||
|
||||
std::vector<NextAction> CastAbolishPoisonAction::getAlternatives()
|
||||
{
|
||||
return NextAction::merge({ NextAction("cure poison") },
|
||||
CastSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastAbolishPoisonOnPartyAction::getAlternatives()
|
||||
{
|
||||
return NextAction::merge({ NextAction("cure poison on party") },
|
||||
CastSpellAction::getPrerequisites());
|
||||
}
|
||||
|
||||
Value<Unit*>* CastEntanglingRootsCcAction::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>("cc target", "entangling roots");
|
||||
}
|
||||
|
||||
bool CastEntanglingRootsCcAction::Execute(Event event) { return botAI->CastSpell("entangling roots", GetTarget()); }
|
||||
|
||||
Value<Unit*>* CastHibernateCcAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", "hibernate"); }
|
||||
|
||||
bool CastHibernateCcAction::Execute(Event event) { return botAI->CastSpell("hibernate", GetTarget()); }
|
||||
bool CastStarfallAction::isUseful()
|
||||
{
|
||||
if (!CastSpellAction::isUseful())
|
||||
return false;
|
||||
|
||||
// Avoid breaking CC
|
||||
WorldLocation aoePos = *context->GetValue<WorldLocation>("aoe position");
|
||||
Unit* ccTarget = context->GetValue<Unit*>("current cc target")->Get();
|
||||
if (ccTarget && ccTarget->IsAlive())
|
||||
{
|
||||
float dist2d = sServerFacade->GetDistance2d(ccTarget, aoePos.GetPositionX(), aoePos.GetPositionY());
|
||||
if (sServerFacade->IsDistanceLessOrEqualThan(dist2d, sPlayerbotAIConfig->aoeRadius))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid single-target usage on initial pull
|
||||
uint8 aoeCount = *context->GetValue<uint8>("aoe count");
|
||||
if (aoeCount < 2)
|
||||
{
|
||||
Unit* target = context->GetValue<Unit*>("current target")->Get();
|
||||
if (!target || (!botAI->HasAura("moonfire", target) && !botAI->HasAura("insect swarm", target)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastReviveAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("caster form") },
|
||||
ResurrectPartyMemberAction::getPrerequisites());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastRebirthAction::getPrerequisites()
|
||||
{
|
||||
return NextAction::merge({ NextAction("caster form") },
|
||||
ResurrectPartyMemberAction::getPrerequisites());
|
||||
}
|
||||
|
||||
bool CastRebirthAction::isUseful()
|
||||
{
|
||||
return CastSpellAction::isUseful() &&
|
||||
AI_VALUE2(float, "distance", GetTargetName()) <= sPlayerbotAIConfig->spellDistance;
|
||||
}
|
||||
|
||||
Unit* CastRejuvenationOnNotFullAction::GetTarget()
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
MinValueCalculator calc(100);
|
||||
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* player = gref->GetSource();
|
||||
if (!player)
|
||||
continue;
|
||||
if (player->isDead() || player->IsFullHealth())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (botAI->HasAura("rejuvenation", player))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
calc.probe(player->GetHealthPct(), player);
|
||||
}
|
||||
return (Unit*)calc.param;
|
||||
}
|
||||
|
||||
bool CastRejuvenationOnNotFullAction::isUseful()
|
||||
{
|
||||
return GetTarget();
|
||||
}
|
||||
333
src/Ai/Class/Druid/Action/DruidActions.h
Normal file
333
src/Ai/Class/Druid/Action/DruidActions.h
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* 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_DRUIDACTIONS_H
|
||||
#define _PLAYERBOT_DRUIDACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
|
||||
class CastFaerieFireAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFaerieFireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "faerie fire") {}
|
||||
};
|
||||
|
||||
class CastFaerieFireFeralAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFaerieFireFeralAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "faerie fire (feral)") {}
|
||||
};
|
||||
|
||||
class CastRejuvenationAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastRejuvenationAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "rejuvenation") {}
|
||||
};
|
||||
|
||||
class CastRegrowthAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastRegrowthAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "regrowth") {}
|
||||
};
|
||||
|
||||
class CastHealingTouchAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastHealingTouchAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "healing touch") {}
|
||||
};
|
||||
|
||||
class CastRejuvenationOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRejuvenationOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "rejuvenation", 15.0f, HealingManaEfficiency::VERY_HIGH)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastRegrowthOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRegrowthOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "regrowth", 35.0f, HealingManaEfficiency::HIGH)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastHealingTouchOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHealingTouchOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "healing touch", 50.0f, HealingManaEfficiency::LOW)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastReviveAction : public ResurrectPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastReviveAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "revive") {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
class CastRebirthAction : public ResurrectPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRebirthAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "rebirth") {}
|
||||
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastMarkOfTheWildAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMarkOfTheWildAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mark of the wild") {}
|
||||
};
|
||||
|
||||
class CastMarkOfTheWildOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastMarkOfTheWildOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "mark of the wild") {}
|
||||
};
|
||||
|
||||
class CastSurvivalInstinctsAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSurvivalInstinctsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "survival instincts") {}
|
||||
};
|
||||
|
||||
class CastFrenziedRegenerationAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrenziedRegenerationAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "frenzied regeneration") {}
|
||||
};
|
||||
|
||||
class CastThornsAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastThornsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "thorns") {}
|
||||
};
|
||||
|
||||
class CastThornsOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastThornsOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "thorns") {}
|
||||
};
|
||||
|
||||
class CastThornsOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastThornsOnMainTankAction(PlayerbotAI* botAI) : BuffOnMainTankAction(botAI, "thorns", false) {}
|
||||
};
|
||||
|
||||
class CastOmenOfClarityAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastOmenOfClarityAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "omen of clarity") {}
|
||||
};
|
||||
|
||||
class CastWrathAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastWrathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wrath") {}
|
||||
};
|
||||
|
||||
class CastStarfallAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastStarfallAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "starfall") {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastHurricaneAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHurricaneAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "hurricane") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastMoonfireAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMoonfireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "moonfire", true) {}
|
||||
};
|
||||
|
||||
class CastInsectSwarmAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastInsectSwarmAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "insect swarm", true) {}
|
||||
};
|
||||
|
||||
class CastStarfireAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastStarfireAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "starfire") {}
|
||||
};
|
||||
|
||||
class CastEntanglingRootsAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEntanglingRootsAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "entangling roots") {}
|
||||
};
|
||||
|
||||
class CastEntanglingRootsCcAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEntanglingRootsCcAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "entangling roots on cc") {}
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastHibernateAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHibernateAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "hibernate") {}
|
||||
};
|
||||
|
||||
class CastHibernateCcAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHibernateCcAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "hibernate on cc") {}
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastNaturesGraspAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastNaturesGraspAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "nature's grasp") {}
|
||||
};
|
||||
|
||||
class CastCurePoisonAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCurePoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cure poison") {}
|
||||
};
|
||||
|
||||
class CastCurePoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCurePoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cure poison", DISPEL_POISON) {}
|
||||
};
|
||||
|
||||
class CastAbolishPoisonAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastAbolishPoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "abolish poison") {}
|
||||
std::vector<NextAction> getAlternatives() override;
|
||||
};
|
||||
|
||||
class CastAbolishPoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastAbolishPoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "abolish poison", DISPEL_POISON)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<NextAction> getAlternatives() override;
|
||||
};
|
||||
|
||||
class CastBarkskinAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBarkskinAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "barkskin") {}
|
||||
};
|
||||
|
||||
class CastInnervateAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastInnervateAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "innervate") {}
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
};
|
||||
|
||||
class CastTranquilityAction : public CastAoeHealSpellAction
|
||||
{
|
||||
public:
|
||||
CastTranquilityAction(PlayerbotAI* botAI)
|
||||
: CastAoeHealSpellAction(botAI, "tranquility", 15.0f, HealingManaEfficiency::MEDIUM)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastNaturesSwiftnessAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastNaturesSwiftnessAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "nature's swiftness") {}
|
||||
};
|
||||
|
||||
class CastWildGrowthOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastWildGrowthOnPartyAction(PlayerbotAI* ai)
|
||||
: HealPartyMemberAction(ai, "wild growth", 15.0f, HealingManaEfficiency::VERY_HIGH)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastPartySwiftmendAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartySwiftmendAction(PlayerbotAI* ai)
|
||||
: HealPartyMemberAction(ai, "swiftmend", 15.0f, HealingManaEfficiency::MEDIUM)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastPartyNourishAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartyNourishAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "nourish", 25.0f, HealingManaEfficiency::LOW) {}
|
||||
};
|
||||
|
||||
class CastDruidRemoveCurseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastDruidRemoveCurseOnPartyAction(PlayerbotAI* ai) : CurePartyMemberAction(ai, "remove curse", DISPEL_CURSE) {}
|
||||
};
|
||||
|
||||
class CastInsectSwarmOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastInsectSwarmOnAttackerAction(PlayerbotAI* ai) : CastDebuffSpellOnAttackerAction(ai, "insect swarm") {}
|
||||
};
|
||||
|
||||
class CastMoonfireOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastMoonfireOnAttackerAction(PlayerbotAI* ai) : CastDebuffSpellOnAttackerAction(ai, "moonfire") {}
|
||||
};
|
||||
|
||||
class CastEnrageAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastEnrageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "enrage") {}
|
||||
};
|
||||
|
||||
class CastRejuvenationOnNotFullAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRejuvenationOnNotFullAction(PlayerbotAI* ai)
|
||||
: HealPartyMemberAction(ai, "rejuvenation", 5.0f, HealingManaEfficiency::VERY_HIGH)
|
||||
{
|
||||
}
|
||||
bool isUseful() override;
|
||||
Unit* GetTarget() override;
|
||||
};
|
||||
|
||||
class CastForceOfNatureAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastForceOfNatureAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "force of nature") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
13
src/Ai/Class/Druid/Action/DruidBearActions.cpp
Normal file
13
src/Ai/Class/Druid/Action/DruidBearActions.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* 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 "DruidBearActions.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool CastMaulAction::isUseful()
|
||||
{
|
||||
return CastMeleeSpellAction::isUseful() && AI_VALUE2(uint8, "rage", "self target") >= 45;
|
||||
}
|
||||
76
src/Ai/Class/Druid/Action/DruidBearActions.h
Normal file
76
src/Ai/Class/Druid/Action/DruidBearActions.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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_DRUIDBEARACTIONS_H
|
||||
#define _PLAYERBOT_DRUIDBEARACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ReachTargetActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CastFeralChargeBearAction : public CastReachTargetSpellAction
|
||||
{
|
||||
public:
|
||||
CastFeralChargeBearAction(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, "feral charge - bear", 1.5f) {}
|
||||
};
|
||||
|
||||
class CastGrowlAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastGrowlAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "growl") {}
|
||||
};
|
||||
|
||||
class CastMaulAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastMaulAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "maul") {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastBashAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastBashAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "bash") {}
|
||||
};
|
||||
|
||||
class CastSwipeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastSwipeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "swipe") {}
|
||||
};
|
||||
|
||||
class CastDemoralizingRoarAction : public CastMeleeDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDemoralizingRoarAction(PlayerbotAI* botAI) : CastMeleeDebuffSpellAction(botAI, "demoralizing roar") {}
|
||||
};
|
||||
|
||||
class CastMangleBearAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastMangleBearAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "mangle (bear)") {}
|
||||
};
|
||||
|
||||
class CastSwipeBearAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastSwipeBearAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "swipe (bear)") {}
|
||||
};
|
||||
|
||||
class CastLacerateAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastLacerateAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "lacerate") {}
|
||||
};
|
||||
|
||||
class CastBashOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastBashOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "bash") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
1
src/Ai/Class/Druid/Action/DruidCatActions.cpp
Normal file
1
src/Ai/Class/Druid/Action/DruidCatActions.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "DruidCatActions.h"
|
||||
117
src/Ai/Class/Druid/Action/DruidCatActions.h
Normal file
117
src/Ai/Class/Druid/Action/DruidCatActions.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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_DRUIDCATACTIONS_H
|
||||
#define _PLAYERBOT_DRUIDCATACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
#include "ReachTargetActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CastFeralChargeCatAction : public CastReachTargetSpellAction
|
||||
{
|
||||
public:
|
||||
CastFeralChargeCatAction(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, "feral charge - cat", 1.5f) {}
|
||||
};
|
||||
|
||||
class CastCowerAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCowerAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cower") {}
|
||||
};
|
||||
|
||||
class CastBerserkAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBerserkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "berserk") {}
|
||||
};
|
||||
|
||||
class CastTigersFuryAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTigersFuryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "tiger's fury") {}
|
||||
};
|
||||
|
||||
class CastSavageRoarAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSavageRoarAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "savage roar") {}
|
||||
std::string const GetTargetName() override { return "current target"; }
|
||||
};
|
||||
|
||||
class CastRakeAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastRakeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "rake", true, 6.0f) {}
|
||||
};
|
||||
|
||||
class CastRakeOnMeleeAttackersAction : public CastDebuffSpellOnMeleeAttackerAction
|
||||
{
|
||||
public:
|
||||
CastRakeOnMeleeAttackersAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "rake", true, 6.0f) {}
|
||||
};
|
||||
|
||||
class CastClawAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastClawAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "claw") {}
|
||||
};
|
||||
|
||||
class CastMangleCatAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastMangleCatAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "mangle (cat)") {}
|
||||
};
|
||||
|
||||
class CastSwipeCatAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastSwipeCatAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "swipe (cat)") {}
|
||||
};
|
||||
|
||||
class CastFerociousBiteAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastFerociousBiteAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "ferocious bite") {}
|
||||
};
|
||||
|
||||
class CastRipAction : public CastMeleeDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastRipAction(PlayerbotAI* botAI) : CastMeleeDebuffSpellAction(botAI, "rip", true, 12.0f) {}
|
||||
};
|
||||
|
||||
class CastShredAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastShredAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "shred") {}
|
||||
};
|
||||
|
||||
class CastProwlAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastProwlAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "prowl") {}
|
||||
};
|
||||
|
||||
class CastDashAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDashAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "dash") {}
|
||||
};
|
||||
|
||||
class CastRavageAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastRavageAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "ravage") {}
|
||||
};
|
||||
|
||||
class CastPounceAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastPounceAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "pounce") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
62
src/Ai/Class/Druid/Action/DruidShapeshiftActions.cpp
Normal file
62
src/Ai/Class/Druid/Action/DruidShapeshiftActions.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 "DruidShapeshiftActions.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool CastBearFormAction::isPossible()
|
||||
{
|
||||
return CastBuffSpellAction::isPossible() && !botAI->HasAura("dire bear form", GetTarget());
|
||||
}
|
||||
|
||||
bool CastBearFormAction::isUseful()
|
||||
{
|
||||
return CastBuffSpellAction::isUseful() && !botAI->HasAura("dire bear form", GetTarget());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CastDireBearFormAction::getAlternatives()
|
||||
{
|
||||
return NextAction::merge({ NextAction("bear form") },
|
||||
CastSpellAction::getAlternatives());
|
||||
}
|
||||
|
||||
bool CastTravelFormAction::isUseful()
|
||||
{
|
||||
bool firstmount = bot->GetLevel() >= 20;
|
||||
|
||||
// useful if no mount or with wsg flag
|
||||
return !bot->IsMounted() && (!firstmount || (bot->HasAura(23333) || bot->HasAura(23335) || bot->HasAura(34976))) &&
|
||||
!botAI->HasAura("dash", bot);
|
||||
}
|
||||
|
||||
bool CastCasterFormAction::isUseful()
|
||||
{
|
||||
return botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form",
|
||||
"flight form", "swift flight form", "moonkin form", nullptr) &&
|
||||
AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->mediumHealth;
|
||||
}
|
||||
|
||||
bool CastCasterFormAction::Execute(Event event)
|
||||
{
|
||||
botAI->RemoveShapeshift();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastCancelTreeFormAction::isUseful()
|
||||
{
|
||||
return botAI->HasAura(33891, bot);
|
||||
}
|
||||
|
||||
bool CastCancelTreeFormAction::Execute(Event event)
|
||||
{
|
||||
botAI->RemoveAura("tree of life");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastTreeFormAction::isUseful()
|
||||
{
|
||||
return GetTarget() && CastSpellAction::isUseful() && !botAI->HasAura(33891, bot);
|
||||
}
|
||||
83
src/Ai/Class/Druid/Action/DruidShapeshiftActions.h
Normal file
83
src/Ai/Class/Druid/Action/DruidShapeshiftActions.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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_DRUIDSHAPESHIFTACTIONS_H
|
||||
#define _PLAYERBOT_DRUIDSHAPESHIFTACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CastBearFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBearFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bear form") {}
|
||||
|
||||
bool isPossible() override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastDireBearFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDireBearFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "dire bear form") {}
|
||||
|
||||
std::vector<NextAction> getAlternatives() override;
|
||||
};
|
||||
|
||||
class CastCatFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCatFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cat form") {}
|
||||
};
|
||||
|
||||
class CastTreeFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTreeFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "tree of life") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastMoonkinFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMoonkinFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "moonkin form") {}
|
||||
};
|
||||
|
||||
class CastAquaticFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAquaticFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aquatic form") {}
|
||||
};
|
||||
|
||||
class CastTravelFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTravelFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "travel form") {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastCasterFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCasterFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "caster form") {}
|
||||
|
||||
bool isUseful() override;
|
||||
bool isPossible() override { return true; }
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastCancelTreeFormAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCancelTreeFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cancel tree form") {}
|
||||
|
||||
bool isUseful() override;
|
||||
bool isPossible() override { return true; }
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
369
src/Ai/Class/Druid/DruidAiObjectContext.cpp
Normal file
369
src/Ai/Class/Druid/DruidAiObjectContext.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* 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 "DruidAiObjectContext.h"
|
||||
|
||||
#include "BearTankDruidStrategy.h"
|
||||
#include "CasterDruidStrategy.h"
|
||||
#include "CatDpsDruidStrategy.h"
|
||||
#include "DruidActions.h"
|
||||
#include "DruidBearActions.h"
|
||||
#include "DruidCatActions.h"
|
||||
#include "DruidShapeshiftActions.h"
|
||||
#include "DruidTriggers.h"
|
||||
#include "GenericDruidNonCombatStrategy.h"
|
||||
#include "GenericDruidStrategy.h"
|
||||
#include "HealDruidStrategy.h"
|
||||
#include "MeleeDruidStrategy.h"
|
||||
#include "OffhealDruidCatStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class DruidStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
DruidStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &DruidStrategyFactoryInternal::nc;
|
||||
creators["cat aoe"] = &DruidStrategyFactoryInternal::cat_aoe;
|
||||
creators["caster aoe"] = &DruidStrategyFactoryInternal::caster_aoe;
|
||||
creators["caster debuff"] = &DruidStrategyFactoryInternal::caster_debuff;
|
||||
creators["dps debuff"] = &DruidStrategyFactoryInternal::caster_debuff;
|
||||
creators["cure"] = &DruidStrategyFactoryInternal::cure;
|
||||
creators["melee"] = &DruidStrategyFactoryInternal::melee;
|
||||
creators["buff"] = &DruidStrategyFactoryInternal::buff;
|
||||
creators["boost"] = &DruidStrategyFactoryInternal::boost;
|
||||
creators["cc"] = &DruidStrategyFactoryInternal::cc;
|
||||
creators["healer dps"] = &DruidStrategyFactoryInternal::healer_dps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericDruidNonCombatStrategy(botAI); }
|
||||
static Strategy* cat_aoe(PlayerbotAI* botAI) { return new CatAoeDruidStrategy(botAI); }
|
||||
static Strategy* caster_aoe(PlayerbotAI* botAI) { return new CasterDruidAoeStrategy(botAI); }
|
||||
static Strategy* caster_debuff(PlayerbotAI* botAI) { return new CasterDruidDebuffStrategy(botAI); }
|
||||
static Strategy* cure(PlayerbotAI* botAI) { return new DruidCureStrategy(botAI); }
|
||||
static Strategy* melee(PlayerbotAI* botAI) { return new MeleeDruidStrategy(botAI); }
|
||||
static Strategy* buff(PlayerbotAI* botAI) { return new GenericDruidBuffStrategy(botAI); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new DruidBoostStrategy(botAI); }
|
||||
static Strategy* cc(PlayerbotAI* botAI) { return new DruidCcStrategy(botAI); }
|
||||
static Strategy* healer_dps(PlayerbotAI* botAI) { return new DruidHealerDpsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class DruidDruidStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
DruidDruidStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bear"] = &DruidDruidStrategyFactoryInternal::bear;
|
||||
creators["tank"] = &DruidDruidStrategyFactoryInternal::bear;
|
||||
creators["cat"] = &DruidDruidStrategyFactoryInternal::cat;
|
||||
creators["caster"] = &DruidDruidStrategyFactoryInternal::caster;
|
||||
creators["dps"] = &DruidDruidStrategyFactoryInternal::cat;
|
||||
creators["heal"] = &DruidDruidStrategyFactoryInternal::heal;
|
||||
creators["offheal"] = &DruidDruidStrategyFactoryInternal::offheal;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bear(PlayerbotAI* botAI) { return new BearTankDruidStrategy(botAI); }
|
||||
static Strategy* cat(PlayerbotAI* botAI) { return new CatDpsDruidStrategy(botAI); }
|
||||
static Strategy* caster(PlayerbotAI* botAI) { return new CasterDruidStrategy(botAI); }
|
||||
static Strategy* heal(PlayerbotAI* botAI) { return new HealDruidStrategy(botAI); }
|
||||
static Strategy* offheal(PlayerbotAI* botAI) { return new OffhealDruidCatStrategy(botAI); }
|
||||
};
|
||||
|
||||
class DruidTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
DruidTriggerFactoryInternal()
|
||||
{
|
||||
creators["omen of clarity"] = &DruidTriggerFactoryInternal::omen_of_clarity;
|
||||
creators["thorns"] = &DruidTriggerFactoryInternal::thorns;
|
||||
creators["thorns on party"] = &DruidTriggerFactoryInternal::thorns_on_party;
|
||||
creators["thorns on main tank"] = &DruidTriggerFactoryInternal::thorns_on_main_tank;
|
||||
creators["bash"] = &DruidTriggerFactoryInternal::bash;
|
||||
creators["faerie fire (feral)"] = &DruidTriggerFactoryInternal::faerie_fire_feral;
|
||||
creators["faerie fire"] = &DruidTriggerFactoryInternal::faerie_fire;
|
||||
creators["insect swarm"] = &DruidTriggerFactoryInternal::insect_swarm;
|
||||
creators["moonfire"] = &DruidTriggerFactoryInternal::moonfire;
|
||||
creators["nature's grasp"] = &DruidTriggerFactoryInternal::natures_grasp;
|
||||
creators["tiger's fury"] = &DruidTriggerFactoryInternal::tigers_fury;
|
||||
creators["berserk"] = &DruidTriggerFactoryInternal::berserk;
|
||||
creators["savage roar"] = &DruidTriggerFactoryInternal::savage_roar;
|
||||
creators["rake"] = &DruidTriggerFactoryInternal::rake;
|
||||
creators["mark of the wild"] = &DruidTriggerFactoryInternal::mark_of_the_wild;
|
||||
creators["mark of the wild on party"] = &DruidTriggerFactoryInternal::mark_of_the_wild_on_party;
|
||||
creators["cure poison"] = &DruidTriggerFactoryInternal::cure_poison;
|
||||
creators["party member cure poison"] = &DruidTriggerFactoryInternal::party_member_cure_poison;
|
||||
creators["entangling roots"] = &DruidTriggerFactoryInternal::entangling_roots;
|
||||
creators["entangling roots kite"] = &DruidTriggerFactoryInternal::entangling_roots_kite;
|
||||
creators["hibernate"] = &DruidTriggerFactoryInternal::hibernate;
|
||||
creators["bear form"] = &DruidTriggerFactoryInternal::bear_form;
|
||||
creators["cat form"] = &DruidTriggerFactoryInternal::cat_form;
|
||||
creators["tree form"] = &DruidTriggerFactoryInternal::tree_form;
|
||||
creators["eclipse (solar)"] = &DruidTriggerFactoryInternal::eclipse_solar;
|
||||
creators["eclipse (lunar)"] = &DruidTriggerFactoryInternal::eclipse_lunar;
|
||||
creators["bash on enemy healer"] = &DruidTriggerFactoryInternal::bash_on_enemy_healer;
|
||||
creators["nature's swiftness"] = &DruidTriggerFactoryInternal::natures_swiftness;
|
||||
creators["party member remove curse"] = &DruidTriggerFactoryInternal::party_member_remove_curse;
|
||||
creators["eclipse (solar) cooldown"] = &DruidTriggerFactoryInternal::eclipse_solar_cooldown;
|
||||
creators["eclipse (lunar) cooldown"] = &DruidTriggerFactoryInternal::eclipse_lunar_cooldown;
|
||||
creators["mangle (cat)"] = &DruidTriggerFactoryInternal::mangle_cat;
|
||||
creators["ferocious bite time"] = &DruidTriggerFactoryInternal::ferocious_bite_time;
|
||||
creators["hurricane channel check"] = &DruidTriggerFactoryInternal::hurricane_channel_check;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* natures_swiftness(PlayerbotAI* botAI) { return new NaturesSwiftnessTrigger(botAI); }
|
||||
static Trigger* eclipse_solar(PlayerbotAI* botAI) { return new EclipseSolarTrigger(botAI); }
|
||||
static Trigger* eclipse_lunar(PlayerbotAI* botAI) { return new EclipseLunarTrigger(botAI); }
|
||||
static Trigger* thorns(PlayerbotAI* botAI) { return new ThornsTrigger(botAI); }
|
||||
static Trigger* thorns_on_party(PlayerbotAI* botAI) { return new ThornsOnPartyTrigger(botAI); }
|
||||
static Trigger* thorns_on_main_tank(PlayerbotAI* botAI) { return new ThornsOnMainTankTrigger(botAI); }
|
||||
static Trigger* bash(PlayerbotAI* botAI) { return new BashInterruptSpellTrigger(botAI); }
|
||||
static Trigger* faerie_fire_feral(PlayerbotAI* botAI) { return new FaerieFireFeralTrigger(botAI); }
|
||||
static Trigger* insect_swarm(PlayerbotAI* botAI) { return new InsectSwarmTrigger(botAI); }
|
||||
static Trigger* moonfire(PlayerbotAI* botAI) { return new MoonfireTrigger(botAI); }
|
||||
static Trigger* faerie_fire(PlayerbotAI* botAI) { return new FaerieFireTrigger(botAI); }
|
||||
static Trigger* natures_grasp(PlayerbotAI* botAI) { return new NaturesGraspTrigger(botAI); }
|
||||
static Trigger* tigers_fury(PlayerbotAI* botAI) { return new TigersFuryTrigger(botAI); }
|
||||
static Trigger* berserk(PlayerbotAI* botAI) { return new BerserkTrigger(botAI); }
|
||||
static Trigger* savage_roar(PlayerbotAI* botAI) { return new SavageRoarTrigger(botAI); }
|
||||
static Trigger* rake(PlayerbotAI* botAI) { return new RakeTrigger(botAI); }
|
||||
static Trigger* mark_of_the_wild(PlayerbotAI* botAI) { return new MarkOfTheWildTrigger(botAI); }
|
||||
static Trigger* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new MarkOfTheWildOnPartyTrigger(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* entangling_roots(PlayerbotAI* botAI) { return new EntanglingRootsTrigger(botAI); }
|
||||
static Trigger* entangling_roots_kite(PlayerbotAI* botAI) { return new EntanglingRootsKiteTrigger(botAI); }
|
||||
static Trigger* hibernate(PlayerbotAI* botAI) { return new HibernateTrigger(botAI); }
|
||||
static Trigger* bear_form(PlayerbotAI* botAI) { return new BearFormTrigger(botAI); }
|
||||
static Trigger* cat_form(PlayerbotAI* botAI) { return new CatFormTrigger(botAI); }
|
||||
static Trigger* tree_form(PlayerbotAI* botAI) { return new TreeFormTrigger(botAI); }
|
||||
static Trigger* bash_on_enemy_healer(PlayerbotAI* botAI) { return new BashInterruptEnemyHealerSpellTrigger(botAI); }
|
||||
static Trigger* omen_of_clarity(PlayerbotAI* botAI) { return new OmenOfClarityTrigger(botAI); }
|
||||
static Trigger* party_member_remove_curse(PlayerbotAI* ai) { return new DruidPartyMemberRemoveCurseTrigger(ai); }
|
||||
static Trigger* eclipse_solar_cooldown(PlayerbotAI* ai) { return new EclipseSolarCooldownTrigger(ai); }
|
||||
static Trigger* eclipse_lunar_cooldown(PlayerbotAI* ai) { return new EclipseLunarCooldownTrigger(ai); }
|
||||
static Trigger* mangle_cat(PlayerbotAI* ai) { return new MangleCatTrigger(ai); }
|
||||
static Trigger* ferocious_bite_time(PlayerbotAI* ai) { return new FerociousBiteTimeTrigger(ai); }
|
||||
static Trigger* hurricane_channel_check(PlayerbotAI* ai) { return new HurricaneChannelCheckTrigger(ai); }
|
||||
};
|
||||
|
||||
class DruidAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
DruidAiObjectContextInternal()
|
||||
{
|
||||
creators["feral charge - bear"] = &DruidAiObjectContextInternal::feral_charge_bear;
|
||||
creators["feral charge - cat"] = &DruidAiObjectContextInternal::feral_charge_cat;
|
||||
creators["swipe (bear)"] = &DruidAiObjectContextInternal::swipe_bear;
|
||||
creators["faerie fire (feral)"] = &DruidAiObjectContextInternal::faerie_fire_feral;
|
||||
creators["faerie fire"] = &DruidAiObjectContextInternal::faerie_fire;
|
||||
creators["bear form"] = &DruidAiObjectContextInternal::bear_form;
|
||||
creators["dire bear form"] = &DruidAiObjectContextInternal::dire_bear_form;
|
||||
creators["moonkin form"] = &DruidAiObjectContextInternal::moonkin_form;
|
||||
creators["cat form"] = &DruidAiObjectContextInternal::cat_form;
|
||||
creators["tree form"] = &DruidAiObjectContextInternal::tree_form;
|
||||
creators["travel form"] = &DruidAiObjectContextInternal::travel_form;
|
||||
creators["aquatic form"] = &DruidAiObjectContextInternal::aquatic_form;
|
||||
creators["caster form"] = &DruidAiObjectContextInternal::caster_form;
|
||||
creators["cancel tree form"] = &DruidAiObjectContextInternal::cancel_tree_form;
|
||||
creators["mangle (bear)"] = &DruidAiObjectContextInternal::mangle_bear;
|
||||
creators["maul"] = &DruidAiObjectContextInternal::maul;
|
||||
creators["bash"] = &DruidAiObjectContextInternal::bash;
|
||||
creators["swipe"] = &DruidAiObjectContextInternal::swipe;
|
||||
creators["growl"] = &DruidAiObjectContextInternal::growl;
|
||||
creators["demoralizing roar"] = &DruidAiObjectContextInternal::demoralizing_roar;
|
||||
creators["hibernate"] = &DruidAiObjectContextInternal::hibernate;
|
||||
creators["entangling roots"] = &DruidAiObjectContextInternal::entangling_roots;
|
||||
creators["entangling roots on cc"] = &DruidAiObjectContextInternal::entangling_roots_on_cc;
|
||||
creators["hibernate"] = &DruidAiObjectContextInternal::hibernate;
|
||||
creators["hibernate on cc"] = &DruidAiObjectContextInternal::hibernate_on_cc;
|
||||
creators["wrath"] = &DruidAiObjectContextInternal::wrath;
|
||||
creators["starfall"] = &DruidAiObjectContextInternal::starfall;
|
||||
creators["insect swarm"] = &DruidAiObjectContextInternal::insect_swarm;
|
||||
creators["moonfire"] = &DruidAiObjectContextInternal::moonfire;
|
||||
creators["starfire"] = &DruidAiObjectContextInternal::starfire;
|
||||
creators["nature's grasp"] = &DruidAiObjectContextInternal::natures_grasp;
|
||||
creators["claw"] = &DruidAiObjectContextInternal::claw;
|
||||
creators["mangle (cat)"] = &DruidAiObjectContextInternal::mangle_cat;
|
||||
creators["swipe (cat)"] = &DruidAiObjectContextInternal::swipe_cat;
|
||||
creators["rake"] = &DruidAiObjectContextInternal::rake;
|
||||
creators["rake on attacker"] = &DruidAiObjectContextInternal::rake_on_attacker;
|
||||
creators["ferocious bite"] = &DruidAiObjectContextInternal::ferocious_bite;
|
||||
creators["rip"] = &DruidAiObjectContextInternal::rip;
|
||||
creators["cower"] = &DruidAiObjectContextInternal::cower;
|
||||
creators["survival instincts"] = &DruidAiObjectContextInternal::survival_instincts;
|
||||
creators["frenzied regeneration"] = &DruidAiObjectContextInternal::frenzied_regeneration;
|
||||
creators["thorns"] = &DruidAiObjectContextInternal::thorns;
|
||||
creators["thorns on party"] = &DruidAiObjectContextInternal::thorns_on_party;
|
||||
creators["thorns on main tank"] = &DruidAiObjectContextInternal::thorns_on_main_tank;
|
||||
creators["cure poison"] = &DruidAiObjectContextInternal::cure_poison;
|
||||
creators["cure poison on party"] = &DruidAiObjectContextInternal::cure_poison_on_party;
|
||||
creators["abolish poison"] = &DruidAiObjectContextInternal::abolish_poison;
|
||||
creators["abolish poison on party"] = &DruidAiObjectContextInternal::abolish_poison_on_party;
|
||||
creators["berserk"] = &DruidAiObjectContextInternal::berserk;
|
||||
creators["tiger's fury"] = &DruidAiObjectContextInternal::tigers_fury;
|
||||
creators["savage roar"] = &DruidAiObjectContextInternal::savage_roar;
|
||||
creators["mark of the wild"] = &DruidAiObjectContextInternal::mark_of_the_wild;
|
||||
creators["mark of the wild on party"] = &DruidAiObjectContextInternal::mark_of_the_wild_on_party;
|
||||
creators["regrowth"] = &DruidAiObjectContextInternal::regrowth;
|
||||
creators["rejuvenation"] = &DruidAiObjectContextInternal::rejuvenation;
|
||||
creators["healing touch"] = &DruidAiObjectContextInternal::healing_touch;
|
||||
creators["regrowth on party"] = &DruidAiObjectContextInternal::regrowth_on_party;
|
||||
creators["rejuvenation on party"] = &DruidAiObjectContextInternal::rejuvenation_on_party;
|
||||
creators["rejuvenation on not full"] = &DruidAiObjectContextInternal::rejuvenation_on_not_full;
|
||||
creators["healing touch on party"] = &DruidAiObjectContextInternal::healing_touch_on_party;
|
||||
creators["rebirth"] = &DruidAiObjectContextInternal::rebirth;
|
||||
creators["revive"] = &DruidAiObjectContextInternal::revive;
|
||||
creators["barkskin"] = &DruidAiObjectContextInternal::barkskin;
|
||||
creators["lacerate"] = &DruidAiObjectContextInternal::lacerate;
|
||||
creators["hurricane"] = &DruidAiObjectContextInternal::hurricane;
|
||||
creators["innervate"] = &DruidAiObjectContextInternal::innervate;
|
||||
creators["tranquility"] = &DruidAiObjectContextInternal::tranquility;
|
||||
creators["bash on enemy healer"] = &DruidAiObjectContextInternal::bash_on_enemy_healer;
|
||||
creators["omen of clarity"] = &DruidAiObjectContextInternal::omen_of_clarity;
|
||||
creators["nature's swiftness"] = &DruidAiObjectContextInternal::natures_swiftness;
|
||||
creators["prowl"] = &DruidAiObjectContextInternal::prowl;
|
||||
creators["dash"] = &DruidAiObjectContextInternal::dash;
|
||||
creators["shred"] = &DruidAiObjectContextInternal::shred;
|
||||
creators["ravage"] = &DruidAiObjectContextInternal::ravage;
|
||||
creators["pounce"] = &DruidAiObjectContextInternal::pounce;
|
||||
creators["wild growth on party"] = &DruidAiObjectContextInternal::wild_growth_on_party;
|
||||
creators["swiftmend on party"] = &DruidAiObjectContextInternal::swiftmend_on_party;
|
||||
creators["nourish on party"] = &DruidAiObjectContextInternal::nourish_on_party;
|
||||
creators["remove curse on party"] = &DruidAiObjectContextInternal::remove_curse_on_party;
|
||||
creators["insect swarm on attacker"] = &DruidAiObjectContextInternal::insect_swarm_on_attacker;
|
||||
creators["moonfire on attacker"] = &DruidAiObjectContextInternal::moonfire_on_attacker;
|
||||
creators["enrage"] = &DruidAiObjectContextInternal::enrage;
|
||||
creators["force of nature"] = &DruidAiObjectContextInternal::force_of_nature;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* natures_swiftness(PlayerbotAI* botAI) { return new CastNaturesSwiftnessAction(botAI); }
|
||||
static Action* omen_of_clarity(PlayerbotAI* botAI) { return new CastOmenOfClarityAction(botAI); }
|
||||
static Action* tranquility(PlayerbotAI* botAI) { return new CastTranquilityAction(botAI); }
|
||||
static Action* feral_charge_bear(PlayerbotAI* botAI) { return new CastFeralChargeBearAction(botAI); }
|
||||
static Action* feral_charge_cat(PlayerbotAI* botAI) { return new CastFeralChargeCatAction(botAI); }
|
||||
static Action* swipe_bear(PlayerbotAI* botAI) { return new CastSwipeBearAction(botAI); }
|
||||
static Action* faerie_fire_feral(PlayerbotAI* botAI) { return new CastFaerieFireFeralAction(botAI); }
|
||||
static Action* faerie_fire(PlayerbotAI* botAI) { return new CastFaerieFireAction(botAI); }
|
||||
static Action* bear_form(PlayerbotAI* botAI) { return new CastBearFormAction(botAI); }
|
||||
static Action* dire_bear_form(PlayerbotAI* botAI) { return new CastDireBearFormAction(botAI); }
|
||||
static Action* cat_form(PlayerbotAI* botAI) { return new CastCatFormAction(botAI); }
|
||||
static Action* tree_form(PlayerbotAI* botAI) { return new CastTreeFormAction(botAI); }
|
||||
static Action* travel_form(PlayerbotAI* botAI) { return new CastTravelFormAction(botAI); }
|
||||
static Action* aquatic_form(PlayerbotAI* botAI) { return new CastAquaticFormAction(botAI); }
|
||||
static Action* caster_form(PlayerbotAI* botAI) { return new CastCasterFormAction(botAI); }
|
||||
static Action* cancel_tree_form(PlayerbotAI* botAI) { return new CastCancelTreeFormAction(botAI); }
|
||||
static Action* mangle_bear(PlayerbotAI* botAI) { return new CastMangleBearAction(botAI); }
|
||||
static Action* maul(PlayerbotAI* botAI) { return new CastMaulAction(botAI); }
|
||||
static Action* bash(PlayerbotAI* botAI) { return new CastBashAction(botAI); }
|
||||
static Action* swipe(PlayerbotAI* botAI) { return new CastSwipeAction(botAI); }
|
||||
static Action* growl(PlayerbotAI* botAI) { return new CastGrowlAction(botAI); }
|
||||
static Action* demoralizing_roar(PlayerbotAI* botAI) { return new CastDemoralizingRoarAction(botAI); }
|
||||
static Action* moonkin_form(PlayerbotAI* botAI) { return new CastMoonkinFormAction(botAI); }
|
||||
static Action* hibernate(PlayerbotAI* botAI) { return new CastHibernateAction(botAI); }
|
||||
static Action* entangling_roots(PlayerbotAI* botAI) { return new CastEntanglingRootsAction(botAI); }
|
||||
static Action* hibernate_on_cc(PlayerbotAI* botAI) { return new CastHibernateCcAction(botAI); }
|
||||
static Action* entangling_roots_on_cc(PlayerbotAI* botAI) { return new CastEntanglingRootsCcAction(botAI); }
|
||||
static Action* wrath(PlayerbotAI* botAI) { return new CastWrathAction(botAI); }
|
||||
static Action* starfall(PlayerbotAI* botAI) { return new CastStarfallAction(botAI); }
|
||||
static Action* insect_swarm(PlayerbotAI* botAI) { return new CastInsectSwarmAction(botAI); }
|
||||
static Action* moonfire(PlayerbotAI* botAI) { return new CastMoonfireAction(botAI); }
|
||||
static Action* starfire(PlayerbotAI* botAI) { return new CastStarfireAction(botAI); }
|
||||
static Action* natures_grasp(PlayerbotAI* botAI) { return new CastNaturesGraspAction(botAI); }
|
||||
static Action* claw(PlayerbotAI* botAI) { return new CastClawAction(botAI); }
|
||||
static Action* mangle_cat(PlayerbotAI* botAI) { return new CastMangleCatAction(botAI); }
|
||||
static Action* swipe_cat(PlayerbotAI* botAI) { return new CastSwipeCatAction(botAI); }
|
||||
static Action* rake(PlayerbotAI* botAI) { return new CastRakeAction(botAI); }
|
||||
static Action* rake_on_attacker(PlayerbotAI* botAI) { return new CastRakeOnMeleeAttackersAction(botAI); }
|
||||
static Action* ferocious_bite(PlayerbotAI* botAI) { return new CastFerociousBiteAction(botAI); }
|
||||
static Action* rip(PlayerbotAI* botAI) { return new CastRipAction(botAI); }
|
||||
static Action* cower(PlayerbotAI* botAI) { return new CastCowerAction(botAI); }
|
||||
static Action* survival_instincts(PlayerbotAI* botAI) { return new CastSurvivalInstinctsAction(botAI); }
|
||||
static Action* frenzied_regeneration(PlayerbotAI* botAI) { return new CastFrenziedRegenerationAction(botAI); }
|
||||
static Action* thorns(PlayerbotAI* botAI) { return new CastThornsAction(botAI); }
|
||||
static Action* thorns_on_party(PlayerbotAI* botAI) { return new CastThornsOnPartyAction(botAI); }
|
||||
static Action* thorns_on_main_tank(PlayerbotAI* botAI) { return new CastThornsOnMainTankAction(botAI); }
|
||||
static Action* cure_poison(PlayerbotAI* botAI) { return new CastCurePoisonAction(botAI); }
|
||||
static Action* cure_poison_on_party(PlayerbotAI* botAI) { return new CastCurePoisonOnPartyAction(botAI); }
|
||||
static Action* abolish_poison(PlayerbotAI* botAI) { return new CastAbolishPoisonAction(botAI); }
|
||||
static Action* abolish_poison_on_party(PlayerbotAI* botAI) { return new CastAbolishPoisonOnPartyAction(botAI); }
|
||||
static Action* berserk(PlayerbotAI* botAI) { return new CastBerserkAction(botAI); }
|
||||
static Action* tigers_fury(PlayerbotAI* botAI) { return new CastTigersFuryAction(botAI); }
|
||||
static Action* savage_roar(PlayerbotAI* botAI) { return new CastSavageRoarAction(botAI); }
|
||||
static Action* mark_of_the_wild(PlayerbotAI* botAI) { return new CastMarkOfTheWildAction(botAI); }
|
||||
static Action* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new CastMarkOfTheWildOnPartyAction(botAI); }
|
||||
static Action* regrowth(PlayerbotAI* botAI) { return new CastRegrowthAction(botAI); }
|
||||
static Action* rejuvenation(PlayerbotAI* botAI) { return new CastRejuvenationAction(botAI); }
|
||||
static Action* healing_touch(PlayerbotAI* botAI) { return new CastHealingTouchAction(botAI); }
|
||||
static Action* regrowth_on_party(PlayerbotAI* botAI) { return new CastRegrowthOnPartyAction(botAI); }
|
||||
static Action* rejuvenation_on_party(PlayerbotAI* botAI) { return new CastRejuvenationOnPartyAction(botAI); }
|
||||
static Action* rejuvenation_on_not_full(PlayerbotAI* botAI) { return new CastRejuvenationOnNotFullAction(botAI); }
|
||||
static Action* healing_touch_on_party(PlayerbotAI* botAI) { return new CastHealingTouchOnPartyAction(botAI); }
|
||||
static Action* rebirth(PlayerbotAI* botAI) { return new CastRebirthAction(botAI); }
|
||||
static Action* revive(PlayerbotAI* botAI) { return new CastReviveAction(botAI); }
|
||||
static Action* barkskin(PlayerbotAI* botAI) { return new CastBarkskinAction(botAI); }
|
||||
static Action* lacerate(PlayerbotAI* botAI) { return new CastLacerateAction(botAI); }
|
||||
static Action* hurricane(PlayerbotAI* botAI) { return new CastHurricaneAction(botAI); }
|
||||
static Action* innervate(PlayerbotAI* botAI) { return new CastInnervateAction(botAI); }
|
||||
static Action* bash_on_enemy_healer(PlayerbotAI* botAI) { return new CastBashOnEnemyHealerAction(botAI); }
|
||||
static Action* ravage(PlayerbotAI* botAI) { return new CastRavageAction(botAI); }
|
||||
static Action* pounce(PlayerbotAI* botAI) { return new CastPounceAction(botAI); }
|
||||
static Action* prowl(PlayerbotAI* botAI) { return new CastProwlAction(botAI); }
|
||||
static Action* dash(PlayerbotAI* botAI) { return new CastDashAction(botAI); }
|
||||
static Action* shred(PlayerbotAI* botAI) { return new CastShredAction(botAI); }
|
||||
static Action* wild_growth_on_party(PlayerbotAI* ai) { return new CastWildGrowthOnPartyAction(ai); }
|
||||
static Action* swiftmend_on_party(PlayerbotAI* ai) { return new CastPartySwiftmendAction(ai); }
|
||||
static Action* nourish_on_party(PlayerbotAI* ai) { return new CastPartyNourishAction(ai); }
|
||||
static Action* remove_curse_on_party(PlayerbotAI* ai) { return new CastDruidRemoveCurseOnPartyAction(ai); }
|
||||
static Action* insect_swarm_on_attacker(PlayerbotAI* ai) { return new CastInsectSwarmOnAttackerAction(ai); }
|
||||
static Action* moonfire_on_attacker(PlayerbotAI* ai) { return new CastMoonfireOnAttackerAction(ai); }
|
||||
static Action* enrage(PlayerbotAI* ai) { return new CastEnrageAction(ai); }
|
||||
static Action* force_of_nature(PlayerbotAI* ai) { return new CastForceOfNatureAction(ai); }
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> DruidAiObjectContext::sharedStrategyContexts;
|
||||
SharedNamedObjectContextList<Action> DruidAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> DruidAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> DruidAiObjectContext::sharedValueContexts;
|
||||
|
||||
DruidAiObjectContext::DruidAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void DruidAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void DruidAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new DruidStrategyFactoryInternal());
|
||||
strategyContexts.Add(new DruidDruidStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void DruidAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new DruidAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void DruidAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new DruidTriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void DruidAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Druid/DruidAiObjectContext.h
Normal file
30
src/Ai/Class/Druid/DruidAiObjectContext.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_DRUIDAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_DRUIDAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class DruidAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
DruidAiObjectContext(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
|
||||
256
src/Ai/Class/Druid/Strategy/BearTankDruidStrategy.cpp
Normal file
256
src/Ai/Class/Druid/Strategy/BearTankDruidStrategy.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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 "BearTankDruidStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class BearTankDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
BearTankDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["melee"] = &melee;
|
||||
creators["feral charge - bear"] = &feral_charge_bear;
|
||||
creators["swipe (bear)"] = &swipe_bear;
|
||||
creators["faerie fire (feral)"] = &faerie_fire_feral;
|
||||
creators["bear form"] = &bear_form;
|
||||
creators["dire bear form"] = &dire_bear_form;
|
||||
creators["mangle (bear)"] = &mangle_bear;
|
||||
creators["maul"] = &maul;
|
||||
creators["bash"] = &bash;
|
||||
creators["swipe"] = &swipe;
|
||||
creators["lacerate"] = &lacerate;
|
||||
creators["demoralizing roar"] = &demoralizing_roar;
|
||||
creators["taunt spell"] = &growl;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* melee([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"melee",
|
||||
/*P*/ { NextAction("feral charge - bear") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* feral_charge_bear([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"feral charge - bear",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("reach melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* swipe_bear([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"swipe (bear)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* faerie_fire_feral([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"faerie fire (feral)",
|
||||
/*P*/ { NextAction("feral charge - bear") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* bear_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"bear form",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* dire_bear_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"dire bear form",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ { NextAction("bear form") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* mangle_bear([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"mangle (bear)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* maul([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"maul",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* bash([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"bash",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* swipe([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"swipe",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* lacerate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"lacerate",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("maul") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* growl([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"growl",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* demoralizing_roar([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"demoralizing roar",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BearTankDruidStrategy::BearTankDruidStrategy(PlayerbotAI* botAI) : FeralDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new BearTankDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> BearTankDruidStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("mangle (bear)", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("faerie fire (feral)", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("lacerate", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("maul", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("enrage", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void BearTankDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
FeralDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("feral charge - bear", ACTION_NORMAL + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"bear form",
|
||||
{
|
||||
NextAction("dire bear form", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("frenzied regeneration", ACTION_HIGH + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"faerie fire (feral)",
|
||||
{
|
||||
NextAction("faerie fire (feral)", ACTION_HIGH + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lose aggro",
|
||||
{
|
||||
NextAction("growl", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("demoralizing roar", ACTION_HIGH + 6),
|
||||
NextAction("swipe (bear)", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"light aoe",
|
||||
{
|
||||
NextAction("swipe (bear)", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"bash",
|
||||
{
|
||||
NextAction("bash", ACTION_INTERRUPT + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"bash on enemy healer",
|
||||
{
|
||||
NextAction("bash on enemy healer", ACTION_INTERRUPT + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Druid/Strategy/BearTankDruidStrategy.h
Normal file
24
src/Ai/Class/Druid/Strategy/BearTankDruidStrategy.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_BEARTANKDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_BEARTANKDRUIDSTRATEGY_H
|
||||
|
||||
#include "FeralDruidStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class BearTankDruidStrategy : public FeralDruidStrategy
|
||||
{
|
||||
public:
|
||||
BearTankDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bear"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_TANK | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
254
src/Ai/Class/Druid/Strategy/CasterDruidStrategy.cpp
Normal file
254
src/Ai/Class/Druid/Strategy/CasterDruidStrategy.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* 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 "CasterDruidStrategy.h"
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "FeralDruidStrategy.h"
|
||||
|
||||
class CasterDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
CasterDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["faerie fire"] = &faerie_fire;
|
||||
creators["hibernate"] = &hibernate;
|
||||
creators["entangling roots"] = &entangling_roots;
|
||||
creators["entangling roots on cc"] = &entangling_roots_on_cc;
|
||||
creators["wrath"] = &wrath;
|
||||
creators["starfall"] = &starfall;
|
||||
creators["insect swarm"] = &insect_swarm;
|
||||
creators["moonfire"] = &moonfire;
|
||||
creators["starfire"] = &starfire;
|
||||
creators["moonkin form"] = &moonkin_form;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* faerie_fire([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"faerie fire",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* hibernate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"hibernate",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ { NextAction("entangling roots") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* entangling_roots([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"entangling roots",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* entangling_roots_on_cc([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"entangling roots on cc",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* wrath([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"wrath",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* starfall([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"starfall",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* insect_swarm([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"insect swarm",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* moonfire([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"moonfire",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* starfire([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"starfire",
|
||||
/*P*/ { NextAction("moonkin form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* moonkin_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"moonkin form",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
CasterDruidStrategy::CasterDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new CasterDruidStrategyActionNodeFactory());
|
||||
actionNodeFactories.Add(new ShapeshiftDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CasterDruidStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("starfall", ACTION_HIGH + 1.0f),
|
||||
NextAction("force of nature", ACTION_DEFAULT + 1.0f),
|
||||
NextAction("wrath", ACTION_DEFAULT + 0.1f),
|
||||
};
|
||||
}
|
||||
|
||||
void CasterDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"eclipse (lunar) cooldown",
|
||||
{
|
||||
NextAction("starfire", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"eclipse (solar) cooldown",
|
||||
{
|
||||
NextAction("wrath", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"insect swarm",
|
||||
{
|
||||
NextAction("insect swarm", ACTION_NORMAL + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"moonfire",
|
||||
{
|
||||
NextAction("moonfire", ACTION_NORMAL + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"eclipse (solar)",
|
||||
{
|
||||
NextAction("wrath", ACTION_NORMAL + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"eclipse (lunar)",
|
||||
{
|
||||
NextAction("starfire", ACTION_NORMAL + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium mana",
|
||||
{
|
||||
NextAction("innervate", ACTION_HIGH + 9)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy too close for spell",
|
||||
{
|
||||
NextAction("flee", ACTION_MOVE + 9)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void CasterDruidAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"hurricane channel check",
|
||||
{
|
||||
NextAction("cancel channel", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("hurricane", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"light aoe",
|
||||
{
|
||||
NextAction("insect swarm on attacker", ACTION_NORMAL + 3),
|
||||
NextAction("moonfire on attacker", ACTION_NORMAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void CasterDruidDebuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"faerie fire",
|
||||
{
|
||||
NextAction("faerie fire", ACTION_HIGH)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
45
src/Ai/Class/Druid/Strategy/CasterDruidStrategy.h
Normal file
45
src/Ai/Class/Druid/Strategy/CasterDruidStrategy.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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_CASTERDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_CASTERDRUIDSTRATEGY_H
|
||||
|
||||
#include "GenericDruidStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CasterDruidStrategy : public GenericDruidStrategy
|
||||
{
|
||||
public:
|
||||
CasterDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "caster"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_RANGED; }
|
||||
};
|
||||
|
||||
class CasterDruidAoeStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
CasterDruidAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "caster aoe"; }
|
||||
};
|
||||
|
||||
class CasterDruidDebuffStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
CasterDruidDebuffStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "caster debuff"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
314
src/Ai/Class/Druid/Strategy/CatDpsDruidStrategy.cpp
Normal file
314
src/Ai/Class/Druid/Strategy/CatDpsDruidStrategy.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* 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 "CatDpsDruidStrategy.h"
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class CatDpsDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
CatDpsDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["faerie fire (feral)"] = &faerie_fire_feral;
|
||||
creators["melee"] = &melee;
|
||||
creators["feral charge - cat"] = &feral_charge_cat;
|
||||
creators["cat form"] = &cat_form;
|
||||
creators["claw"] = &claw;
|
||||
creators["mangle (cat)"] = &mangle_cat;
|
||||
creators["rake"] = &rake;
|
||||
creators["ferocious bite"] = &ferocious_bite;
|
||||
creators["rip"] = &rip;
|
||||
creators["pounce"] = &pounce;
|
||||
creators["ravage"] = &ravage;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* faerie_fire_feral([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"faerie fire (feral)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* melee([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"melee",
|
||||
/*P*/ { NextAction("feral charge - cat") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* feral_charge_cat([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"feral charge - cat",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("reach melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* cat_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"cat form",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* claw([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"claw",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("melee") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* mangle_cat([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"mangle (cat)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rake([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rake",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* ferocious_bite([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"ferocious bite",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("rip") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rip([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rip",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* pounce([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"pounce",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("ravage") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* ravage([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"ravage",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("shred") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
CatDpsDruidStrategy::CatDpsDruidStrategy(PlayerbotAI* botAI) : FeralDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new CatDpsDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> CatDpsDruidStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("tiger's fury", ACTION_DEFAULT + 0.1f)
|
||||
};
|
||||
}
|
||||
|
||||
void CatDpsDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
FeralDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
// Default priority
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"almost full energy available",
|
||||
{
|
||||
NextAction("shred", ACTION_DEFAULT + 0.4f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points not full",
|
||||
{
|
||||
NextAction("shred", ACTION_DEFAULT + 0.4f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"almost full energy available",
|
||||
{
|
||||
NextAction("mangle (cat)", ACTION_DEFAULT + 0.3f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points not full and high energy",
|
||||
{
|
||||
NextAction("mangle (cat)", ACTION_DEFAULT + 0.3f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"almost full energy available",
|
||||
{
|
||||
NextAction("claw", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points not full and high energy",
|
||||
{
|
||||
NextAction("claw", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"faerie fire (feral)",
|
||||
{
|
||||
NextAction("faerie fire (feral)", ACTION_DEFAULT + 0.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Main spell
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"cat form", {
|
||||
NextAction("cat form", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"savage roar", {
|
||||
NextAction("savage roar", ACTION_HIGH + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points available",
|
||||
{
|
||||
NextAction("rip", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"ferocious bite time",
|
||||
{
|
||||
NextAction("ferocious bite", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target with combo points almost dead",
|
||||
{
|
||||
NextAction("ferocious bite", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"mangle (cat)",
|
||||
{
|
||||
NextAction("mangle (cat)", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"rake",
|
||||
{
|
||||
NextAction("rake", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium threat",
|
||||
{
|
||||
NextAction("cower", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// AOE
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("swipe (cat)", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"light aoe",
|
||||
{
|
||||
NextAction("rake on attacker", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
// Reach target
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("feral charge - cat", ACTION_HIGH + 9)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("dash", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void CatAoeDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) {}
|
||||
35
src/Ai/Class/Druid/Strategy/CatDpsDruidStrategy.h
Normal file
35
src/Ai/Class/Druid/Strategy/CatDpsDruidStrategy.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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_CATDPSDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_CATDPSDRUIDSTRATEGY_H
|
||||
|
||||
#include "FeralDruidStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CatDpsDruidStrategy : public FeralDruidStrategy
|
||||
{
|
||||
public:
|
||||
CatDpsDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cat"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
class CatAoeDruidStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
CatAoeDruidStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cat aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
113
src/Ai/Class/Druid/Strategy/FeralDruidStrategy.cpp
Normal file
113
src/Ai/Class/Druid/Strategy/FeralDruidStrategy.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 "FeralDruidStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class FeralDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FeralDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["survival instincts"] = &survival_instincts;
|
||||
creators["thorns"] = þs;
|
||||
creators["omen of clarity"] = &omen_of_clarity;
|
||||
creators["cure poison"] = &cure_poison;
|
||||
creators["cure poison on party"] = &cure_poison_on_party;
|
||||
creators["abolish poison"] = &abolish_poison;
|
||||
creators["abolish poison on party"] = &abolish_poison_on_party;
|
||||
creators["prowl"] = &prowl;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* survival_instincts([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("survival instincts",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("barkskin") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* thorns([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("thorns",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* omen_of_clarity([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("omen of clarity",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* cure_poison([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cure poison",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* cure_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cure poison on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* abolish_poison([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("abolish poison",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* abolish_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("abolish poison on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* prowl([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("prowl",
|
||||
/*P*/ { NextAction("cat form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
FeralDruidStrategy::FeralDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FeralDruidStrategyActionNodeFactory());
|
||||
actionNodeFactories.Add(new ShapeshiftDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void FeralDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"enemy out of melee", { NextAction("reach melee", ACTION_HIGH + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"critical health", { NextAction("survival instincts", ACTION_EMERGENCY + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"omen of clarity", { NextAction("omen of clarity", ACTION_HIGH + 9) }));
|
||||
triggers.push_back(new TriggerNode("player has flag",
|
||||
{ NextAction("dash", ACTION_EMERGENCY + 2) }));
|
||||
triggers.push_back(new TriggerNode("enemy flagcarrier near",
|
||||
{ NextAction("dash", ACTION_EMERGENCY + 2) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("berserk", { NextAction("berserk", ACTION_HIGH + 6) }));
|
||||
}
|
||||
86
src/Ai/Class/Druid/Strategy/FeralDruidStrategy.h
Normal file
86
src/Ai/Class/Druid/Strategy/FeralDruidStrategy.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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_FERALRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_FERALRUIDSTRATEGY_H
|
||||
|
||||
#include "GenericDruidStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ShapeshiftDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
ShapeshiftDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["rejuvenation"] = &rejuvenation;
|
||||
creators["regrowth"] = ®rowth;
|
||||
creators["healing touch"] = &healing_touch;
|
||||
creators["rejuvenation on party"] = &rejuvenation_on_party;
|
||||
creators["regrowth on party"] = ®rowth_on_party;
|
||||
creators["healing touch on party"] = &healing_touch_on_party;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* regrowth([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("regrowth",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ { NextAction("healing touch") },
|
||||
/*C*/ { NextAction("melee", 10.0f) });
|
||||
}
|
||||
|
||||
static ActionNode* rejuvenation([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rejuvenation",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* healing_touch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("healing touch",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("regrowth on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ { NextAction("healing touch on party") },
|
||||
/*C*/ { NextAction("melee", 10.0f) });
|
||||
}
|
||||
|
||||
static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rejuvenation on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* healing_touch_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("healing touch on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
class FeralDruidStrategy : public GenericDruidStrategy
|
||||
{
|
||||
protected:
|
||||
FeralDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
194
src/Ai/Class/Druid/Strategy/GenericDruidNonCombatStrategy.cpp
Normal file
194
src/Ai/Class/Druid/Strategy/GenericDruidNonCombatStrategy.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 "GenericDruidNonCombatStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
class GenericDruidNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericDruidNonCombatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["thorns"] = þs;
|
||||
creators["thorns on party"] = þs_on_party;
|
||||
creators["mark of the wild"] = &mark_of_the_wild;
|
||||
creators["mark of the wild on party"] = &mark_of_the_wild_on_party;
|
||||
// creators["innervate"] = &innervate;
|
||||
creators["regrowth_on_party"] = ®rowth_on_party;
|
||||
creators["rejuvenation on party"] = &rejuvenation_on_party;
|
||||
creators["remove curse on party"] = &remove_curse_on_party;
|
||||
creators["abolish poison on party"] = &abolish_poison_on_party;
|
||||
creators["revive"] = &revive;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* thorns([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("thorns",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* thorns_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("thorns on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* mark_of_the_wild([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mark of the wild",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* mark_of_the_wild_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mark of the wild on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("regrowth on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rejuvenation on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* remove_curse_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("remove curse on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* abolish_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("abolish poison on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* revive([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("revive",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericDruidNonCombatStrategy::GenericDruidNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericDruidNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericDruidNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("mark of the wild", { NextAction("mark of the wild", 14.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member cure poison", { NextAction("abolish poison on party", 20.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member dead", { NextAction("revive", ACTION_CRITICAL_HEAL + 10) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", 1.0f) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member critical health",
|
||||
{
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 7),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5),
|
||||
}));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member low health",
|
||||
{
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
}));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member medium health",
|
||||
{ NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 3),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1),
|
||||
}));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member almost full health",
|
||||
{ NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3), NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member remove curse",
|
||||
{ NextAction("remove curse on party", ACTION_DISPEL + 7) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("new pet", { NextAction("set pet stance", 60.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("party member critical health", {
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 7),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("party member low health", {
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("party member medium health", {
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 3),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", {
|
||||
NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3),
|
||||
NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("party member remove curse", {
|
||||
NextAction("remove curse on party", ACTION_DISPEL + 7),
|
||||
}));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
if (specTab == 0 || specTab == 2) // Balance or Restoration
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", 1.0f) }));
|
||||
if (specTab == 1) // Feral
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply stone", 1.0f) }));
|
||||
|
||||
}
|
||||
|
||||
GenericDruidBuffStrategy::GenericDruidBuffStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericDruidNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericDruidBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("mark of the wild on party", {
|
||||
NextAction("mark of the wild on party", 13.0f),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("thorns on main tank", {
|
||||
NextAction("thorns on main tank", 11.0f),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("thorns", {
|
||||
NextAction("thorns", 10.0f),
|
||||
}));
|
||||
}
|
||||
31
src/Ai/Class/Druid/Strategy/GenericDruidNonCombatStrategy.h
Normal file
31
src/Ai/Class/Druid/Strategy/GenericDruidNonCombatStrategy.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_GENERICDRUIDNONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICDRUIDNONCOMBATSTRATEGY_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericDruidNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericDruidNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "nc"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class GenericDruidBuffStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericDruidBuffStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "buff"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
158
src/Ai/Class/Druid/Strategy/GenericDruidStrategy.cpp
Normal file
158
src/Ai/Class/Druid/Strategy/GenericDruidStrategy.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 "GenericDruidStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class GenericDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericDruidStrategyActionNodeFactory()
|
||||
{
|
||||
creators["melee"] = &melee;
|
||||
creators["caster form"] = &caster_form;
|
||||
creators["cure poison"] = &cure_poison;
|
||||
creators["cure poison on party"] = &cure_poison_on_party;
|
||||
creators["abolish poison"] = &abolish_poison;
|
||||
creators["abolish poison on party"] = &abolish_poison_on_party;
|
||||
creators["rebirth"] = &rebirth;
|
||||
creators["entangling roots on cc"] = &entangling_roots_on_cc;
|
||||
creators["innervate"] = &innervate;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* melee([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("melee",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* caster_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("caster form",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* cure_poison([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cure poison",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* cure_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cure poison on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* abolish_poison([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("abolish poison",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* abolish_poison_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("abolish poison on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* rebirth([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rebirth",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* entangling_roots_on_cc([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("entangling roots on cc",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* innervate([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("innervate",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("mana potion") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericDruidStrategy::GenericDruidStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("low health", { NextAction("barkskin", ACTION_HIGH + 7) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("combat party member dead",
|
||||
{ NextAction("rebirth", ACTION_HIGH + 9) }));
|
||||
triggers.push_back(new TriggerNode("being attacked",
|
||||
{ NextAction("nature's grasp", ACTION_HIGH + 1) }));
|
||||
triggers.push_back(new TriggerNode("new pet", { NextAction("set pet stance", 60.0f) }));
|
||||
}
|
||||
|
||||
void DruidCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member cure poison",
|
||||
{ NextAction("abolish poison on party", ACTION_DISPEL + 1) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member remove curse",
|
||||
{ NextAction("remove curse on party", ACTION_DISPEL + 7) }));
|
||||
|
||||
}
|
||||
|
||||
void DruidBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"nature's swiftness", { NextAction("nature's swiftness", ACTION_HIGH + 9) }));
|
||||
}
|
||||
|
||||
void DruidCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"entangling roots", { NextAction("entangling roots on cc", ACTION_HIGH + 2) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"entangling roots kite", { NextAction("entangling roots", ACTION_HIGH + 2) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"hibernate", { NextAction("hibernate on cc", ACTION_HIGH + 3) }));
|
||||
}
|
||||
|
||||
void DruidHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("healer should attack",
|
||||
{
|
||||
NextAction("cancel tree form", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("moonfire", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("wrath", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("starfire", ACTION_DEFAULT),
|
||||
}));
|
||||
|
||||
}
|
||||
58
src/Ai/Class/Druid/Strategy/GenericDruidStrategy.h
Normal file
58
src/Ai/Class/Druid/Strategy/GenericDruidStrategy.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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_GENERICDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICDRUIDSTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericDruidStrategy : public CombatStrategy
|
||||
{
|
||||
protected:
|
||||
GenericDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
public:
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class DruidCureStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
DruidCureStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cure"; }
|
||||
};
|
||||
|
||||
class DruidBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
DruidBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "boost"; }
|
||||
};
|
||||
|
||||
class DruidCcStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
DruidCcStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cc"; }
|
||||
};
|
||||
|
||||
class DruidHealerDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
DruidHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "healer dps"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
101
src/Ai/Class/Druid/Strategy/HealDruidStrategy.cpp
Normal file
101
src/Ai/Class/Druid/Strategy/HealDruidStrategy.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 "HealDruidStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class HealDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
HealDruidStrategyActionNodeFactory() {
|
||||
creators["nourish on party"] = &nourtish_on_party;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* nourtish_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("nourish on party",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("healing touch on party") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
HealDruidStrategy::HealDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new HealDruidStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void HealDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"party member to heal out of spell range",
|
||||
{ NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 9) }));
|
||||
|
||||
// CRITICAL
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member critical health",
|
||||
{
|
||||
NextAction("tree form", ACTION_CRITICAL_HEAL + 4.1f),
|
||||
NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 4),
|
||||
NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 3),
|
||||
NextAction("wild growth on party", ACTION_CRITICAL_HEAL + 2),
|
||||
NextAction("nourish on party", ACTION_CRITICAL_HEAL + 1),
|
||||
}));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member critical health",
|
||||
{ NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4) }));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"group heal setting",
|
||||
{
|
||||
NextAction("tree form", ACTION_MEDIUM_HEAL + 2.3f),
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 2.2f),
|
||||
NextAction("rejuvenation on not full", ACTION_MEDIUM_HEAL + 2.1f),
|
||||
}));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium group heal setting",
|
||||
{
|
||||
NextAction("tree form", ACTION_CRITICAL_HEAL + 0.6f),
|
||||
NextAction("tranquility", ACTION_CRITICAL_HEAL + 0.5f) }));
|
||||
|
||||
// LOW
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member low health",
|
||||
{ NextAction("tree form", ACTION_MEDIUM_HEAL + 1.5f),
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 1.4f),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 1.3f),
|
||||
NextAction("swiftmend on party", ACTION_MEDIUM_HEAL + 1.2),
|
||||
NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1.1f),
|
||||
}));
|
||||
|
||||
// MEDIUM
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member medium health",
|
||||
{
|
||||
NextAction("tree form", ACTION_MEDIUM_HEAL + 0.5f),
|
||||
NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 0.4f),
|
||||
NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 0.3f),
|
||||
NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 0.2f),
|
||||
NextAction("nourish on party", ACTION_MEDIUM_HEAL + 0.1f) }));
|
||||
|
||||
// almost full
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member almost full health",
|
||||
{ NextAction("wild growth on party", ACTION_LIGHT_HEAL + 0.3f),
|
||||
NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 0.2f),
|
||||
NextAction("regrowth on party", ACTION_LIGHT_HEAL + 0.1f) }));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium mana", { NextAction("innervate", ACTION_HIGH + 5) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell",
|
||||
{ NextAction("flee", ACTION_MOVE + 9) }));
|
||||
}
|
||||
24
src/Ai/Class/Druid/Strategy/HealDruidStrategy.h
Normal file
24
src/Ai/Class/Druid/Strategy/HealDruidStrategy.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_HEALDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_HEALDRUIDSTRATEGY_H
|
||||
|
||||
#include "GenericDruidStrategy.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class HealDruidStrategy : public GenericDruidStrategy
|
||||
{
|
||||
public:
|
||||
HealDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "heal"; }
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_RANGED | STRATEGY_TYPE_HEAL; }
|
||||
};
|
||||
|
||||
#endif
|
||||
32
src/Ai/Class/Druid/Strategy/MeleeDruidStrategy.cpp
Normal file
32
src/Ai/Class/Druid/Strategy/MeleeDruidStrategy.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 "MeleeDruidStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
MeleeDruidStrategy::MeleeDruidStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
std::vector<NextAction> MeleeDruidStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("faerie fire", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void MeleeDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"omen of clarity",
|
||||
{
|
||||
NextAction("omen of clarity", ACTION_HIGH + 9)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
}
|
||||
21
src/Ai/Class/Druid/Strategy/MeleeDruidStrategy.h
Normal file
21
src/Ai/Class/Druid/Strategy/MeleeDruidStrategy.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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_MELEEDRUIDSTRATEGY_H
|
||||
#define _PLAYERBOT_MELEEDRUIDSTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class MeleeDruidStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
MeleeDruidStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "melee"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
307
src/Ai/Class/Druid/Strategy/OffhealDruidCatStrategy.cpp
Normal file
307
src/Ai/Class/Druid/Strategy/OffhealDruidCatStrategy.cpp
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* 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 "OffhealDruidCatStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class OffhealDruidCatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
OffhealDruidCatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["cat form"] = &cat_form;
|
||||
creators["mangle (cat)"] = &mangle_cat;
|
||||
creators["shred"] = &shred;
|
||||
creators["rake"] = &rake;
|
||||
creators["rip"] = &rip;
|
||||
creators["ferocious bite"] = &ferocious_bite;
|
||||
creators["savage roar"] = &savage_roar;
|
||||
creators["faerie fire (feral)"] = &faerie_fire_feral;
|
||||
creators["healing touch on party"] = &healing_touch_on_party;
|
||||
creators["regrowth on party"] = ®rowth_on_party;
|
||||
creators["rejuvenation on party"] = &rejuvenation_on_party;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* cat_form([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"cat form",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* mangle_cat([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"mangle (cat)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* shred([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"shred",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("claw") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rake([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rake",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rip([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rip",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* ferocious_bite([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"ferocious bite",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("rip") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* savage_roar([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"savage roar",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* faerie_fire_feral([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"faerie fire (feral)",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* healing_touch_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"healing touch on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ { NextAction("cat form") }
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"regrowth on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ { NextAction("cat form") }
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"rejuvenation on party",
|
||||
/*P*/ { NextAction("caster form") },
|
||||
/*A*/ {},
|
||||
/*C*/ { NextAction("cat form") }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
OffhealDruidCatStrategy::OffhealDruidCatStrategy(PlayerbotAI* botAI) : FeralDruidStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new OffhealDruidCatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> OffhealDruidCatStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("mangle (cat)", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("shred", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("rake", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("melee", ACTION_DEFAULT),
|
||||
NextAction("cat form", ACTION_DEFAULT - 0.1f)
|
||||
};
|
||||
}
|
||||
|
||||
void OffhealDruidCatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
FeralDruidStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"cat form",
|
||||
{
|
||||
NextAction("cat form", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"savage roar",
|
||||
{
|
||||
NextAction("savage roar", ACTION_HIGH + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points available",
|
||||
{
|
||||
NextAction("rip", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"ferocious bite time",
|
||||
{
|
||||
NextAction("ferocious bite", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target with combo points almost dead",
|
||||
{
|
||||
NextAction("ferocious bite", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"mangle (cat)",
|
||||
{
|
||||
NextAction("mangle (cat)", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"rake",
|
||||
{
|
||||
NextAction("rake", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"almost full energy available",
|
||||
{
|
||||
NextAction("shred", ACTION_DEFAULT + 0.4f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"combo points not full",
|
||||
{
|
||||
NextAction("shred", ACTION_DEFAULT + 0.4f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"faerie fire (feral)",
|
||||
{
|
||||
NextAction("faerie fire (feral)", ACTION_NORMAL)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("feral charge - cat", ACTION_HIGH + 9),
|
||||
NextAction("dash", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("swipe (cat)", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low energy",
|
||||
{
|
||||
NextAction("tiger's fury", ACTION_NORMAL + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member critical health",
|
||||
{
|
||||
NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 6),
|
||||
NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member low health",
|
||||
{
|
||||
NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member medium health",
|
||||
{
|
||||
NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member to heal out of spell range",
|
||||
{
|
||||
NextAction("reach party member to heal", ACTION_EMERGENCY + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("innervate", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
27
src/Ai/Class/Druid/Strategy/OffhealDruidCatStrategy.h
Normal file
27
src/Ai/Class/Druid/Strategy/OffhealDruidCatStrategy.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_OFFHEALDRUIDCATSTRATEGY_H
|
||||
#define _PLAYERBOT_OFFHEALDRUIDCATSTRATEGY_H
|
||||
|
||||
#include "FeralDruidStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class OffhealDruidCatStrategy : public FeralDruidStrategy
|
||||
{
|
||||
public:
|
||||
OffhealDruidCatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "offheal"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override
|
||||
{
|
||||
return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_HEAL | STRATEGY_TYPE_MELEE;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
63
src/Ai/Class/Druid/Trigger/DruidTriggers.cpp
Normal file
63
src/Ai/Class/Druid/Trigger/DruidTriggers.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 "DruidTriggers.h"
|
||||
#include "Player.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool MarkOfTheWildOnPartyTrigger::IsActive()
|
||||
{
|
||||
return BuffOnPartyTrigger::IsActive() && !botAI->HasAura("gift of the wild", GetTarget());
|
||||
}
|
||||
|
||||
bool MarkOfTheWildTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && !botAI->HasAura("gift of the wild", GetTarget());
|
||||
}
|
||||
|
||||
bool ThornsOnPartyTrigger::IsActive()
|
||||
{
|
||||
return BuffOnPartyTrigger::IsActive() && !botAI->HasAura("thorns", GetTarget());
|
||||
}
|
||||
|
||||
bool EntanglingRootsKiteTrigger::IsActive()
|
||||
{
|
||||
return DebuffTrigger::IsActive() && AI_VALUE(uint8, "attacker count") < 3 && !GetTarget()->GetPower(POWER_MANA);
|
||||
}
|
||||
|
||||
bool ThornsTrigger::IsActive() { return BuffTrigger::IsActive() && !botAI->HasAura("thorns", GetTarget()); }
|
||||
|
||||
bool BearFormTrigger::IsActive() { return !botAI->HasAnyAuraOf(bot, "bear form", "dire bear form", nullptr); }
|
||||
|
||||
bool TreeFormTrigger::IsActive() { return !botAI->HasAura(33891, bot); }
|
||||
|
||||
bool CatFormTrigger::IsActive() { return !botAI->HasAura("cat form", bot); }
|
||||
|
||||
const std::set<uint32> HurricaneChannelCheckTrigger::HURRICANE_SPELL_IDS = {
|
||||
16914, // Hurricane Rank 1
|
||||
17401, // Hurricane Rank 2
|
||||
17402, // Hurricane Rank 3
|
||||
27012, // Hurricane Rank 4
|
||||
48467 // Hurricane Rank 5
|
||||
};
|
||||
|
||||
bool HurricaneChannelCheckTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
// Check if the bot is channeling a spell
|
||||
if (Spell* spell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
{
|
||||
// Only trigger if the spell being channeled is Hurricane
|
||||
if (HURRICANE_SPELL_IDS.count(spell->m_spellInfo->Id))
|
||||
{
|
||||
uint8 attackerCount = AI_VALUE(uint8, "attacker count");
|
||||
return attackerCount < minEnemies;
|
||||
}
|
||||
}
|
||||
|
||||
// Not channeling Hurricane
|
||||
return false;
|
||||
}
|
||||
283
src/Ai/Class/Druid/Trigger/DruidTriggers.h
Normal file
283
src/Ai/Class/Druid/Trigger/DruidTriggers.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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_DRUIDTRIGGERS_H
|
||||
#define _PLAYERBOT_DRUIDTRIGGERS_H
|
||||
|
||||
#include "CureTriggers.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Trigger.h"
|
||||
#include <set>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class MarkOfTheWildOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
MarkOfTheWildOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "mark of the wild", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MarkOfTheWildTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
MarkOfTheWildTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mark of the wild", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class ThornsOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
ThornsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "thorns", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class ThornsOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
{
|
||||
public:
|
||||
ThornsOnMainTankTrigger(PlayerbotAI* botAI) : BuffOnMainTankTrigger(botAI, "thorns", false, 2 * 2000) {}
|
||||
};
|
||||
|
||||
class ThornsTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
ThornsTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "thorns", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class OmenOfClarityTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
OmenOfClarityTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "omen of clarity") {}
|
||||
};
|
||||
|
||||
class RakeTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
RakeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rake", 1, true) {}
|
||||
};
|
||||
|
||||
class InsectSwarmTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
InsectSwarmTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "insect swarm", 1, true) {}
|
||||
};
|
||||
|
||||
class MoonfireTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
MoonfireTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "moonfire", 1, true) {}
|
||||
};
|
||||
|
||||
class FaerieFireTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FaerieFireTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "faerie fire", 1, false, 25.0f) {}
|
||||
};
|
||||
|
||||
class FaerieFireFeralTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FaerieFireFeralTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "faerie fire (feral)") {}
|
||||
};
|
||||
|
||||
class BashInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
BashInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "bash") {}
|
||||
};
|
||||
|
||||
class TigersFuryTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
TigersFuryTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "tiger's fury") {}
|
||||
};
|
||||
|
||||
class BerserkTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
BerserkTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "berserk") {}
|
||||
};
|
||||
|
||||
class SavageRoarTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
SavageRoarTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "savage roar") {}
|
||||
};
|
||||
|
||||
class NaturesGraspTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
NaturesGraspTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "nature's grasp") {}
|
||||
};
|
||||
|
||||
class EntanglingRootsTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
EntanglingRootsTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "entangling roots") {}
|
||||
};
|
||||
|
||||
class EntanglingRootsKiteTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
EntanglingRootsKiteTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "entangling roots") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HibernateTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
HibernateTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "hibernate") {}
|
||||
};
|
||||
|
||||
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 BearFormTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
BearFormTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "bear form") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class TreeFormTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
TreeFormTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "tree of life") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class CatFormTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
CatFormTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "cat form") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class EclipseSolarTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
EclipseSolarTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "eclipse (solar)") {}
|
||||
};
|
||||
|
||||
class EclipseLunarTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
EclipseLunarTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "eclipse (lunar)") {}
|
||||
};
|
||||
|
||||
class BashInterruptEnemyHealerSpellTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
BashInterruptEnemyHealerSpellTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "bash") {}
|
||||
};
|
||||
|
||||
class NaturesSwiftnessTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
NaturesSwiftnessTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "nature's swiftness") {}
|
||||
};
|
||||
|
||||
class DruidPartyMemberRemoveCurseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
DruidPartyMemberRemoveCurseTrigger(PlayerbotAI* ai)
|
||||
: PartyMemberNeedCureTrigger(ai, "druid remove curse", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class EclipseSolarCooldownTrigger : public SpellCooldownTrigger
|
||||
{
|
||||
public:
|
||||
EclipseSolarCooldownTrigger(PlayerbotAI* ai) : SpellCooldownTrigger(ai, "eclipse (solar)") {}
|
||||
bool IsActive() override { return bot->HasSpellCooldown(48517); }
|
||||
};
|
||||
|
||||
class EclipseLunarCooldownTrigger : public SpellCooldownTrigger
|
||||
{
|
||||
public:
|
||||
EclipseLunarCooldownTrigger(PlayerbotAI* ai) : SpellCooldownTrigger(ai, "eclipse (lunar)") {}
|
||||
bool IsActive() override { return bot->HasSpellCooldown(48518); }
|
||||
};
|
||||
|
||||
class MangleCatTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
MangleCatTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "mangle (cat)", 1, false, 0.0f) {}
|
||||
bool IsActive() override
|
||||
{
|
||||
return DebuffTrigger::IsActive() && !botAI->HasAura("mangle (bear)", GetTarget(), false, false, -1, true)
|
||||
&& !botAI->HasAura("trauma", GetTarget(), false, false, -1, true);
|
||||
}
|
||||
};
|
||||
|
||||
class FerociousBiteTimeTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
FerociousBiteTimeTrigger(PlayerbotAI* ai) : Trigger(ai, "ferocious bite time") {}
|
||||
bool IsActive() override
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
uint8 cp = AI_VALUE2(uint8, "combo", "current target");
|
||||
if (cp < 5)
|
||||
return false;
|
||||
|
||||
Aura* roar = botAI->GetAura("savage roar", bot);
|
||||
bool roarCheck = !roar || roar->GetDuration() > 10000;
|
||||
if (!roarCheck)
|
||||
return false;
|
||||
|
||||
Aura* rip = botAI->GetAura("rip", target, true);
|
||||
bool ripCheck = !rip || rip->GetDuration() > 10000;
|
||||
if (!ripCheck)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class HurricaneChannelCheckTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
HurricaneChannelCheckTrigger(PlayerbotAI* botAI, uint32 minEnemies = 2)
|
||||
: Trigger(botAI, "hurricane channel check"), minEnemies(minEnemies)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
uint32 minEnemies;
|
||||
static const std::set<uint32> HURRICANE_SPELL_IDS;
|
||||
};
|
||||
|
||||
#endif
|
||||
109
src/Ai/Class/Hunter/Action/HunterActions.cpp
Normal file
109
src/Ai/Class/Hunter/Action/HunterActions.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 "HunterActions.h"
|
||||
|
||||
#include "Event.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool CastViperStingAction::isUseful()
|
||||
{
|
||||
return CastAuraSpellAction::isUseful() && AI_VALUE2(uint8, "mana", "self target") < 50 &&
|
||||
AI_VALUE2(uint8, "mana", "current target") >= 30;
|
||||
}
|
||||
|
||||
bool CastAspectOfTheCheetahAction::isUseful()
|
||||
{
|
||||
return !botAI->HasAnyAuraOf(GetTarget(), "aspect of the cheetah", "aspect of the pack", nullptr);
|
||||
}
|
||||
|
||||
bool CastAspectOfTheHawkAction::isUseful()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
if (bot->HasSpell(61846) || bot->HasSpell(61847)) // Aspect of the Dragonhawk spell IDs
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastArcaneShotAction::isUseful()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
if (bot->HasSpell(53301) || bot->HasSpell(60051) || bot->HasSpell(60052) || bot->HasSpell(60053)) // Explosive Shot spell IDs
|
||||
return false;
|
||||
|
||||
// Armor Penetration rating check - will not cast Arcane Shot above 435 ArP
|
||||
int32 armorPenRating = bot->GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1) + bot->GetUInt32Value(CR_ARMOR_PENETRATION);
|
||||
if (armorPenRating > 435)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastImmolationTrapAction::isUseful()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
if (bot->HasSpell(13813) || bot->HasSpell(14316) || bot->HasSpell(14317) || bot->HasSpell(27025) || bot->HasSpell(49066) || bot->HasSpell(49067)) // Explosive Trap spell IDs
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Value<Unit*>* CastFreezingTrap::GetTargetValue() { return context->GetValue<Unit*>("cc target", "freezing trap"); }
|
||||
|
||||
bool FeedPetAction::Execute(Event event)
|
||||
{
|
||||
if (Pet* pet = bot->GetPet())
|
||||
if (pet->getPetType() == HUNTER_PET && pet->GetHappinessState() != HAPPY)
|
||||
pet->SetPower(POWER_HAPPINESS, pet->GetMaxPower(Powers(POWER_HAPPINESS)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastAutoShotAction::isUseful()
|
||||
{
|
||||
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
|
||||
return false;
|
||||
|
||||
if (AI_VALUE(Unit*, "current target") && bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) &&
|
||||
bot->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_targets.GetUnitTargetGUID() ==
|
||||
AI_VALUE(Unit*, "current target")->GetGUID())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return AI_VALUE(uint32, "active spell") != AI_VALUE2(uint32, "spell id", getName());
|
||||
}
|
||||
|
||||
bool CastDisengageAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
// can cast spell check passed in isUseful()
|
||||
bot->SetOrientation(bot->GetAngle(target));
|
||||
return CastSpellAction::Execute(event);
|
||||
}
|
||||
|
||||
bool CastDisengageAction::isUseful()
|
||||
{
|
||||
return !botAI->HasStrategy("trap weave", BOT_STATE_COMBAT);
|
||||
}
|
||||
|
||||
Value<Unit*>* CastScareBeastCcAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", "scare beast"); }
|
||||
|
||||
bool CastScareBeastCcAction::Execute(Event event) { return botAI->CastSpell("scare beast", GetTarget()); }
|
||||
|
||||
bool CastWingClipAction::isUseful() { return CastSpellAction::isUseful() && !botAI->HasAura(spell, GetTarget()); }
|
||||
|
||||
std::vector<NextAction> CastWingClipAction::getPrerequisites()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
451
src/Ai/Class/Hunter/Action/HunterActions.h
Normal file
451
src/Ai/Class/Hunter/Action/HunterActions.h
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* 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_HUNTERACTIONS_H
|
||||
#define _PLAYERBOT_HUNTERACTIONS_H
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "Event.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
|
||||
// Buff and Out of Combat Spells
|
||||
|
||||
class CastTrueshotAuraAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTrueshotAuraAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "trueshot aura") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheHawkAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheHawkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the hawk") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastAspectOfTheMonkeyAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheMonkeyAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the monkey") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheDragonhawkAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheDragonhawkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the dragonhawk") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheWildAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheWildAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the wild") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheCheetahAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheCheetahAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the cheetah") {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastAspectOfThePackAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfThePackAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the pack") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheViperAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAspectOfTheViperAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the viper") {}
|
||||
};
|
||||
|
||||
// Cooldown Spells
|
||||
|
||||
class CastRapidFireAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastRapidFireAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "rapid fire") {}
|
||||
};
|
||||
|
||||
class CastDeterrenceAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeterrenceAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "deterrence") {}
|
||||
};
|
||||
|
||||
class CastReadinessAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastReadinessAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "readiness") {}
|
||||
};
|
||||
|
||||
class CastDisengageAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDisengageAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "disengage") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
// CC Spells
|
||||
|
||||
class CastScareBeastAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastScareBeastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "scare beast") {}
|
||||
};
|
||||
|
||||
class CastScareBeastCcAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastScareBeastCcAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "scare beast on cc") {}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastFreezingTrap : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFreezingTrap(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "freezing trap") {}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
};
|
||||
|
||||
class CastWyvernStingAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastWyvernStingAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "wyvern sting", true) {}
|
||||
};
|
||||
|
||||
class CastSilencingShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastSilencingShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "silencing shot") {}
|
||||
};
|
||||
|
||||
class CastConcussiveShotAction : public CastSnareSpellAction
|
||||
{
|
||||
public:
|
||||
CastConcussiveShotAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "concussive shot") {}
|
||||
};
|
||||
|
||||
class CastIntimidationAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIntimidationAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "intimidation", false, 5000) {}
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
// Threat Spells
|
||||
|
||||
class CastDistractingShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDistractingShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "distracting shot") {}
|
||||
};
|
||||
|
||||
class CastMisdirectionOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastMisdirectionOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "misdirection", true) {}
|
||||
};
|
||||
|
||||
class CastFeignDeathAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFeignDeathAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "feign death") {}
|
||||
};
|
||||
|
||||
// Pet Spells
|
||||
|
||||
class FeedPetAction : public Action
|
||||
{
|
||||
public:
|
||||
FeedPetAction(PlayerbotAI* botAI) : Action(botAI, "feed pet") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastCallPetAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCallPetAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "call pet") {}
|
||||
};
|
||||
|
||||
class CastMendPetAction : public CastAuraSpellAction
|
||||
{
|
||||
public:
|
||||
CastMendPetAction(PlayerbotAI* botAI) : CastAuraSpellAction(botAI, "mend pet") {}
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
class CastRevivePetAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastRevivePetAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "revive pet") {}
|
||||
};
|
||||
|
||||
class CastKillCommandAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastKillCommandAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "kill command", false, 5000) {}
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
class CastBestialWrathAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBestialWrathAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "bestial wrath", false, 5000) {}
|
||||
std::string const GetTargetName() override { return "pet target"; }
|
||||
};
|
||||
|
||||
// Direct Damage Spells
|
||||
|
||||
class CastAutoShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastAutoShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "auto shot") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::None; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastArcaneShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "arcane shot") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastAimedShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastAimedShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "aimed shot") {}
|
||||
};
|
||||
|
||||
class CastChimeraShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastChimeraShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "chimera shot") {}
|
||||
};
|
||||
|
||||
class CastSteadyShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastSteadyShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "steady shot") {}
|
||||
};
|
||||
|
||||
class CastKillShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastKillShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "kill shot") {}
|
||||
};
|
||||
|
||||
// DoT/Debuff Spells
|
||||
|
||||
class CastHuntersMarkAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastHuntersMarkAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "hunter's mark") {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastTranquilizingShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastTranquilizingShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "tranquilizing shot") {}
|
||||
};
|
||||
|
||||
class CastViperStingAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastViperStingAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "viper sting", true) {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastSerpentStingAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSerpentStingAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "serpent sting", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastScorpidStingAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastScorpidStingAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "scorpid sting", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastSerpentStingOnAttackerAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastSerpentStingOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "serpent sting", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastImmolationTrapAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastImmolationTrapAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "immolation trap") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastExplosiveTrapAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveTrapAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "explosive trap") {}
|
||||
};
|
||||
|
||||
class CastBlackArrow : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlackArrow(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "black arrow", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
if (botAI->HasStrategy("trap weave", BOT_STATE_COMBAT))
|
||||
return false;
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastExplosiveShotAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveShotAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "explosive shot", true, 0.0f) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
// Rank 4
|
||||
class CastExplosiveShotRank4Action : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveShotRank4Action(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "explosive shot", true, 0.0f) {}
|
||||
|
||||
bool Execute(Event event) override { return botAI->CastSpell(60053, GetTarget()); }
|
||||
bool isUseful() override
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
return !target->HasAura(60053);
|
||||
}
|
||||
};
|
||||
|
||||
// Rank 3
|
||||
class CastExplosiveShotRank3Action : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveShotRank3Action(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "explosive shot", true, 0.0f) {}
|
||||
|
||||
bool Execute(Event event) override { return botAI->CastSpell(60052, GetTarget()); }
|
||||
bool isUseful() override
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
return !target->HasAura(60052);
|
||||
}
|
||||
};
|
||||
|
||||
// Rank 2
|
||||
class CastExplosiveShotRank2Action : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveShotRank2Action(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "explosive shot", true, 0.0f) {}
|
||||
|
||||
bool Execute(Event event) override { return botAI->CastSpell(60051, GetTarget()); }
|
||||
bool isUseful() override
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
return !target->HasAura(60051);
|
||||
}
|
||||
};
|
||||
|
||||
// Rank 1
|
||||
class CastExplosiveShotRank1Action : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveShotRank1Action(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "explosive shot", true, 0.0f) {}
|
||||
|
||||
bool Execute(Event event) override { return botAI->CastSpell(53301, GetTarget()); }
|
||||
bool isUseful() override
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
return !target->HasAura(53301);
|
||||
}
|
||||
};
|
||||
|
||||
// Melee Spells
|
||||
|
||||
class CastWingClipAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastWingClipAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "wing clip") {}
|
||||
|
||||
bool isUseful() override;
|
||||
std::vector<NextAction> getPrerequisites() override;
|
||||
};
|
||||
|
||||
class CastRaptorStrikeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastRaptorStrikeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "raptor strike") {}
|
||||
};
|
||||
|
||||
class CastMongooseBiteAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastMongooseBiteAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "mongoose bite") {}
|
||||
};
|
||||
|
||||
// AoE Spells
|
||||
|
||||
class CastMultiShotAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastMultiShotAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "multi-shot") {}
|
||||
};
|
||||
|
||||
class CastVolleyAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastVolleyAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "volley") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
#endif
|
||||
307
src/Ai/Class/Hunter/HunterAiObjectContext.cpp
Normal file
307
src/Ai/Class/Hunter/HunterAiObjectContext.cpp
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* 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 "HunterAiObjectContext.h"
|
||||
|
||||
#include "BeastMasteryHunterStrategy.h"
|
||||
#include "GenericHunterNonCombatStrategy.h"
|
||||
#include "GenericHunterStrategy.h"
|
||||
#include "HunterActions.h"
|
||||
#include "HunterBuffStrategies.h"
|
||||
#include "HunterTriggers.h"
|
||||
#include "MarksmanshipHunterStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SurvivalHunterStrategy.h"
|
||||
|
||||
class HunterStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
HunterStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &HunterStrategyFactoryInternal::nc;
|
||||
creators["boost"] = &HunterStrategyFactoryInternal::boost;
|
||||
creators["pet"] = &HunterStrategyFactoryInternal::pet;
|
||||
creators["cc"] = &HunterStrategyFactoryInternal::cc;
|
||||
creators["trap weave"] = &HunterStrategyFactoryInternal::trap_weave;
|
||||
creators["bm"] = &HunterStrategyFactoryInternal::beast_mastery;
|
||||
creators["mm"] = &HunterStrategyFactoryInternal::marksmanship;
|
||||
creators["surv"] = &HunterStrategyFactoryInternal::survival;
|
||||
creators["aoe"] = &HunterStrategyFactoryInternal::aoe;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericHunterNonCombatStrategy(botAI); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new HunterBoostStrategy(botAI); }
|
||||
static Strategy* pet(PlayerbotAI* botAI) { return new HunterPetStrategy(botAI); }
|
||||
static Strategy* cc(PlayerbotAI* botAI) { return new HunterCcStrategy(botAI); }
|
||||
static Strategy* trap_weave(PlayerbotAI* botAI) { return new HunterTrapWeaveStrategy(botAI); }
|
||||
static Strategy* beast_mastery(PlayerbotAI* botAI) { return new BeastMasteryHunterStrategy(botAI); }
|
||||
static Strategy* marksmanship(PlayerbotAI* botAI) { return new MarksmanshipHunterStrategy(botAI); }
|
||||
static Strategy* survival(PlayerbotAI* botAI) { return new SurvivalHunterStrategy(botAI); }
|
||||
static Strategy* aoe(PlayerbotAI* botAI) { return new AoEHunterStrategy(botAI); }
|
||||
};
|
||||
|
||||
class HunterBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
HunterBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bspeed"] = &HunterBuffStrategyFactoryInternal::bspeed;
|
||||
creators["bdps"] = &HunterBuffStrategyFactoryInternal::bdps;
|
||||
creators["bmana"] = &HunterBuffStrategyFactoryInternal::bmana;
|
||||
creators["rnature"] = &HunterBuffStrategyFactoryInternal::rnature;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bspeed(PlayerbotAI* botAI) { return new HunterBuffSpeedStrategy(botAI); }
|
||||
static Strategy* bdps(PlayerbotAI* botAI) { return new HunterBuffDpsStrategy(botAI); }
|
||||
static Strategy* bmana(PlayerbotAI* botAI) { return new HunterBuffManaStrategy(botAI); }
|
||||
static Strategy* rnature(PlayerbotAI* botAI) { return new HunterNatureResistanceStrategy(botAI); }
|
||||
};
|
||||
|
||||
class HunterTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
HunterTriggerFactoryInternal()
|
||||
{
|
||||
creators["aspect of the viper"] = &HunterTriggerFactoryInternal::aspect_of_the_viper;
|
||||
creators["black arrow"] = &HunterTriggerFactoryInternal::black_arrow;
|
||||
creators["no stings"] = &HunterTriggerFactoryInternal::NoStings;
|
||||
creators["hunters pet dead"] = &HunterTriggerFactoryInternal::hunters_pet_dead;
|
||||
creators["hunters pet low health"] = &HunterTriggerFactoryInternal::hunters_pet_low_health;
|
||||
creators["hunters pet medium health"] = &HunterTriggerFactoryInternal::hunters_pet_medium_health;
|
||||
creators["hunter's mark"] = &HunterTriggerFactoryInternal::hunters_mark;
|
||||
creators["freezing trap"] = &HunterTriggerFactoryInternal::freezing_trap;
|
||||
creators["aspect of the pack"] = &HunterTriggerFactoryInternal::aspect_of_the_pack;
|
||||
creators["rapid fire"] = &HunterTriggerFactoryInternal::rapid_fire;
|
||||
creators["aspect of the hawk"] = &HunterTriggerFactoryInternal::aspect_of_the_hawk;
|
||||
creators["aspect of the monkey"] = &HunterTriggerFactoryInternal::aspect_of_the_monkey;
|
||||
creators["aspect of the wild"] = &HunterTriggerFactoryInternal::aspect_of_the_wild;
|
||||
creators["aspect of the viper"] = &HunterTriggerFactoryInternal::aspect_of_the_viper;
|
||||
creators["trueshot aura"] = &HunterTriggerFactoryInternal::trueshot_aura;
|
||||
creators["no track"] = &HunterTriggerFactoryInternal::no_track;
|
||||
creators["serpent sting on attacker"] = &HunterTriggerFactoryInternal::serpent_sting_on_attacker;
|
||||
creators["pet not happy"] = &HunterTriggerFactoryInternal::pet_not_happy;
|
||||
creators["concussive shot on snare target"] = &HunterTriggerFactoryInternal::concussive_shot_on_snare_target;
|
||||
creators["scare beast"] = &HunterTriggerFactoryInternal::scare_beast;
|
||||
creators["low ammo"] = &HunterTriggerFactoryInternal::low_ammo;
|
||||
creators["no ammo"] = &HunterTriggerFactoryInternal::no_ammo;
|
||||
creators["has ammo"] = &HunterTriggerFactoryInternal::has_ammo;
|
||||
creators["switch to melee"] = &HunterTriggerFactoryInternal::switch_to_melee;
|
||||
creators["switch to ranged"] = &HunterTriggerFactoryInternal::switch_to_ranged;
|
||||
creators["misdirection on main tank"] = &HunterTriggerFactoryInternal::misdirection_on_main_tank;
|
||||
creators["tranquilizing shot enrage"] = &HunterTriggerFactoryInternal::remove_enrage;
|
||||
creators["tranquilizing shot magic"] = &HunterTriggerFactoryInternal::remove_magic;
|
||||
creators["immolation trap no cd"] = &HunterTriggerFactoryInternal::immolation_trap_no_cd;
|
||||
creators["kill command"] = &HunterTriggerFactoryInternal::kill_command;
|
||||
creators["explosive shot"] = &HunterTriggerFactoryInternal::explosive_shot;
|
||||
creators["lock and load"] = &HunterTriggerFactoryInternal::lock_and_load;
|
||||
creators["silencing shot"] = &HunterTriggerFactoryInternal::silencing_shot;
|
||||
creators["intimidation"] = &HunterTriggerFactoryInternal::intimidation;
|
||||
creators["volley channel check"] = &HunterTriggerFactoryInternal::volley_channel_check;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* auto_shot(PlayerbotAI* botAI) { return new AutoShotTrigger(botAI); }
|
||||
static Trigger* scare_beast(PlayerbotAI* botAI) { return new ScareBeastTrigger(botAI); }
|
||||
static Trigger* concussive_shot_on_snare_target(PlayerbotAI* botAI)
|
||||
{
|
||||
return new ConsussiveShotSnareTrigger(botAI);
|
||||
}
|
||||
static Trigger* pet_not_happy(PlayerbotAI* botAI) { return new HunterPetNotHappy(botAI); }
|
||||
static Trigger* serpent_sting_on_attacker(PlayerbotAI* botAI) { return new SerpentStingOnAttackerTrigger(botAI); }
|
||||
static Trigger* trueshot_aura(PlayerbotAI* botAI) { return new TrueshotAuraTrigger(botAI); }
|
||||
static Trigger* no_track(PlayerbotAI* botAI) { return new NoTrackTrigger(botAI); }
|
||||
static Trigger* aspect_of_the_viper(PlayerbotAI* botAI) { return new HunterAspectOfTheViperTrigger(botAI); }
|
||||
static Trigger* black_arrow(PlayerbotAI* botAI) { return new BlackArrowTrigger(botAI); }
|
||||
static Trigger* NoStings(PlayerbotAI* botAI) { return new HunterNoStingsActiveTrigger(botAI); }
|
||||
static Trigger* hunters_pet_dead(PlayerbotAI* botAI) { return new HuntersPetDeadTrigger(botAI); }
|
||||
static Trigger* hunters_pet_low_health(PlayerbotAI* botAI) { return new HuntersPetLowHealthTrigger(botAI); }
|
||||
static Trigger* hunters_pet_medium_health(PlayerbotAI* botAI) { return new HuntersPetMediumHealthTrigger(botAI); }
|
||||
static Trigger* hunters_mark(PlayerbotAI* botAI) { return new HuntersMarkTrigger(botAI); }
|
||||
static Trigger* freezing_trap(PlayerbotAI* botAI) { return new FreezingTrapTrigger(botAI); }
|
||||
static Trigger* aspect_of_the_pack(PlayerbotAI* botAI) { return new HunterAspectOfThePackTrigger(botAI); }
|
||||
static Trigger* rapid_fire(PlayerbotAI* botAI) { return new RapidFireTrigger(botAI); }
|
||||
static Trigger* aspect_of_the_hawk(PlayerbotAI* botAI) { return new HunterAspectOfTheHawkTrigger(botAI); }
|
||||
static Trigger* aspect_of_the_monkey(PlayerbotAI* botAI) { return new HunterAspectOfTheMonkeyTrigger(botAI); }
|
||||
static Trigger* aspect_of_the_wild(PlayerbotAI* botAI) { return new HunterAspectOfTheWildTrigger(botAI); }
|
||||
static Trigger* low_ammo(PlayerbotAI* botAI) { return new HunterLowAmmoTrigger(botAI); }
|
||||
static Trigger* no_ammo(PlayerbotAI* botAI) { return new HunterNoAmmoTrigger(botAI); }
|
||||
static Trigger* has_ammo(PlayerbotAI* botAI) { return new HunterHasAmmoTrigger(botAI); }
|
||||
static Trigger* switch_to_melee(PlayerbotAI* botAI) { return new SwitchToMeleeTrigger(botAI); }
|
||||
static Trigger* switch_to_ranged(PlayerbotAI* botAI) { return new SwitchToRangedTrigger(botAI); }
|
||||
static Trigger* misdirection_on_main_tank(PlayerbotAI* ai) { return new MisdirectionOnMainTankTrigger(ai); }
|
||||
static Trigger* remove_enrage(PlayerbotAI* ai) { return new TargetRemoveEnrageTrigger(ai); }
|
||||
static Trigger* remove_magic(PlayerbotAI* ai) { return new TargetRemoveMagicTrigger(ai); }
|
||||
static Trigger* immolation_trap_no_cd(PlayerbotAI* ai) { return new ImmolationTrapNoCdTrigger(ai); }
|
||||
static Trigger* kill_command(PlayerbotAI* botAI) { return new KillCommandTrigger(botAI); }
|
||||
static Trigger* explosive_shot(PlayerbotAI* botAI) { return new ExplosiveShotTrigger(botAI); }
|
||||
static Trigger* lock_and_load(PlayerbotAI* botAI) { return new LockAndLoadTrigger(botAI); }
|
||||
static Trigger* silencing_shot(PlayerbotAI* botAI) { return new SilencingShotTrigger(botAI); }
|
||||
static Trigger* intimidation(PlayerbotAI* botAI) { return new IntimidationTrigger(botAI); }
|
||||
static Trigger* volley_channel_check(PlayerbotAI* botAI) { return new VolleyChannelCheckTrigger(botAI); }
|
||||
};
|
||||
|
||||
class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
HunterAiObjectContextInternal()
|
||||
{
|
||||
creators["auto shot"] = &HunterAiObjectContextInternal::auto_shot;
|
||||
creators["aimed shot"] = &HunterAiObjectContextInternal::aimed_shot;
|
||||
creators["chimera shot"] = &HunterAiObjectContextInternal::chimera_shot;
|
||||
creators["explosive shot"] = &HunterAiObjectContextInternal::explosive_shot;
|
||||
creators["arcane shot"] = &HunterAiObjectContextInternal::arcane_shot;
|
||||
creators["concussive shot"] = &HunterAiObjectContextInternal::concussive_shot;
|
||||
creators["distracting shot"] = &HunterAiObjectContextInternal::distracting_shot;
|
||||
creators["multi-shot"] = &HunterAiObjectContextInternal::multi_shot;
|
||||
creators["volley"] = &HunterAiObjectContextInternal::volley;
|
||||
creators["serpent sting"] = &HunterAiObjectContextInternal::serpent_sting;
|
||||
creators["serpent sting on attacker"] = &HunterAiObjectContextInternal::serpent_sting_on_attacker;
|
||||
creators["wyvern sting"] = &HunterAiObjectContextInternal::wyvern_sting;
|
||||
creators["viper sting"] = &HunterAiObjectContextInternal::viper_sting;
|
||||
creators["scorpid sting"] = &HunterAiObjectContextInternal::scorpid_sting;
|
||||
creators["hunter's mark"] = &HunterAiObjectContextInternal::hunters_mark;
|
||||
creators["mend pet"] = &HunterAiObjectContextInternal::mend_pet;
|
||||
creators["kill command"] = &HunterAiObjectContextInternal::kill_command;
|
||||
creators["revive pet"] = &HunterAiObjectContextInternal::revive_pet;
|
||||
creators["call pet"] = &HunterAiObjectContextInternal::call_pet;
|
||||
creators["black arrow"] = &HunterAiObjectContextInternal::black_arrow;
|
||||
creators["freezing trap"] = &HunterAiObjectContextInternal::freezing_trap;
|
||||
creators["rapid fire"] = &HunterAiObjectContextInternal::rapid_fire;
|
||||
creators["boost"] = &HunterAiObjectContextInternal::rapid_fire;
|
||||
creators["deterrence"] = &HunterAiObjectContextInternal::deterrence;
|
||||
creators["readiness"] = &HunterAiObjectContextInternal::readiness;
|
||||
creators["aspect of the hawk"] = &HunterAiObjectContextInternal::aspect_of_the_hawk;
|
||||
creators["aspect of the monkey"] = &HunterAiObjectContextInternal::aspect_of_the_monkey;
|
||||
creators["aspect of the wild"] = &HunterAiObjectContextInternal::aspect_of_the_wild;
|
||||
creators["aspect of the viper"] = &HunterAiObjectContextInternal::aspect_of_the_viper;
|
||||
creators["aspect of the pack"] = &HunterAiObjectContextInternal::aspect_of_the_pack;
|
||||
creators["aspect of the cheetah"] = &HunterAiObjectContextInternal::aspect_of_the_cheetah;
|
||||
creators["trueshot aura"] = &HunterAiObjectContextInternal::trueshot_aura;
|
||||
creators["track humanoids"] = &HunterAiObjectContextInternal::track_humanoids;
|
||||
creators["feign death"] = &HunterAiObjectContextInternal::feign_death;
|
||||
creators["wing clip"] = &HunterAiObjectContextInternal::wing_clip;
|
||||
creators["raptor strike"] = &HunterAiObjectContextInternal::raptor_strike;
|
||||
creators["mongoose bite"] = &HunterAiObjectContextInternal::mongoose_bite;
|
||||
creators["feed pet"] = &HunterAiObjectContextInternal::feed_pet;
|
||||
creators["bestial wrath"] = &HunterAiObjectContextInternal::bestial_wrath;
|
||||
creators["scare beast"] = &HunterAiObjectContextInternal::scare_beast;
|
||||
creators["scare beast on cc"] = &HunterAiObjectContextInternal::scare_beast_on_cc;
|
||||
creators["aspect of the dragonhawk"] = &HunterAiObjectContextInternal::aspect_of_the_dragonhawk;
|
||||
creators["tranquilizing shot"] = &HunterAiObjectContextInternal::tranquilizing_shot;
|
||||
creators["steady shot"] = &HunterAiObjectContextInternal::steady_shot;
|
||||
creators["kill shot"] = &HunterAiObjectContextInternal::kill_shot;
|
||||
creators["misdirection on main tank"] = &HunterAiObjectContextInternal::misdirection_on_main_tank;
|
||||
creators["silencing shot"] = &HunterAiObjectContextInternal::silencing_shot;
|
||||
creators["disengage"] = &HunterAiObjectContextInternal::disengage;
|
||||
creators["immolation trap"] = &HunterAiObjectContextInternal::immolation_trap;
|
||||
creators["explosive trap"] = &HunterAiObjectContextInternal::explosive_trap;
|
||||
creators["explosive shot rank 4"] = &HunterAiObjectContextInternal::explosive_shot_rank_4;
|
||||
creators["explosive shot rank 3"] = &HunterAiObjectContextInternal::explosive_shot_rank_3;
|
||||
creators["explosive shot rank 2"] = &HunterAiObjectContextInternal::explosive_shot_rank_2;
|
||||
creators["explosive shot rank 1"] = &HunterAiObjectContextInternal::explosive_shot_rank_1;
|
||||
creators["intimidation"] = &HunterAiObjectContextInternal::intimidation;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* scare_beast(PlayerbotAI* botAI) { return new CastScareBeastAction(botAI); }
|
||||
static Action* scare_beast_on_cc(PlayerbotAI* botAI) { return new CastScareBeastCcAction(botAI); }
|
||||
static Action* bestial_wrath(PlayerbotAI* botAI) { return new CastBestialWrathAction(botAI); }
|
||||
static Action* feed_pet(PlayerbotAI* botAI) { return new FeedPetAction(botAI); }
|
||||
static Action* feign_death(PlayerbotAI* botAI) { return new CastFeignDeathAction(botAI); }
|
||||
static Action* trueshot_aura(PlayerbotAI* botAI) { return new CastTrueshotAuraAction(botAI); }
|
||||
static Action* track_humanoids(PlayerbotAI* botAI) { return new CastBuffSpellAction(botAI, "track humanoids"); }
|
||||
static Action* auto_shot(PlayerbotAI* botAI) { return new CastAutoShotAction(botAI); }
|
||||
static Action* aimed_shot(PlayerbotAI* botAI) { return new CastAimedShotAction(botAI); }
|
||||
static Action* chimera_shot(PlayerbotAI* botAI) { return new CastChimeraShotAction(botAI); }
|
||||
static Action* explosive_shot(PlayerbotAI* botAI) { return new CastExplosiveShotAction(botAI); }
|
||||
static Action* arcane_shot(PlayerbotAI* botAI) { return new CastArcaneShotAction(botAI); }
|
||||
static Action* concussive_shot(PlayerbotAI* botAI) { return new CastConcussiveShotAction(botAI); }
|
||||
static Action* distracting_shot(PlayerbotAI* botAI) { return new CastDistractingShotAction(botAI); }
|
||||
static Action* multi_shot(PlayerbotAI* botAI) { return new CastMultiShotAction(botAI); }
|
||||
static Action* volley(PlayerbotAI* botAI) { return new CastVolleyAction(botAI); }
|
||||
static Action* serpent_sting(PlayerbotAI* botAI) { return new CastSerpentStingAction(botAI); }
|
||||
static Action* serpent_sting_on_attacker(PlayerbotAI* botAI) { return new CastSerpentStingOnAttackerAction(botAI); }
|
||||
static Action* wyvern_sting(PlayerbotAI* botAI) { return new CastWyvernStingAction(botAI); }
|
||||
static Action* viper_sting(PlayerbotAI* botAI) { return new CastViperStingAction(botAI); }
|
||||
static Action* scorpid_sting(PlayerbotAI* botAI) { return new CastScorpidStingAction(botAI); }
|
||||
static Action* hunters_mark(PlayerbotAI* botAI) { return new CastHuntersMarkAction(botAI); }
|
||||
static Action* mend_pet(PlayerbotAI* botAI) { return new CastMendPetAction(botAI); }
|
||||
static Action* kill_command(PlayerbotAI* botAI) { return new CastKillCommandAction(botAI); }
|
||||
static Action* revive_pet(PlayerbotAI* botAI) { return new CastRevivePetAction(botAI); }
|
||||
static Action* call_pet(PlayerbotAI* botAI) { return new CastCallPetAction(botAI); }
|
||||
static Action* black_arrow(PlayerbotAI* botAI) { return new CastBlackArrow(botAI); }
|
||||
static Action* freezing_trap(PlayerbotAI* botAI) { return new CastFreezingTrap(botAI); }
|
||||
static Action* rapid_fire(PlayerbotAI* botAI) { return new CastRapidFireAction(botAI); }
|
||||
static Action* deterrence(PlayerbotAI* botAI) { return new CastDeterrenceAction(botAI); }
|
||||
static Action* readiness(PlayerbotAI* botAI) { return new CastReadinessAction(botAI); }
|
||||
static Action* aspect_of_the_hawk(PlayerbotAI* botAI) { return new CastAspectOfTheHawkAction(botAI); }
|
||||
static Action* aspect_of_the_monkey(PlayerbotAI* botAI) { return new CastAspectOfTheMonkeyAction(botAI); }
|
||||
static Action* aspect_of_the_wild(PlayerbotAI* botAI) { return new CastAspectOfTheWildAction(botAI); }
|
||||
static Action* aspect_of_the_viper(PlayerbotAI* botAI) { return new CastAspectOfTheViperAction(botAI); }
|
||||
static Action* aspect_of_the_pack(PlayerbotAI* botAI) { return new CastAspectOfThePackAction(botAI); }
|
||||
static Action* aspect_of_the_cheetah(PlayerbotAI* botAI) { return new CastAspectOfTheCheetahAction(botAI); }
|
||||
static Action* wing_clip(PlayerbotAI* botAI) { return new CastWingClipAction(botAI); }
|
||||
static Action* raptor_strike(PlayerbotAI* botAI) { return new CastRaptorStrikeAction(botAI); }
|
||||
static Action* mongoose_bite(PlayerbotAI* botAI) { return new CastMongooseBiteAction(botAI); }
|
||||
static Action* aspect_of_the_dragonhawk(PlayerbotAI* ai) { return new CastAspectOfTheDragonhawkAction(ai); }
|
||||
static Action* tranquilizing_shot(PlayerbotAI* ai) { return new CastTranquilizingShotAction(ai); }
|
||||
static Action* steady_shot(PlayerbotAI* ai) { return new CastSteadyShotAction(ai); }
|
||||
static Action* kill_shot(PlayerbotAI* ai) { return new CastKillShotAction(ai); }
|
||||
static Action* misdirection_on_main_tank(PlayerbotAI* ai) { return new CastMisdirectionOnMainTankAction(ai); }
|
||||
static Action* silencing_shot(PlayerbotAI* ai) { return new CastSilencingShotAction(ai); }
|
||||
static Action* disengage(PlayerbotAI* ai) { return new CastDisengageAction(ai); }
|
||||
static Action* immolation_trap(PlayerbotAI* ai) { return new CastImmolationTrapAction(ai); }
|
||||
static Action* explosive_trap(PlayerbotAI* ai) { return new CastExplosiveTrapAction(ai); }
|
||||
static Action* explosive_shot_rank_4(PlayerbotAI* ai) { return new CastExplosiveShotRank4Action(ai); }
|
||||
static Action* explosive_shot_rank_3(PlayerbotAI* ai) { return new CastExplosiveShotRank3Action(ai); }
|
||||
static Action* explosive_shot_rank_2(PlayerbotAI* ai) { return new CastExplosiveShotRank2Action(ai); }
|
||||
static Action* explosive_shot_rank_1(PlayerbotAI* ai) { return new CastExplosiveShotRank1Action(ai); }
|
||||
static Action* intimidation(PlayerbotAI* ai) { return new CastIntimidationAction(ai); }
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> HunterAiObjectContext::sharedStrategyContexts;
|
||||
SharedNamedObjectContextList<Action> HunterAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> HunterAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> HunterAiObjectContext::sharedValueContexts;
|
||||
|
||||
HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void HunterAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void HunterAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new HunterStrategyFactoryInternal());
|
||||
strategyContexts.Add(new HunterBuffStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void HunterAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new HunterAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void HunterAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new HunterTriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void HunterAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Hunter/HunterAiObjectContext.h
Normal file
30
src/Ai/Class/Hunter/HunterAiObjectContext.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_HUNTERAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_HUNTERAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class HunterAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
HunterAiObjectContext(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
|
||||
113
src/Ai/Class/Hunter/Strategy/BeastMasteryHunterStrategy.cpp
Normal file
113
src/Ai/Class/Hunter/Strategy/BeastMasteryHunterStrategy.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 "BeastMasteryHunterStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class BeastMasteryHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
BeastMasteryHunterStrategyActionNodeFactory()
|
||||
{
|
||||
creators["auto shot"] = &auto_shot;
|
||||
creators["kill command"] = &kill_command;
|
||||
creators["kill shot"] = &kill_shot;
|
||||
creators["viper sting"] = &viper_sting;
|
||||
creators["serpent sting"] = serpent_sting;
|
||||
creators["aimed shot"] = &aimed_shot;
|
||||
creators["arcane shot"] = &arcane_shot;
|
||||
creators["steady shot"] = &steady_shot;
|
||||
creators["multi-shot"] = &multi_shot;
|
||||
creators["volley"] = &volley;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* auto_shot(PlayerbotAI*) { return new ActionNode("auto shot", {}, {}, {}); }
|
||||
static ActionNode* kill_command(PlayerbotAI*) { return new ActionNode("kill command", {}, {}, {}); }
|
||||
static ActionNode* kill_shot(PlayerbotAI*) { return new ActionNode("kill shot", {}, {}, {}); }
|
||||
static ActionNode* viper_sting(PlayerbotAI*) { return new ActionNode("viper sting", {}, {}, {}); }
|
||||
static ActionNode* serpent_sting(PlayerbotAI*) { return new ActionNode("serpent sting", {}, {}, {}); }
|
||||
static ActionNode* aimed_shot(PlayerbotAI*) { return new ActionNode("aimed shot", {}, {}, {}); }
|
||||
static ActionNode* arcane_shot(PlayerbotAI*) { return new ActionNode("arcane shot", {}, {}, {}); }
|
||||
static ActionNode* steady_shot(PlayerbotAI*) { return new ActionNode("steady shot", {}, {}, {}); }
|
||||
static ActionNode* multi_shot(PlayerbotAI*) { return new ActionNode("multi shot", {}, {}, {}); }
|
||||
static ActionNode* volley(PlayerbotAI*) { return new ActionNode("volley", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
BeastMasteryHunterStrategy::BeastMasteryHunterStrategy(PlayerbotAI* botAI) : GenericHunterStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new BeastMasteryHunterStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> BeastMasteryHunterStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("bestial wrath", 19.0f),
|
||||
NextAction("kill command", 5.7f),
|
||||
NextAction("kill shot", 5.6f),
|
||||
NextAction("serpent sting", 5.5f),
|
||||
NextAction("aimed shot", 5.4f),
|
||||
NextAction("arcane shot", 5.3f),
|
||||
NextAction("steady shot", 5.2f),
|
||||
NextAction("auto shot", 5.1f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void BeastMasteryHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericHunterStrategy::InitTriggers(triggers);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"intimidation",
|
||||
{
|
||||
NextAction("intimidation", 40.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"kill command",
|
||||
{
|
||||
NextAction("kill command", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target critical health",
|
||||
{
|
||||
NextAction("kill shot", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("viper sting", 17.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"no stings",
|
||||
{
|
||||
NextAction("serpent sting", 17.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"serpent sting on attacker",
|
||||
{
|
||||
NextAction("serpent sting on attacker", 16.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Hunter/Strategy/BeastMasteryHunterStrategy.h
Normal file
24
src/Ai/Class/Hunter/Strategy/BeastMasteryHunterStrategy.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_BEASTMASTERYHUNTERSTRATEGY_H
|
||||
#define _PLAYERBOT_BEASTMASTERYHUNTERSTRATEGY_H
|
||||
|
||||
#include "GenericHunterStrategy.h"
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class BeastMasteryHunterStrategy : public GenericHunterStrategy
|
||||
{
|
||||
public:
|
||||
BeastMasteryHunterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bm"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 "GenericHunterNonCombatStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class GenericHunterNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericHunterNonCombatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["rapid fire"] = &rapid_fire;
|
||||
creators["boost"] = &rapid_fire;
|
||||
creators["aspect of the pack"] = &aspect_of_the_pack;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* rapid_fire([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rapid fire",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("readiness")},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* aspect_of_the_pack([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("aspect of the pack",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("aspect of the cheetah")},
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericHunterNonCombatStrategy::GenericHunterNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericHunterNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericHunterNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("trueshot aura", { NextAction("trueshot aura", 2.0f)}));
|
||||
triggers.push_back(new TriggerNode("often", {
|
||||
NextAction("apply stone", 1.0f),
|
||||
NextAction("apply oil", 1.0f),
|
||||
}));
|
||||
triggers.push_back(new TriggerNode("low ammo", { NextAction("say::low ammo", ACTION_NORMAL)}));
|
||||
triggers.push_back(new TriggerNode("no track", { NextAction("track humanoids", ACTION_NORMAL)}));
|
||||
triggers.push_back(new TriggerNode("no ammo", { NextAction("equip upgrades", ACTION_HIGH + 1)}));
|
||||
}
|
||||
|
||||
void HunterPetStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("no pet", { NextAction("call pet", 60.0f)}));
|
||||
triggers.push_back(new TriggerNode("has pet", { NextAction("toggle pet spell", 60.0f)}));
|
||||
triggers.push_back(new TriggerNode("new pet", { NextAction("set pet stance", 60.0f)}));
|
||||
triggers.push_back(new TriggerNode("pet not happy", { NextAction("feed pet", 60.0f)}));
|
||||
triggers.push_back(new TriggerNode("hunters pet medium health", { NextAction("mend pet", 60.0f)}));
|
||||
triggers.push_back(new TriggerNode("hunters pet dead", { NextAction("revive pet", 60.0f)}));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_GENERICHUNTERNONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICHUNTERNONCOMBATSTRATEGY_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericHunterNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericHunterNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "nc"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class HunterPetStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
HunterPetStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
std::string const getName() override { return "pet"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
157
src/Ai/Class/Hunter/Strategy/GenericHunterStrategy.cpp
Normal file
157
src/Ai/Class/Hunter/Strategy/GenericHunterStrategy.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 "GenericHunterStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class GenericHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericHunterStrategyActionNodeFactory()
|
||||
{
|
||||
creators["rapid fire"] = &rapid_fire;
|
||||
creators["boost"] = &rapid_fire;
|
||||
creators["aspect of the pack"] = &aspect_of_the_pack;
|
||||
creators["aspect of the dragonhawk"] = &aspect_of_the_dragonhawk;
|
||||
creators["feign death"] = &feign_death;
|
||||
creators["wing clip"] = &wing_clip;
|
||||
creators["mongoose bite"] = &mongoose_bite;
|
||||
creators["raptor strike"] = &raptor_strike;
|
||||
creators["explosive trap"] = &explosive_trap;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* rapid_fire([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("rapid fire",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("readiness") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* aspect_of_the_pack([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("aspect of the pack",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("aspect of the cheetah") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* aspect_of_the_dragonhawk([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("aspect of the dragonhawk",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("aspect of the hawk") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* feign_death([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("feign death",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* wing_clip([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("wing clip",
|
||||
/*P*/ {},
|
||||
// /*A*/ { NextAction("mongoose bite") },
|
||||
{},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* mongoose_bite([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mongoose bite",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("raptor strike") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* raptor_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("raptor strike",
|
||||
/*P*/ { NextAction("melee") },
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* explosive_trap([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("explosive trap",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("immolation trap") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericHunterStrategy::GenericHunterStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericHunterStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
// Mark/Ammo/Mana Triggers
|
||||
triggers.push_back(new TriggerNode("no ammo", { NextAction("equip upgrades", 30.0f) }));
|
||||
triggers.push_back(new TriggerNode("hunter's mark", { NextAction("hunter's mark", 29.5f) }));
|
||||
triggers.push_back(new TriggerNode("rapid fire", { NextAction("rapid fire", 29.0f) }));
|
||||
triggers.push_back(new TriggerNode("aspect of the viper", { NextAction("aspect of the viper", 28.0f) }));
|
||||
triggers.push_back(new TriggerNode("aspect of the hawk", { NextAction("aspect of the dragonhawk", 27.5f) }));
|
||||
|
||||
// Aggro/Threat/Defensive Triggers
|
||||
triggers.push_back(new TriggerNode("has aggro", { NextAction("concussive shot", 20.0f) }));
|
||||
triggers.push_back(new TriggerNode("low tank threat", { NextAction("misdirection on main tank", 27.0f) }));
|
||||
triggers.push_back(new TriggerNode("low health", { NextAction("deterrence", 35.0f) }));
|
||||
triggers.push_back(new TriggerNode("concussive shot on snare target", { NextAction("concussive shot", 20.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium threat", { NextAction("feign death", 35.0f) }));
|
||||
triggers.push_back(new TriggerNode("hunters pet medium health", { NextAction("mend pet", 22.0f) }));
|
||||
triggers.push_back(new TriggerNode("hunters pet low health", { NextAction("mend pet", 21.0f) }));
|
||||
|
||||
// Dispel Triggers
|
||||
triggers.push_back(new TriggerNode("tranquilizing shot enrage", { NextAction("tranquilizing shot", 61.0f) }));
|
||||
triggers.push_back(new TriggerNode("tranquilizing shot magic", { NextAction("tranquilizing shot", 61.0f) }));
|
||||
|
||||
// Ranged-based Triggers
|
||||
triggers.push_back(new TriggerNode("enemy within melee", {
|
||||
NextAction("explosive trap", 37.0f),
|
||||
NextAction("mongoose bite", 22.0f),
|
||||
NextAction("wing clip", 21.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy too close for auto shot", {
|
||||
NextAction("disengage", 35.0f),
|
||||
NextAction("flee", 34.0f) }));
|
||||
}
|
||||
|
||||
// ===== AoE Strategy, 2/3+ enemies =====
|
||||
AoEHunterStrategy::AoEHunterStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void AoEHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("volley channel check", { NextAction("cancel channel", 23.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium aoe", { NextAction("volley", 22.0f) }));
|
||||
triggers.push_back(new TriggerNode("light aoe", { NextAction("multi-shot", 21.0f) }));
|
||||
}
|
||||
|
||||
void HunterBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
}
|
||||
|
||||
void HunterCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("scare beast", { NextAction("scare beast on cc", 23.0f) }));
|
||||
triggers.push_back(new TriggerNode("freezing trap", { NextAction("freezing trap on cc", 23.0f) }));
|
||||
}
|
||||
|
||||
void HunterTrapWeaveStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("immolation trap no cd", { NextAction("reach melee", 23.0f) }));
|
||||
}
|
||||
60
src/Ai/Class/Hunter/Strategy/GenericHunterStrategy.h
Normal file
60
src/Ai/Class/Hunter/Strategy/GenericHunterStrategy.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_GENERICHUNTERSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICHUNTERSTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericHunterStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericHunterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "hunter"; }
|
||||
uint32 GetType() const override { return CombatStrategy::GetType() | STRATEGY_TYPE_RANGED | STRATEGY_TYPE_DPS; }
|
||||
};
|
||||
|
||||
class AoEHunterStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
AoEHunterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "aoe"; }
|
||||
};
|
||||
|
||||
class HunterBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
HunterBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
std::string const getName() override { return "boost"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class HunterCcStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
HunterCcStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cc"; }
|
||||
};
|
||||
|
||||
class HunterTrapWeaveStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
HunterTrapWeaveStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "trap weave"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
53
src/Ai/Class/Hunter/Strategy/HunterBuffStrategies.cpp
Normal file
53
src/Ai/Class/Hunter/Strategy/HunterBuffStrategies.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 "HunterBuffStrategies.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class BuffHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
BuffHunterStrategyActionNodeFactory() { creators["aspect of the hawk"] = &aspect_of_the_hawk; }
|
||||
|
||||
private:
|
||||
static ActionNode* aspect_of_the_hawk([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("aspect of the hawk",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("aspect of the monkey") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
HunterBuffDpsStrategy::HunterBuffDpsStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new BuffHunterStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void HunterBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("aspect of the hawk", { NextAction("aspect of the dragonhawk", 20.1f),
|
||||
NextAction("aspect of the hawk", 20.0f) }));
|
||||
}
|
||||
|
||||
void HunterNatureResistanceStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("aspect of the wild",
|
||||
{ NextAction("aspect of the wild", 20.0f) }));
|
||||
}
|
||||
|
||||
void HunterBuffSpeedStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("aspect of the pack",
|
||||
{ NextAction("aspect of the pack", 20.0f) }));
|
||||
}
|
||||
|
||||
void HunterBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("aspect of the viper",
|
||||
{ NextAction("aspect of the viper", 20.0f) }));
|
||||
}
|
||||
49
src/Ai/Class/Hunter/Strategy/HunterBuffStrategies.h
Normal file
49
src/Ai/Class/Hunter/Strategy/HunterBuffStrategies.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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_HUNTERBUFFSTRATEGIES_H
|
||||
#define _PLAYERBOT_HUNTERBUFFSTRATEGIES_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class HunterBuffSpeedStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
HunterBuffSpeedStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {}
|
||||
|
||||
std::string const getName() override { return "bspeed"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class HunterBuffManaStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
HunterBuffManaStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {}
|
||||
|
||||
std::string const getName() override { return "bmana"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class HunterBuffDpsStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
HunterBuffDpsStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "bdps"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class HunterNatureResistanceStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
HunterNatureResistanceStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {}
|
||||
|
||||
std::string const getName() override { return "rnature"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
118
src/Ai/Class/Hunter/Strategy/MarksmanshipHunterStrategy.cpp
Normal file
118
src/Ai/Class/Hunter/Strategy/MarksmanshipHunterStrategy.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 "MarksmanshipHunterStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class MarksmanshipHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
MarksmanshipHunterStrategyActionNodeFactory()
|
||||
{
|
||||
creators["auto shot"] = &auto_shot;
|
||||
creators["silencing shot"] = &silencing_shot;
|
||||
creators["kill command"] = &kill_command;
|
||||
creators["kill shot"] = &kill_shot;
|
||||
creators["viper sting"] = &viper_sting;
|
||||
creators["serpent sting"] = serpent_sting;
|
||||
creators["chimera shot"] = &chimera_shot;
|
||||
creators["aimed shot"] = &aimed_shot;
|
||||
creators["arcane shot"] = &arcane_shot;
|
||||
creators["steady shot"] = &steady_shot;
|
||||
creators["multi-shot"] = &multi_shot;
|
||||
creators["volley"] = &volley;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* auto_shot(PlayerbotAI*) { return new ActionNode("auto shot", {}, {}, {}); }
|
||||
static ActionNode* silencing_shot(PlayerbotAI*) { return new ActionNode("silencing shot", {}, {}, {}); }
|
||||
static ActionNode* kill_command(PlayerbotAI*) { return new ActionNode("kill command", {}, {}, {}); }
|
||||
static ActionNode* kill_shot(PlayerbotAI*) { return new ActionNode("kill shot", {}, {}, {}); }
|
||||
static ActionNode* viper_sting(PlayerbotAI*) { return new ActionNode("viper sting", {}, {}, {}); }
|
||||
static ActionNode* serpent_sting(PlayerbotAI*) { return new ActionNode("serpent sting", {}, {}, {}); }
|
||||
static ActionNode* chimera_shot(PlayerbotAI*) { return new ActionNode("chimera shot", {}, {}, {}); }
|
||||
static ActionNode* aimed_shot(PlayerbotAI*) { return new ActionNode("aimed shot", {}, {}, {}); }
|
||||
static ActionNode* arcane_shot(PlayerbotAI*) { return new ActionNode("arcane shot", {}, {}, {}); }
|
||||
static ActionNode* steady_shot(PlayerbotAI*) { return new ActionNode("steady shot", {}, {}, {}); }
|
||||
static ActionNode* multi_shot(PlayerbotAI*) { return new ActionNode("multi shot", {}, {}, {}); }
|
||||
static ActionNode* volley(PlayerbotAI*) { return new ActionNode("volley", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
MarksmanshipHunterStrategy::MarksmanshipHunterStrategy(PlayerbotAI* botAI) : GenericHunterStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new MarksmanshipHunterStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> MarksmanshipHunterStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("kill command", 5.8f),
|
||||
NextAction("kill shot", 5.7f),
|
||||
NextAction("serpent sting", 5.6f),
|
||||
NextAction("chimera shot", 5.5f),
|
||||
NextAction("aimed shot", 5.4f),
|
||||
NextAction("arcane shot", 5.3f),
|
||||
NextAction("steady shot", 5.2f),
|
||||
NextAction("auto shot", 5.1f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void MarksmanshipHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericHunterStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"silencing shot",
|
||||
{
|
||||
NextAction("silencing shot", 40.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"kill command",
|
||||
{
|
||||
NextAction("kill command", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target critical health",
|
||||
{
|
||||
NextAction("kill shot", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("viper sting", 17.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"no stings",
|
||||
{
|
||||
NextAction("serpent sting", 17.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"serpent sting on attacker",
|
||||
{
|
||||
NextAction("serpent sting on attacker", 16.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Hunter/Strategy/MarksmanshipHunterStrategy.h
Normal file
24
src/Ai/Class/Hunter/Strategy/MarksmanshipHunterStrategy.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_MARKSMANSHIPHUNTERSTRATEGY_H
|
||||
#define _PLAYERBOT_MARKSMANSHIPHUNTERSTRATEGY_H
|
||||
|
||||
#include "GenericHunterStrategy.h"
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class MarksmanshipHunterStrategy : public GenericHunterStrategy
|
||||
{
|
||||
public:
|
||||
MarksmanshipHunterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "mm"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
159
src/Ai/Class/Hunter/Strategy/SurvivalHunterStrategy.cpp
Normal file
159
src/Ai/Class/Hunter/Strategy/SurvivalHunterStrategy.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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 "SurvivalHunterStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class SurvivalHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
SurvivalHunterStrategyActionNodeFactory()
|
||||
{
|
||||
creators["auto shot"] = &auto_shot;
|
||||
creators["kill command"] = &kill_command;
|
||||
creators["kill shot"] = &kill_shot;
|
||||
creators["explosive shot"] = &explosive_shot;
|
||||
creators["black arrow"] = &black_arrow;
|
||||
creators["viper sting"] = &viper_sting;
|
||||
creators["serpent sting"] = serpent_sting;
|
||||
creators["aimed shot"] = &aimed_shot;
|
||||
creators["arcane shot"] = &arcane_shot;
|
||||
creators["steady shot"] = &steady_shot;
|
||||
creators["multi-shot"] = &multi_shot;
|
||||
creators["volley"] = &volley;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* auto_shot(PlayerbotAI*) { return new ActionNode("auto shot", {}, {}, {}); }
|
||||
static ActionNode* kill_command(PlayerbotAI*) { return new ActionNode("kill command", {}, {}, {}); }
|
||||
static ActionNode* kill_shot(PlayerbotAI*) { return new ActionNode("kill shot", {}, {}, {}); }
|
||||
static ActionNode* explosive_shot(PlayerbotAI*) { return new ActionNode("explosive shot", {}, {}, {}); }
|
||||
static ActionNode* black_arrow(PlayerbotAI*) { return new ActionNode("black arrow", {}, {}, {}); }
|
||||
static ActionNode* viper_sting(PlayerbotAI*) { return new ActionNode("viper sting", {}, {}, {}); }
|
||||
static ActionNode* serpent_sting(PlayerbotAI*) { return new ActionNode("serpent sting", {}, {}, {}); }
|
||||
static ActionNode* aimed_shot(PlayerbotAI*) { return new ActionNode("aimed shot", {}, {}, {}); }
|
||||
static ActionNode* arcane_shot(PlayerbotAI*) { return new ActionNode("arcane shot", {}, {}, {}); }
|
||||
static ActionNode* steady_shot(PlayerbotAI*) { return new ActionNode("steady shot", {}, {}, {}); }
|
||||
static ActionNode* multi_shot(PlayerbotAI*) { return new ActionNode("multi shot", {}, {}, {}); }
|
||||
static ActionNode* volley(PlayerbotAI*) { return new ActionNode("volley", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
SurvivalHunterStrategy::SurvivalHunterStrategy(PlayerbotAI* botAI) : GenericHunterStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new SurvivalHunterStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> SurvivalHunterStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("kill command", 5.9f),
|
||||
NextAction("kill shot", 5.8f),
|
||||
NextAction("explosive shot", 5.7f),
|
||||
NextAction("black arrow", 5.6f),
|
||||
NextAction("serpent sting", 5.5f),
|
||||
NextAction("aimed shot", 5.4f),
|
||||
NextAction("arcane shot", 5.3f),
|
||||
NextAction("steady shot", 5.2f),
|
||||
NextAction("auto shot", 5.1f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void SurvivalHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericHunterStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lock and load",
|
||||
{
|
||||
NextAction("explosive shot rank 4", 28.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lock and load",
|
||||
{
|
||||
NextAction("explosive shot rank 3", 27.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lock and load",
|
||||
{
|
||||
NextAction("explosive shot rank 2", 27.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lock and load",
|
||||
{
|
||||
NextAction("explosive shot rank 1", 26.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"kill command",
|
||||
{
|
||||
NextAction("kill command", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target critical health",
|
||||
{
|
||||
NextAction("kill shot", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"explosive shot",
|
||||
{
|
||||
NextAction("explosive shot", 17.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"black arrow",
|
||||
{
|
||||
NextAction("black arrow", 16.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("viper sting", 16.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"no stings",
|
||||
{
|
||||
NextAction("serpent sting", 15.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"serpent sting on attacker",
|
||||
{
|
||||
NextAction("serpent sting on attacker", 15.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Hunter/Strategy/SurvivalHunterStrategy.h
Normal file
24
src/Ai/Class/Hunter/Strategy/SurvivalHunterStrategy.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_SURVIVALHUNTERSTRATEGY_H
|
||||
#define _PLAYERBOT_SURVIVALHUNTERSTRATEGY_H
|
||||
|
||||
#include "GenericHunterStrategy.h"
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class SurvivalHunterStrategy : public GenericHunterStrategy
|
||||
{
|
||||
public:
|
||||
SurvivalHunterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "surv"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
170
src/Ai/Class/Hunter/Trigger/HunterTriggers.cpp
Normal file
170
src/Ai/Class/Hunter/Trigger/HunterTriggers.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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 "HunterTriggers.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "HunterActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Player.h"
|
||||
|
||||
bool KillCommandTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
return !botAI->HasAura("kill command", target);
|
||||
}
|
||||
|
||||
bool BlackArrowTrigger::IsActive()
|
||||
{
|
||||
if (botAI->HasStrategy("trap weave", BOT_STATE_COMBAT))
|
||||
return false;
|
||||
|
||||
return DebuffTrigger::IsActive();
|
||||
return BuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
bool HunterAspectOfTheHawkTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
return SpellTrigger::IsActive() && !botAI->HasAura("aspect of the hawk", target) &&
|
||||
!botAI->HasAura("aspect of the dragonhawk", target) &&
|
||||
(!AI_VALUE2(bool, "has mana", "self target") || AI_VALUE2(uint8, "mana", "self target") > 70);
|
||||
}
|
||||
|
||||
bool HunterNoStingsActiveTrigger::IsActive()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
return DebuffTrigger::IsActive() && target && !botAI->HasAura("serpent sting", target, false, true) &&
|
||||
!botAI->HasAura("scorpid sting", target, false, true) && !botAI->HasAura("viper sting", target, false, true);
|
||||
return BuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
bool HuntersPetDeadTrigger::IsActive()
|
||||
{
|
||||
// Unit* pet = AI_VALUE(Unit*, "pet target");
|
||||
// return pet && AI_VALUE2(bool, "dead", "pet target") && !AI_VALUE2(bool, "mounted", "self target");
|
||||
return AI_VALUE(bool, "pet dead") && !AI_VALUE2(bool, "mounted", "self target");
|
||||
}
|
||||
|
||||
bool HuntersPetLowHealthTrigger::IsActive()
|
||||
{
|
||||
Unit* pet = AI_VALUE(Unit*, "pet target");
|
||||
return pet && AI_VALUE2(uint8, "health", "pet target") < 40 && !AI_VALUE2(bool, "dead", "pet target") &&
|
||||
!AI_VALUE2(bool, "mounted", "self target");
|
||||
}
|
||||
|
||||
bool HuntersPetMediumHealthTrigger::IsActive()
|
||||
{
|
||||
Unit* pet = AI_VALUE(Unit*, "pet target");
|
||||
return pet && AI_VALUE2(uint8, "health", "pet target") < sPlayerbotAIConfig->mediumHealth &&
|
||||
!AI_VALUE2(bool, "dead", "pet target") && !AI_VALUE2(bool, "mounted", "self target");
|
||||
}
|
||||
|
||||
bool HunterPetNotHappy::IsActive()
|
||||
{
|
||||
return !AI_VALUE(bool, "pet happy") && !AI_VALUE2(bool, "mounted", "self target");
|
||||
}
|
||||
|
||||
bool HunterAspectOfTheViperTrigger::IsActive()
|
||||
{
|
||||
return SpellTrigger::IsActive() && !botAI->HasAura(spell, GetTarget()) &&
|
||||
AI_VALUE2(uint8, "mana", "self target") < (sPlayerbotAIConfig->lowMana / 2);
|
||||
;
|
||||
}
|
||||
|
||||
bool HunterAspectOfThePackTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && !botAI->HasAura("aspect of the cheetah", GetTarget());
|
||||
};
|
||||
|
||||
bool HunterLowAmmoTrigger::IsActive()
|
||||
{
|
||||
return bot->GetGroup() && (AI_VALUE2(uint32, "item count", "ammo") < 100) &&
|
||||
(AI_VALUE2(uint32, "item count", "ammo") > 0);
|
||||
}
|
||||
|
||||
bool HunterHasAmmoTrigger::IsActive() { return !AmmoCountTrigger::IsActive(); }
|
||||
|
||||
bool SwitchToRangedTrigger::IsActive()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
return botAI->HasStrategy("close", BOT_STATE_COMBAT) && target &&
|
||||
(target->GetVictim() != bot &&
|
||||
sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
|
||||
}
|
||||
|
||||
bool SwitchToMeleeTrigger::IsActive()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) && target &&
|
||||
(target->GetVictim() == bot &&
|
||||
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
|
||||
}
|
||||
|
||||
bool NoTrackTrigger::IsActive()
|
||||
{
|
||||
std::vector<std::string> track_list = {
|
||||
"track beasts",
|
||||
"track demons",
|
||||
"track dragonkin",
|
||||
"track elementals",
|
||||
"track giants",
|
||||
"track hidden",
|
||||
"track humanoids"
|
||||
};
|
||||
|
||||
for (auto &track: track_list)
|
||||
{
|
||||
if (botAI->HasAura(track, bot))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SerpentStingOnAttackerTrigger::IsActive()
|
||||
{
|
||||
if (!DebuffOnAttackerTrigger::IsActive())
|
||||
return false;
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return !botAI->HasAura("scorpid sting", target, false, true) &&
|
||||
!botAI->HasAura("viper sting", target, false, true);
|
||||
return BuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
const std::set<uint32> VolleyChannelCheckTrigger::VOLLEY_SPELL_IDS = {
|
||||
1510, // Volley Rank 1
|
||||
14294, // Volley Rank 2
|
||||
14295, // Volley Rank 3
|
||||
27022, // Volley Rank 4
|
||||
58431, // Volley Rank 5
|
||||
58434 // Volley Rank 6
|
||||
};
|
||||
|
||||
bool VolleyChannelCheckTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
// Check if the bot is channeling a spell
|
||||
if (Spell* spell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
{
|
||||
// Only trigger if the spell being channeled is Volley
|
||||
if (VOLLEY_SPELL_IDS.count(spell->m_spellInfo->Id))
|
||||
{
|
||||
uint8 attackerCount = AI_VALUE(uint8, "attacker count");
|
||||
return attackerCount < minEnemies;
|
||||
}
|
||||
}
|
||||
|
||||
// Not channeling Volley
|
||||
return false;
|
||||
}
|
||||
263
src/Ai/Class/Hunter/Trigger/HunterTriggers.h
Normal file
263
src/Ai/Class/Hunter/Trigger/HunterTriggers.h
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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_HUNTERTRIGGERS_H
|
||||
#define _PLAYERBOT_HUNTERTRIGGERS_H
|
||||
|
||||
#include "CureTriggers.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "Trigger.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include <set>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
// Buff and Out of Combat Triggers
|
||||
|
||||
class HunterAspectOfTheMonkeyTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterAspectOfTheMonkeyTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the monkey") {}
|
||||
};
|
||||
|
||||
class HunterAspectOfTheHawkTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterAspectOfTheHawkTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the hawk") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HunterAspectOfTheWildTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterAspectOfTheWildTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the wild") {}
|
||||
};
|
||||
|
||||
class HunterAspectOfTheViperTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterAspectOfTheViperTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the viper") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HunterAspectOfThePackTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterAspectOfThePackTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the pack") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class TrueshotAuraTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
TrueshotAuraTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "trueshot aura") {}
|
||||
};
|
||||
|
||||
class NoTrackTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
NoTrackTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "no track") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HunterLowAmmoTrigger : public AmmoCountTrigger
|
||||
{
|
||||
public:
|
||||
HunterLowAmmoTrigger(PlayerbotAI* botAI) : AmmoCountTrigger(botAI, "ammo", 1, 30) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HunterNoAmmoTrigger : public AmmoCountTrigger
|
||||
{
|
||||
public:
|
||||
HunterNoAmmoTrigger(PlayerbotAI* botAI) : AmmoCountTrigger(botAI, "ammo", 1, 10) {}
|
||||
};
|
||||
|
||||
class HunterHasAmmoTrigger : public AmmoCountTrigger
|
||||
{
|
||||
public:
|
||||
HunterHasAmmoTrigger(PlayerbotAI* botAI) : AmmoCountTrigger(botAI, "ammo", 1, 10) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
// Cooldown Triggers
|
||||
|
||||
class RapidFireTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
RapidFireTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "rapid fire") {}
|
||||
};
|
||||
|
||||
class BestialWrathTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
BestialWrathTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "bestial wrath") {}
|
||||
};
|
||||
|
||||
class IntimidationTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
IntimidationTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "intimidation") {}
|
||||
};
|
||||
|
||||
class KillCommandTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
KillCommandTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "kill command") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class LockAndLoadTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
LockAndLoadTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "lock and load") {}
|
||||
|
||||
bool IsActive() override
|
||||
{
|
||||
return botAI->HasAura("lock and load", botAI->GetBot());
|
||||
}
|
||||
};
|
||||
|
||||
// CC Triggers
|
||||
|
||||
class FreezingTrapTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
FreezingTrapTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "freezing trap") {}
|
||||
};
|
||||
|
||||
class ConsussiveShotSnareTrigger : public SnareTargetTrigger
|
||||
{
|
||||
public:
|
||||
ConsussiveShotSnareTrigger(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, "concussive shot") {}
|
||||
};
|
||||
|
||||
class ScareBeastTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
ScareBeastTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "scare beast") {}
|
||||
};
|
||||
|
||||
class SilencingShotTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
SilencingShotTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "silencing shot") {}
|
||||
};
|
||||
|
||||
// DoT/Debuff Triggers
|
||||
|
||||
class HuntersMarkTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
HuntersMarkTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "hunter's mark", 1, true, 0.5f) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class ExplosiveShotTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
ExplosiveShotTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "explosive shot", 1, true) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class BlackArrowTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
BlackArrowTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "black arrow", 1, true) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HunterNoStingsActiveTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
HunterNoStingsActiveTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "no stings") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class SerpentStingOnAttackerTrigger : public DebuffOnAttackerTrigger
|
||||
{
|
||||
public:
|
||||
SerpentStingOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "serpent sting", true) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
// Damage/Combat Triggers
|
||||
|
||||
class AutoShotTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
AutoShotTrigger(PlayerbotAI* botAI) : Trigger(botAI, "auto shot") {}
|
||||
};
|
||||
|
||||
class SwitchToRangedTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
SwitchToRangedTrigger(PlayerbotAI* botAI) : Trigger(botAI, "switch to ranged") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class SwitchToMeleeTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
SwitchToMeleeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "switch to melee") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MisdirectionOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
{
|
||||
public:
|
||||
MisdirectionOnMainTankTrigger(PlayerbotAI* ai) : BuffOnMainTankTrigger(ai, "misdirection", true) {}
|
||||
};
|
||||
|
||||
class TargetRemoveEnrageTrigger : public TargetAuraDispelTrigger
|
||||
{
|
||||
public:
|
||||
TargetRemoveEnrageTrigger(PlayerbotAI* ai) : TargetAuraDispelTrigger(ai, "tranquilizing shot", DISPEL_ENRAGE) {}
|
||||
};
|
||||
|
||||
class TargetRemoveMagicTrigger : public TargetAuraDispelTrigger
|
||||
{
|
||||
public:
|
||||
TargetRemoveMagicTrigger(PlayerbotAI* ai) : TargetAuraDispelTrigger(ai, "tranquilizing shot", DISPEL_MAGIC) {}
|
||||
};
|
||||
|
||||
class ImmolationTrapNoCdTrigger : public SpellNoCooldownTrigger
|
||||
{
|
||||
public:
|
||||
ImmolationTrapNoCdTrigger(PlayerbotAI* ai) : SpellNoCooldownTrigger(ai, "immolation trap") {}
|
||||
};
|
||||
|
||||
BEGIN_TRIGGER(HuntersPetDeadTrigger, Trigger)
|
||||
END_TRIGGER()
|
||||
|
||||
BEGIN_TRIGGER(HuntersPetLowHealthTrigger, Trigger)
|
||||
END_TRIGGER()
|
||||
|
||||
BEGIN_TRIGGER(HuntersPetMediumHealthTrigger, Trigger)
|
||||
END_TRIGGER()
|
||||
|
||||
BEGIN_TRIGGER(HunterPetNotHappy, Trigger)
|
||||
END_TRIGGER()
|
||||
|
||||
class VolleyChannelCheckTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
VolleyChannelCheckTrigger(PlayerbotAI* botAI, uint32 minEnemies = 2)
|
||||
: Trigger(botAI, "volley channel check"), minEnemies(minEnemies)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
uint32 minEnemies;
|
||||
static const std::set<uint32> VOLLEY_SPELL_IDS;
|
||||
};
|
||||
|
||||
#endif
|
||||
144
src/Ai/Class/Mage/Action/MageActions.cpp
Normal file
144
src/Ai/Class/Mage/Action/MageActions.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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 "MageActions.h"
|
||||
#include <cmath>
|
||||
#include "UseItemAction.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
Value<Unit*>* CastPolymorphAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
|
||||
|
||||
bool UseManaSapphireAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(33312, false) > 0; // Mana Sapphire
|
||||
}
|
||||
|
||||
bool UseManaEmeraldAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(22044, false) > 0; // Mana Emerald
|
||||
}
|
||||
|
||||
bool UseManaRubyAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(8008, false) > 0; // Mana Ruby
|
||||
}
|
||||
|
||||
bool UseManaCitrineAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(8007, false) > 0; // Mana Citrine
|
||||
}
|
||||
|
||||
bool UseManaJadeAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(5513, false) > 0; // Mana Jade
|
||||
}
|
||||
|
||||
bool UseManaAgateAction::isUseful()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
return AI_VALUE2(bool, "combat", "self target") && bot->GetItemCount(5514, false) > 0; // Mana Agate
|
||||
}
|
||||
|
||||
bool CastFrostNovaAction::isUseful()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target || !target->IsInWorld())
|
||||
return false;
|
||||
|
||||
if (target->ToCreature() && target->ToCreature()->HasMechanicTemplateImmunity(1 << (MECHANIC_FREEZE - 1)))
|
||||
return false;
|
||||
|
||||
if (target->isFrozen())
|
||||
return false;
|
||||
|
||||
return sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||
}
|
||||
|
||||
bool CastConeOfColdAction::isUseful()
|
||||
{
|
||||
bool facingTarget = AI_VALUE2(bool, "facing", "current target");
|
||||
bool targetClose = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||
return facingTarget && targetClose;
|
||||
}
|
||||
|
||||
bool CastDragonsBreathAction::isUseful()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
bool facingTarget = AI_VALUE2(bool, "facing", "current target");
|
||||
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||
return facingTarget && targetClose;
|
||||
}
|
||||
|
||||
bool CastBlastWaveAction::isUseful()
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||
return targetClose;
|
||||
}
|
||||
|
||||
Unit* CastFocusMagicOnPartyAction::GetTarget()
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return nullptr;
|
||||
|
||||
Unit* casterDps = nullptr;
|
||||
Unit* healer = nullptr;
|
||||
Unit* target = nullptr;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
if (!member || member == bot || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
if (member->GetMap() != bot->GetMap() || bot->GetDistance(member) > sPlayerbotAIConfig->spellDistance)
|
||||
continue;
|
||||
|
||||
if (member->HasAura(54646))
|
||||
continue;
|
||||
|
||||
if (member->getClass() == CLASS_MAGE)
|
||||
return member;
|
||||
|
||||
if (!casterDps && botAI->IsCaster(member) && botAI->IsDps(member))
|
||||
casterDps = member;
|
||||
|
||||
if (!healer && botAI->IsHeal(member))
|
||||
healer = member;
|
||||
|
||||
if (!target)
|
||||
target = member;
|
||||
}
|
||||
|
||||
if (casterDps)
|
||||
return casterDps;
|
||||
|
||||
if (healer)
|
||||
return healer;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
bool CastBlinkBackAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (!target)
|
||||
return false;
|
||||
// can cast spell check passed in isUseful()
|
||||
bot->SetOrientation(bot->GetAngle(target) + M_PI);
|
||||
return CastSpellAction::Execute(event);
|
||||
}
|
||||
407
src/Ai/Class/Mage/Action/MageActions.h
Normal file
407
src/Ai/Class/Mage/Action/MageActions.h
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* 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_MAGEACTIONS_H
|
||||
#define _PLAYERBOT_MAGEACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "UseItemAction.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
// Buff and Out of Combat Actions
|
||||
|
||||
class CastMoltenArmorAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMoltenArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "molten armor") {}
|
||||
};
|
||||
|
||||
class CastMageArmorAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMageArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mage armor") {}
|
||||
};
|
||||
|
||||
class CastIceArmorAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ice armor") {}
|
||||
};
|
||||
|
||||
class CastFrostArmorAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostArmorAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "frost armor") {}
|
||||
};
|
||||
|
||||
class CastArcaneIntellectAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneIntellectAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "arcane intellect") {}
|
||||
};
|
||||
|
||||
class CastArcaneIntellectOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastArcaneIntellectOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "arcane intellect") {}
|
||||
};
|
||||
|
||||
class CastFocusMagicOnPartyAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFocusMagicOnPartyAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "focus magic") {}
|
||||
Unit* GetTarget() override;
|
||||
};
|
||||
|
||||
class CastSummonWaterElementalAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSummonWaterElementalAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "summon water elemental") {}
|
||||
};
|
||||
|
||||
// Boost Actions
|
||||
|
||||
class CastCombustionAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastCombustionAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "combustion") {}
|
||||
};
|
||||
|
||||
class CastArcanePowerAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcanePowerAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "arcane power") {}
|
||||
};
|
||||
|
||||
class CastPresenceOfMindAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastPresenceOfMindAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "presence of mind") {}
|
||||
};
|
||||
|
||||
class CastIcyVeinsAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIcyVeinsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "icy veins") {}
|
||||
};
|
||||
|
||||
class CastColdSnapAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastColdSnapAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cold snap") {}
|
||||
};
|
||||
|
||||
// Defensive Actions
|
||||
|
||||
class CastFireWardAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFireWardAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "fire ward") {}
|
||||
};
|
||||
|
||||
class CastFrostWardAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostWardAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "frost ward") {}
|
||||
};
|
||||
|
||||
class CastIceBarrierAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceBarrierAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ice barrier") {}
|
||||
};
|
||||
|
||||
class CastInvisibilityAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastInvisibilityAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "invisibility") {}
|
||||
};
|
||||
class CastIceBlockAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceBlockAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "ice block") {}
|
||||
};
|
||||
|
||||
class CastMirrorImageAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastMirrorImageAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mirror image") {}
|
||||
};
|
||||
|
||||
class CastBlinkBackAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlinkBackAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blink") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastManaShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastManaShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "mana shield") {}
|
||||
};
|
||||
|
||||
// Utility Actions
|
||||
|
||||
class CastEvocationAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastEvocationAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "evocation") {}
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
};
|
||||
|
||||
class CastConjureManaGemAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastConjureManaGemAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "conjure mana gem") {}
|
||||
};
|
||||
|
||||
class CastConjureFoodAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastConjureFoodAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "conjure food") {}
|
||||
};
|
||||
|
||||
class CastConjureWaterAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastConjureWaterAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "conjure water") {}
|
||||
};
|
||||
|
||||
class UseManaSapphireAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaSapphireAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana sapphire") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
class UseManaEmeraldAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaEmeraldAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana emerald") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class UseManaRubyAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaRubyAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana ruby") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class UseManaCitrineAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaCitrineAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana citrine") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class UseManaJadeAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaJadeAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana jade") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class UseManaAgateAction : public UseItemAction
|
||||
{
|
||||
public:
|
||||
UseManaAgateAction(PlayerbotAI* botAI) : UseItemAction(botAI, "mana agate") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
// CC, Interrupt, and Dispel Actions
|
||||
|
||||
class CastPolymorphAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastPolymorphAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "polymorph") {}
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
};
|
||||
|
||||
class CastSpellstealAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastSpellstealAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "spellsteal") {}
|
||||
};
|
||||
|
||||
class CastCounterspellAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastCounterspellAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "counterspell") {}
|
||||
};
|
||||
|
||||
class CastCounterspellOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastCounterspellOnEnemyHealerAction(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, "counterspell") {}
|
||||
};
|
||||
|
||||
class CastFrostNovaAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostNovaAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frost nova") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastDeepFreezeAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDeepFreezeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "deep freeze") {}
|
||||
bool isPossible() override { return true; }
|
||||
};
|
||||
|
||||
class CastRemoveCurseAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastRemoveCurseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "remove curse") {}
|
||||
};
|
||||
|
||||
class CastRemoveLesserCurseAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastRemoveLesserCurseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "remove lesser curse") {}
|
||||
};
|
||||
|
||||
class CastRemoveCurseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRemoveCurseOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "remove curse", DISPEL_CURSE) {}
|
||||
};
|
||||
|
||||
class CastRemoveLesserCurseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRemoveLesserCurseOnPartyAction(PlayerbotAI* botAI)
|
||||
: CurePartyMemberAction(botAI, "remove lesser curse", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Damage and Debuff Actions
|
||||
|
||||
class CastFireballAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFireballAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "fireball") {}
|
||||
};
|
||||
|
||||
class CastScorchAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastScorchAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "scorch") {}
|
||||
};
|
||||
|
||||
class CastFireBlastAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFireBlastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "fire blast") {}
|
||||
};
|
||||
|
||||
class CastArcaneBlastAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneBlastAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "arcane blast") {}
|
||||
std::string const GetTargetName() override { return "current target"; }
|
||||
};
|
||||
|
||||
class CastArcaneBarrageAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneBarrageAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "arcane barrage") {}
|
||||
};
|
||||
|
||||
class CastArcaneMissilesAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastArcaneMissilesAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "arcane missiles") {}
|
||||
};
|
||||
|
||||
class CastPyroblastAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastPyroblastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "pyroblast") {}
|
||||
};
|
||||
|
||||
class CastLivingBombAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastLivingBombOnAttackersAction : public CastDebuffSpellOnAttackerAction
|
||||
{
|
||||
public:
|
||||
CastLivingBombOnAttackersAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "living bomb", true) {}
|
||||
bool isUseful() override
|
||||
{
|
||||
// Bypass TTL check
|
||||
return CastAuraSpellAction::isUseful();
|
||||
}
|
||||
};
|
||||
|
||||
class CastFrostboltAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostboltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frostbolt") {}
|
||||
};
|
||||
|
||||
class CastFrostfireBoltAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastFrostfireBoltAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "frostfire bolt") {}
|
||||
};
|
||||
|
||||
class CastIceLanceAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastIceLanceAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "ice lance") {}
|
||||
};
|
||||
|
||||
class CastBlizzardAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlizzardAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blizzard") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastConeOfColdAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastConeOfColdAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "cone of cold") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastFlamestrikeAction : public CastDebuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastFlamestrikeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flamestrike", true, 0.0f) {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
};
|
||||
|
||||
class CastDragonsBreathAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDragonsBreathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dragon's breath") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastBlastWaveAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlastWaveAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blast wave") {}
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
345
src/Ai/Class/Mage/MageAiObjectContext.cpp
Normal file
345
src/Ai/Class/Mage/MageAiObjectContext.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* 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 "MageAiObjectContext.h"
|
||||
#include "ArcaneMageStrategy.h"
|
||||
#include "FireMageStrategy.h"
|
||||
#include "FrostFireMageStrategy.h"
|
||||
#include "FrostMageStrategy.h"
|
||||
#include "GenericMageNonCombatStrategy.h"
|
||||
#include "MageActions.h"
|
||||
#include "MageTriggers.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PullStrategy.h"
|
||||
|
||||
class MageStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
MageStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &MageStrategyFactoryInternal::nc;
|
||||
creators["pull"] = &MageStrategyFactoryInternal::pull;
|
||||
creators["aoe"] = &MageStrategyFactoryInternal::aoe;
|
||||
creators["cure"] = &MageStrategyFactoryInternal::cure;
|
||||
creators["buff"] = &MageStrategyFactoryInternal::buff;
|
||||
creators["boost"] = &MageStrategyFactoryInternal::boost;
|
||||
creators["cc"] = &MageStrategyFactoryInternal::cc;
|
||||
creators["firestarter"] = &MageStrategyFactoryInternal::firestarter;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericMageNonCombatStrategy(botAI); }
|
||||
static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "shoot"); }
|
||||
static Strategy* aoe(PlayerbotAI* botAI) { return new MageAoeStrategy(botAI); }
|
||||
static Strategy* cure(PlayerbotAI* botAI) { return new MageCureStrategy(botAI); }
|
||||
static Strategy* buff(PlayerbotAI* botAI) { return new MageBuffStrategy(botAI); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new MageBoostStrategy(botAI); }
|
||||
static Strategy* cc(PlayerbotAI* botAI) { return new MageCcStrategy(botAI); }
|
||||
static Strategy* firestarter(PlayerbotAI* botAI) { return new FirestarterStrategy(botAI); }
|
||||
};
|
||||
|
||||
class MageCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
MageCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["frost"] = &MageCombatStrategyFactoryInternal::frost;
|
||||
creators["fire"] = &MageCombatStrategyFactoryInternal::fire;
|
||||
creators["frostfire"] = &MageCombatStrategyFactoryInternal::frostfire;
|
||||
creators["arcane"] = &MageCombatStrategyFactoryInternal::arcane;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* frost(PlayerbotAI* botAI) { return new FrostMageStrategy(botAI); }
|
||||
static Strategy* fire(PlayerbotAI* botAI) { return new FireMageStrategy(botAI); }
|
||||
static Strategy* frostfire(PlayerbotAI* botAI) { return new FrostFireMageStrategy(botAI); }
|
||||
static Strategy* arcane(PlayerbotAI* botAI) { return new ArcaneMageStrategy(botAI); }
|
||||
};
|
||||
|
||||
class MageBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
MageBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bmana"] = &MageBuffStrategyFactoryInternal::bmana;
|
||||
creators["bdps"] = &MageBuffStrategyFactoryInternal::bdps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bmana(PlayerbotAI* botAI) { return new MageBuffManaStrategy(botAI); }
|
||||
static Strategy* bdps(PlayerbotAI* botAI) { return new MageBuffDpsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class MageTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
MageTriggerFactoryInternal()
|
||||
{
|
||||
creators["fireball"] = &MageTriggerFactoryInternal::fireball;
|
||||
creators["pyroblast"] = &MageTriggerFactoryInternal::pyroblast;
|
||||
creators["combustion"] = &MageTriggerFactoryInternal::combustion;
|
||||
creators["fingers of frost"] = &MageTriggerFactoryInternal::fingers_of_frost;
|
||||
creators["brain freeze"] = &MageTriggerFactoryInternal::brain_freeze;
|
||||
creators["icy veins"] = &MageTriggerFactoryInternal::icy_veins;
|
||||
creators["cold snap"] = &MageTriggerFactoryInternal::cold_snap;
|
||||
creators["ice barrier"] = &MageTriggerFactoryInternal::ice_barrier;
|
||||
creators["arcane intellect"] = &MageTriggerFactoryInternal::arcane_intellect;
|
||||
creators["arcane intellect on party"] = &MageTriggerFactoryInternal::arcane_intellect_on_party;
|
||||
creators["mage armor"] = &MageTriggerFactoryInternal::mage_armor;
|
||||
creators["remove curse"] = &MageTriggerFactoryInternal::remove_curse;
|
||||
creators["remove curse on party"] = &MageTriggerFactoryInternal::remove_curse_on_party;
|
||||
creators["counterspell"] = &MageTriggerFactoryInternal::counterspell;
|
||||
creators["polymorph"] = &MageTriggerFactoryInternal::polymorph;
|
||||
creators["spellsteal"] = &MageTriggerFactoryInternal::spellsteal;
|
||||
creators["hot streak"] = &MageTriggerFactoryInternal::hot_streak;
|
||||
creators["living bomb"] = &MageTriggerFactoryInternal::living_bomb;
|
||||
creators["living bomb on attackers"] = &MageTriggerFactoryInternal::living_bomb_on_attackers;
|
||||
creators["missile barrage"] = &MageTriggerFactoryInternal::missile_barrage;
|
||||
creators["arcane blast"] = &MageTriggerFactoryInternal::arcane_blast;
|
||||
creators["counterspell on enemy healer"] = &MageTriggerFactoryInternal::counterspell_enemy_healer;
|
||||
creators["arcane power"] = &MageTriggerFactoryInternal::arcane_power;
|
||||
creators["presence of mind"] = &MageTriggerFactoryInternal::presence_of_mind;
|
||||
creators["fire ward"] = &MageTriggerFactoryInternal::fire_ward;
|
||||
creators["frost ward"] = &MageTriggerFactoryInternal::frost_ward;
|
||||
creators["arcane blast stack"] = &MageTriggerFactoryInternal::arcane_blast_stack;
|
||||
creators["mirror image"] = &MageTriggerFactoryInternal::mirror_image;
|
||||
creators["frost nova on target"] = &MageTriggerFactoryInternal::frost_nova_on_target;
|
||||
creators["frostbite on target"] = &MageTriggerFactoryInternal::frostbite_on_target;
|
||||
creators["no focus magic"] = &MageTriggerFactoryInternal::no_focus_magic;
|
||||
creators["frostfire bolt"] = &MageTriggerFactoryInternal::frostfire_bolt;
|
||||
creators["firestarter"] = &MageTriggerFactoryInternal::firestarter;
|
||||
creators["improved scorch"] = &MageTriggerFactoryInternal::improved_scorch;
|
||||
creators["flamestrike nearby"] = &MageTriggerFactoryInternal::flamestrike_nearby;
|
||||
creators["flamestrike active and medium aoe"] = &MageTriggerFactoryInternal::flamestrike_blizzard;
|
||||
creators["arcane blast 4 stacks and missile barrage"] = &MageTriggerFactoryInternal::arcane_blast_4_stacks_and_missile_barrage;
|
||||
creators["icy veins on cd"] = &MageTriggerFactoryInternal::icy_veins_on_cd;
|
||||
creators["deep freeze on cd"] = &MageTriggerFactoryInternal::deep_freeze_on_cd;
|
||||
creators["no mana gem"] = &MageTriggerFactoryInternal::NoManaGem;
|
||||
creators["blizzard channel check"] = &MageTriggerFactoryInternal::blizzard_channel_check;
|
||||
creators["blast wave off cd"] = &MageTriggerFactoryInternal::blast_wave_off_cd;
|
||||
creators["blast wave off cd and medium aoe"] = &MageTriggerFactoryInternal::blast_wave_off_cd_and_medium_aoe;
|
||||
creators["no firestarter strategy"] = &MageTriggerFactoryInternal::no_firestarter_strategy;
|
||||
creators["enemy is close and no firestarter strategy"] = &MageTriggerFactoryInternal::enemy_is_close_and_no_firestarter_strategy;
|
||||
creators["enemy too close for spell and no firestarter strategy"] = &MageTriggerFactoryInternal::enemy_too_close_for_spell_and_no_firestarter_strategy;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* presence_of_mind(PlayerbotAI* botAI) { return new PresenceOfMindTrigger(botAI); }
|
||||
static Trigger* frost_ward(PlayerbotAI* botAI) { return new FrostWardTrigger(botAI); }
|
||||
static Trigger* fire_ward(PlayerbotAI* botAI) { return new FireWardTrigger(botAI); }
|
||||
static Trigger* arcane_power(PlayerbotAI* botAI) { return new ArcanePowerTrigger(botAI); }
|
||||
static Trigger* hot_streak(PlayerbotAI* botAI) { return new HotStreakTrigger(botAI); }
|
||||
static Trigger* fireball(PlayerbotAI* botAI) { return new FireballTrigger(botAI); }
|
||||
static Trigger* pyroblast(PlayerbotAI* botAI) { return new PyroblastTrigger(botAI); }
|
||||
static Trigger* combustion(PlayerbotAI* botAI) { return new CombustionTrigger(botAI); }
|
||||
static Trigger* fingers_of_frost(PlayerbotAI* botAI) { return new FingersOfFrostTrigger(botAI); }
|
||||
static Trigger* brain_freeze(PlayerbotAI* botAI) { return new BrainFreezeTrigger(botAI); }
|
||||
static Trigger* icy_veins(PlayerbotAI* botAI) { return new IcyVeinsTrigger(botAI); }
|
||||
static Trigger* cold_snap(PlayerbotAI* botAI) { return new ColdSnapTrigger(botAI); }
|
||||
static Trigger* ice_barrier(PlayerbotAI* botAI) { return new IceBarrierTrigger(botAI); }
|
||||
static Trigger* arcane_intellect(PlayerbotAI* botAI) { return new ArcaneIntellectTrigger(botAI); }
|
||||
static Trigger* arcane_intellect_on_party(PlayerbotAI* botAI) { return new ArcaneIntellectOnPartyTrigger(botAI); }
|
||||
static Trigger* mage_armor(PlayerbotAI* botAI) { return new MageArmorTrigger(botAI); }
|
||||
static Trigger* remove_curse(PlayerbotAI* botAI) { return new RemoveCurseTrigger(botAI); }
|
||||
static Trigger* remove_curse_on_party(PlayerbotAI* botAI) { return new PartyMemberRemoveCurseTrigger(botAI); }
|
||||
static Trigger* counterspell(PlayerbotAI* botAI) { return new CounterspellInterruptSpellTrigger(botAI); }
|
||||
static Trigger* polymorph(PlayerbotAI* botAI) { return new PolymorphTrigger(botAI); }
|
||||
static Trigger* spellsteal(PlayerbotAI* botAI) { return new SpellstealTrigger(botAI); }
|
||||
static Trigger* living_bomb(PlayerbotAI* botAI) { return new LivingBombTrigger(botAI); }
|
||||
static Trigger* living_bomb_on_attackers(PlayerbotAI* botAI) { return new LivingBombOnAttackersTrigger(botAI); }
|
||||
static Trigger* missile_barrage(PlayerbotAI* botAI) { return new MissileBarrageTrigger(botAI); }
|
||||
static Trigger* arcane_blast(PlayerbotAI* botAI) { return new ArcaneBlastTrigger(botAI); }
|
||||
static Trigger* counterspell_enemy_healer(PlayerbotAI* botAI) { return new CounterspellEnemyHealerTrigger(botAI); }
|
||||
static Trigger* arcane_blast_stack(PlayerbotAI* botAI) { return new ArcaneBlastStackTrigger(botAI); }
|
||||
static Trigger* mirror_image(PlayerbotAI* botAI) { return new MirrorImageTrigger(botAI); }
|
||||
static Trigger* frost_nova_on_target(PlayerbotAI* botAI) { return new FrostNovaOnTargetTrigger(botAI); }
|
||||
static Trigger* frostbite_on_target(PlayerbotAI* botAI) { return new FrostbiteOnTargetTrigger(botAI); }
|
||||
static Trigger* no_focus_magic(PlayerbotAI* botAI) { return new NoFocusMagicTrigger(botAI); }
|
||||
static Trigger* frostfire_bolt(PlayerbotAI* botAI) { return new FrostfireBoltTrigger(botAI); }
|
||||
static Trigger* improved_scorch(PlayerbotAI* botAI) { return new ImprovedScorchTrigger(botAI); }
|
||||
static Trigger* firestarter(PlayerbotAI* botAI) { return new FirestarterTrigger(botAI); }
|
||||
static Trigger* flamestrike_nearby(PlayerbotAI* botAI) { return new FlamestrikeNearbyTrigger(botAI); }
|
||||
static Trigger* flamestrike_blizzard(PlayerbotAI* botAI) { return new FlamestrikeBlizzardTrigger(botAI); }
|
||||
static Trigger* arcane_blast_4_stacks_and_missile_barrage(PlayerbotAI* botAI) { return new ArcaneBlast4StacksAndMissileBarrageTrigger(botAI); }
|
||||
static Trigger* icy_veins_on_cd(PlayerbotAI* botAI) { return new IcyVeinsCooldownTrigger(botAI); }
|
||||
static Trigger* deep_freeze_on_cd(PlayerbotAI* botAI) { return new DeepFreezeCooldownTrigger(botAI); }
|
||||
static Trigger* NoManaGem(PlayerbotAI* botAI) { return new NoManaGemTrigger(botAI); }
|
||||
static Trigger* blizzard_channel_check(PlayerbotAI* botAI) { return new BlizzardChannelCheckTrigger(botAI); }
|
||||
static Trigger* blast_wave_off_cd(PlayerbotAI* botAI) { return new BlastWaveOffCdTrigger(botAI); }
|
||||
static Trigger* blast_wave_off_cd_and_medium_aoe(PlayerbotAI* botAI) { return new BlastWaveOffCdTriggerAndMediumAoeTrigger(botAI); }
|
||||
static Trigger* no_firestarter_strategy(PlayerbotAI* botAI) { return new NoFirestarterStrategyTrigger(botAI); }
|
||||
static Trigger* enemy_is_close_and_no_firestarter_strategy(PlayerbotAI* botAI) { return new EnemyIsCloseAndNoFirestarterStrategyTrigger(botAI); }
|
||||
static Trigger* enemy_too_close_for_spell_and_no_firestarter_strategy(PlayerbotAI* botAI) { return new EnemyTooCloseForSpellAndNoFirestarterStrategyTrigger(botAI); }
|
||||
};
|
||||
|
||||
class MageAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
MageAiObjectContextInternal()
|
||||
{
|
||||
creators["arcane power"] = &MageAiObjectContextInternal::arcane_power;
|
||||
creators["presence of mind"] = &MageAiObjectContextInternal::presence_of_mind;
|
||||
creators["frostbolt"] = &MageAiObjectContextInternal::frostbolt;
|
||||
creators["frostfire bolt"] = &MageAiObjectContextInternal::frostfire_bolt;
|
||||
creators["ice lance"] = &MageAiObjectContextInternal::ice_lance;
|
||||
creators["deep freeze"] = &MageAiObjectContextInternal::deep_freeze;
|
||||
creators["blizzard"] = &MageAiObjectContextInternal::blizzard;
|
||||
creators["cone of cold"] = &MageAiObjectContextInternal::cone_of_cold;
|
||||
creators["frost nova"] = &MageAiObjectContextInternal::frost_nova;
|
||||
creators["arcane intellect"] = &MageAiObjectContextInternal::arcane_intellect;
|
||||
creators["arcane intellect on party"] = &MageAiObjectContextInternal::arcane_intellect_on_party;
|
||||
creators["conjure water"] = &MageAiObjectContextInternal::conjure_water;
|
||||
creators["conjure food"] = &MageAiObjectContextInternal::conjure_food;
|
||||
creators["conjure mana gem"] = &MageAiObjectContextInternal::conjure_mana_gem;
|
||||
creators["molten armor"] = &MageAiObjectContextInternal::molten_armor;
|
||||
creators["mage armor"] = &MageAiObjectContextInternal::mage_armor;
|
||||
creators["ice armor"] = &MageAiObjectContextInternal::ice_armor;
|
||||
creators["frost armor"] = &MageAiObjectContextInternal::frost_armor;
|
||||
creators["fireball"] = &MageAiObjectContextInternal::fireball;
|
||||
creators["pyroblast"] = &MageAiObjectContextInternal::pyroblast;
|
||||
creators["flamestrike"] = &MageAiObjectContextInternal::flamestrike;
|
||||
creators["fire blast"] = &MageAiObjectContextInternal::fire_blast;
|
||||
creators["scorch"] = &MageAiObjectContextInternal::scorch;
|
||||
creators["counterspell"] = &MageAiObjectContextInternal::counterspell;
|
||||
creators["remove curse"] = &MageAiObjectContextInternal::remove_curse;
|
||||
creators["remove curse on party"] = &MageAiObjectContextInternal::remove_curse_on_party;
|
||||
creators["remove lesser curse"] = &MageAiObjectContextInternal::remove_lesser_curse;
|
||||
creators["remove lesser curse on party"] = &MageAiObjectContextInternal::remove_lesser_curse_on_party;
|
||||
creators["icy veins"] = &MageAiObjectContextInternal::icy_veins;
|
||||
creators["cold snap"] = &MageAiObjectContextInternal::cold_snap;
|
||||
creators["ice barrier"] = &MageAiObjectContextInternal::ice_barrier;
|
||||
creators["summon water elemental"] = &MageAiObjectContextInternal::summon_water_elemental;
|
||||
creators["combustion"] = &MageAiObjectContextInternal::combustion;
|
||||
creators["ice block"] = &MageAiObjectContextInternal::ice_block;
|
||||
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
||||
creators["spellsteal"] = &MageAiObjectContextInternal::spellsteal;
|
||||
creators["living bomb"] = &MageAiObjectContextInternal::living_bomb;
|
||||
creators["living bomb on attackers"] = &MageAiObjectContextInternal::living_bomb_on_attackers;
|
||||
creators["dragon's breath"] = &MageAiObjectContextInternal::dragons_breath;
|
||||
creators["blast wave"] = &MageAiObjectContextInternal::blast_wave;
|
||||
creators["invisibility"] = &MageAiObjectContextInternal::invisibility;
|
||||
creators["evocation"] = &MageAiObjectContextInternal::evocation;
|
||||
creators["arcane blast"] = &MageAiObjectContextInternal::arcane_blast;
|
||||
creators["arcane barrage"] = &MageAiObjectContextInternal::arcane_barrage;
|
||||
creators["arcane missiles"] = &MageAiObjectContextInternal::arcane_missiles;
|
||||
creators["counterspell on enemy healer"] = &MageAiObjectContextInternal::counterspell_on_enemy_healer;
|
||||
creators["fire ward"] = &MageAiObjectContextInternal::fire_ward;
|
||||
creators["frost ward"] = &MageAiObjectContextInternal::frost_ward;
|
||||
creators["mirror image"] = &MageAiObjectContextInternal::mirror_image;
|
||||
creators["focus magic on party"] = &MageAiObjectContextInternal::focus_magic_on_party;
|
||||
creators["blink back"] = &MageAiObjectContextInternal::blink_back;
|
||||
creators["use mana sapphire"] = &MageAiObjectContextInternal::use_mana_sapphire;
|
||||
creators["use mana emerald"] = &MageAiObjectContextInternal::use_mana_emerald;
|
||||
creators["use mana ruby"] = &MageAiObjectContextInternal::use_mana_ruby;
|
||||
creators["use mana citrine"] = &MageAiObjectContextInternal::use_mana_citrine;
|
||||
creators["use mana jade"] = &MageAiObjectContextInternal::use_mana_jade;
|
||||
creators["use mana agate"] = &MageAiObjectContextInternal::use_mana_agate;
|
||||
creators["mana shield"] = &MageAiObjectContextInternal::mana_shield;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* presence_of_mind(PlayerbotAI* botAI) { return new CastPresenceOfMindAction(botAI); }
|
||||
static Action* frost_ward(PlayerbotAI* botAI) { return new CastFrostWardAction(botAI); }
|
||||
static Action* fire_ward(PlayerbotAI* botAI) { return new CastFireWardAction(botAI); }
|
||||
static Action* arcane_power(PlayerbotAI* botAI) { return new CastArcanePowerAction(botAI); }
|
||||
static Action* arcane_missiles(PlayerbotAI* botAI) { return new CastArcaneMissilesAction(botAI); }
|
||||
static Action* arcane_barrage(PlayerbotAI* botAI) { return new CastArcaneBarrageAction(botAI); }
|
||||
static Action* arcane_blast(PlayerbotAI* botAI) { return new CastArcaneBlastAction(botAI); }
|
||||
static Action* frostbolt(PlayerbotAI* botAI) { return new CastFrostboltAction(botAI); }
|
||||
static Action* frostfire_bolt(PlayerbotAI* botAI) { return new CastFrostfireBoltAction(botAI); }
|
||||
static Action* ice_lance(PlayerbotAI* botAI) { return new CastIceLanceAction(botAI); }
|
||||
static Action* deep_freeze(PlayerbotAI* botAI) { return new CastDeepFreezeAction(botAI); }
|
||||
static Action* blizzard(PlayerbotAI* botAI) { return new CastBlizzardAction(botAI); }
|
||||
static Action* cone_of_cold(PlayerbotAI* botAI) { return new CastConeOfColdAction(botAI); }
|
||||
static Action* frost_nova(PlayerbotAI* botAI) { return new CastFrostNovaAction(botAI); }
|
||||
static Action* arcane_intellect(PlayerbotAI* botAI) { return new CastArcaneIntellectAction(botAI); }
|
||||
static Action* arcane_intellect_on_party(PlayerbotAI* botAI) { return new CastArcaneIntellectOnPartyAction(botAI); }
|
||||
static Action* conjure_water(PlayerbotAI* botAI) { return new CastConjureWaterAction(botAI); }
|
||||
static Action* conjure_food(PlayerbotAI* botAI) { return new CastConjureFoodAction(botAI); }
|
||||
static Action* conjure_mana_gem(PlayerbotAI* botAI) { return new CastConjureManaGemAction(botAI); }
|
||||
static Action* molten_armor(PlayerbotAI* botAI) { return new CastMoltenArmorAction(botAI); }
|
||||
static Action* mage_armor(PlayerbotAI* botAI) { return new CastMageArmorAction(botAI); }
|
||||
static Action* ice_armor(PlayerbotAI* botAI) { return new CastIceArmorAction(botAI); }
|
||||
static Action* frost_armor(PlayerbotAI* botAI) { return new CastFrostArmorAction(botAI); }
|
||||
static Action* fireball(PlayerbotAI* botAI) { return new CastFireballAction(botAI); }
|
||||
static Action* pyroblast(PlayerbotAI* botAI) { return new CastPyroblastAction(botAI); }
|
||||
static Action* flamestrike(PlayerbotAI* botAI) { return new CastFlamestrikeAction(botAI); }
|
||||
static Action* fire_blast(PlayerbotAI* botAI) { return new CastFireBlastAction(botAI); }
|
||||
static Action* scorch(PlayerbotAI* botAI) { return new CastScorchAction(botAI); }
|
||||
static Action* counterspell(PlayerbotAI* botAI) { return new CastCounterspellAction(botAI); }
|
||||
static Action* remove_curse(PlayerbotAI* botAI) { return new CastRemoveCurseAction(botAI); }
|
||||
static Action* remove_curse_on_party(PlayerbotAI* botAI) { return new CastRemoveCurseOnPartyAction(botAI); }
|
||||
static Action* remove_lesser_curse(PlayerbotAI* botAI) { return new CastRemoveLesserCurseAction(botAI); }
|
||||
static Action* remove_lesser_curse_on_party(PlayerbotAI* botAI) { return new CastRemoveLesserCurseOnPartyAction(botAI); }
|
||||
static Action* icy_veins(PlayerbotAI* botAI) { return new CastIcyVeinsAction(botAI); }
|
||||
static Action* cold_snap(PlayerbotAI* botAI) { return new CastColdSnapAction(botAI); }
|
||||
static Action* ice_barrier(PlayerbotAI* botAI) { return new CastIceBarrierAction(botAI); }
|
||||
static Action* summon_water_elemental(PlayerbotAI* botAI) { return new CastSummonWaterElementalAction(botAI); }
|
||||
static Action* combustion(PlayerbotAI* botAI) { return new CastCombustionAction(botAI); }
|
||||
static Action* ice_block(PlayerbotAI* botAI) { return new CastIceBlockAction(botAI); }
|
||||
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
||||
static Action* spellsteal(PlayerbotAI* botAI) { return new CastSpellstealAction(botAI); }
|
||||
static Action* living_bomb(PlayerbotAI* botAI) { return new CastLivingBombAction(botAI); }
|
||||
static Action* living_bomb_on_attackers(PlayerbotAI* botAI) { return new CastLivingBombOnAttackersAction(botAI); }
|
||||
static Action* dragons_breath(PlayerbotAI* botAI) { return new CastDragonsBreathAction(botAI); }
|
||||
static Action* blast_wave(PlayerbotAI* botAI) { return new CastBlastWaveAction(botAI); }
|
||||
static Action* invisibility(PlayerbotAI* botAI) { return new CastInvisibilityAction(botAI); }
|
||||
static Action* evocation(PlayerbotAI* botAI) { return new CastEvocationAction(botAI); }
|
||||
static Action* counterspell_on_enemy_healer(PlayerbotAI* botAI) { return new CastCounterspellOnEnemyHealerAction(botAI); }
|
||||
static Action* mirror_image(PlayerbotAI* botAI) { return new CastMirrorImageAction(botAI); }
|
||||
static Action* focus_magic_on_party(PlayerbotAI* botAI) { return new CastFocusMagicOnPartyAction(botAI); }
|
||||
static Action* blink_back(PlayerbotAI* botAI) { return new CastBlinkBackAction(botAI); }
|
||||
static Action* use_mana_sapphire(PlayerbotAI* botAI) { return new UseManaSapphireAction(botAI); }
|
||||
static Action* use_mana_emerald(PlayerbotAI* botAI) { return new UseManaEmeraldAction(botAI); }
|
||||
static Action* use_mana_ruby(PlayerbotAI* botAI) { return new UseManaRubyAction(botAI); }
|
||||
static Action* use_mana_citrine(PlayerbotAI* botAI) { return new UseManaCitrineAction(botAI); }
|
||||
static Action* use_mana_jade(PlayerbotAI* botAI) { return new UseManaJadeAction(botAI); }
|
||||
static Action* use_mana_agate(PlayerbotAI* botAI) { return new UseManaAgateAction(botAI); }
|
||||
static Action* mana_shield(PlayerbotAI* botAI) { return new CastManaShieldAction(botAI); }
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> MageAiObjectContext::sharedStrategyContexts;
|
||||
SharedNamedObjectContextList<Action> MageAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> MageAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> MageAiObjectContext::sharedValueContexts;
|
||||
|
||||
MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void MageAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void MageAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new MageStrategyFactoryInternal());
|
||||
strategyContexts.Add(new MageCombatStrategyFactoryInternal());
|
||||
strategyContexts.Add(new MageBuffStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void MageAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new MageAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void MageAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new MageTriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void MageAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Mage/MageAiObjectContext.h
Normal file
30
src/Ai/Class/Mage/MageAiObjectContext.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_MAGEAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_MAGEAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class MageAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
MageAiObjectContext(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
|
||||
67
src/Ai/Class/Mage/Strategy/ArcaneMageStrategy.cpp
Normal file
67
src/Ai/Class/Mage/Strategy/ArcaneMageStrategy.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 "ArcaneMageStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class ArcaneMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
ArcaneMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["arcane blast"] = &arcane_blast;
|
||||
creators["arcane barrage"] = &arcane_barrage;
|
||||
creators["arcane missiles"] = &arcane_missiles;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["frostbolt"] = &frostbolt;
|
||||
creators["arcane power"] = &arcane_power;
|
||||
creators["icy veins"] = &icy_veins;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* arcane_blast(PlayerbotAI*) { return new ActionNode("arcane blast", {}, {}, {}); }
|
||||
static ActionNode* arcane_barrage(PlayerbotAI*) { return new ActionNode("arcane barrage", {}, {}, {}); }
|
||||
static ActionNode* arcane_missiles(PlayerbotAI*) { return new ActionNode("arcane missiles", {}, {}, {}); }
|
||||
static ActionNode* fire_blast(PlayerbotAI*) { return new ActionNode("fire blast", {}, {}, {}); }
|
||||
static ActionNode* frostbolt(PlayerbotAI*) { return new ActionNode("frostbolt", {}, {}, {}); }
|
||||
static ActionNode* arcane_power(PlayerbotAI*) { return new ActionNode("arcane power", {}, {}, {}); }
|
||||
static ActionNode* icy_veins(PlayerbotAI*) { return new ActionNode("icy veins", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
ArcaneMageStrategy::ArcaneMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new ArcaneMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> ArcaneMageStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("arcane blast", 5.6f),
|
||||
NextAction("arcane missiles", 5.5f),
|
||||
NextAction("arcane barrage", 5.4f), // cast while moving
|
||||
NextAction("fire blast", 5.3f), // cast while moving if arcane barrage isn't available/learned
|
||||
NextAction("frostbolt", 5.2f), // for arcane immune targets
|
||||
NextAction("shoot", 5.1f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void ArcaneMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericMageStrategy::InitTriggers(triggers);
|
||||
|
||||
// Proc Trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"arcane blast 4 stacks and missile barrage",
|
||||
{
|
||||
NextAction("arcane missiles", 15.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
23
src/Ai/Class/Mage/Strategy/ArcaneMageStrategy.h
Normal file
23
src/Ai/Class/Mage/Strategy/ArcaneMageStrategy.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_ARCANEMAGESTRATEGY_H
|
||||
#define _PLAYERBOT_ARCANEMAGESTRATEGY_H
|
||||
|
||||
#include "GenericMageStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ArcaneMageStrategy : public GenericMageStrategy
|
||||
{
|
||||
public:
|
||||
ArcaneMageStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "arcane"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
102
src/Ai/Class/Mage/Strategy/FireMageStrategy.cpp
Normal file
102
src/Ai/Class/Mage/Strategy/FireMageStrategy.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 "FireMageStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class FireMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FireMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["fireball"] = &fireball;
|
||||
creators["frostbolt"] = &frostbolt;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["pyroblast"] = &pyroblast;
|
||||
creators["scorch"] = &scorch;
|
||||
creators["living bomb"] = &living_bomb;
|
||||
creators["combustion"] = &combustion;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* fireball(PlayerbotAI*) { return new ActionNode("fireball", {}, {}, {}); }
|
||||
static ActionNode* frostbolt(PlayerbotAI*) { return new ActionNode("frostbolt", {}, {}, {}); }
|
||||
static ActionNode* fire_blast(PlayerbotAI*) { return new ActionNode("fire blast", {}, {}, {}); }
|
||||
static ActionNode* pyroblast(PlayerbotAI*) { return new ActionNode("pyroblast", {}, {}, {}); }
|
||||
static ActionNode* scorch(PlayerbotAI*) { return new ActionNode("scorch", {}, {}, {}); }
|
||||
static ActionNode* living_bomb(PlayerbotAI*) { return new ActionNode("living bomb", {}, {}, {}); }
|
||||
static ActionNode* combustion(PlayerbotAI*) { return new ActionNode("combustion", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
FireMageStrategy::FireMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FireMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> FireMageStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("fireball", 5.3f),
|
||||
NextAction("frostbolt", 5.2f), // fire immune target
|
||||
NextAction("fire blast", 5.1f), // cast during movement
|
||||
NextAction("shoot", 5.0f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization =====
|
||||
void FireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericMageStrategy::InitTriggers(triggers);
|
||||
|
||||
// Debuff Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"improved scorch",
|
||||
{
|
||||
NextAction("scorch", 19.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"living bomb",
|
||||
{
|
||||
NextAction("living bomb", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Proc Trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"hot streak",
|
||||
{
|
||||
NextAction("pyroblast", 25.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Combat strategy to run to melee for Dragon's Breath and Blast Wave
|
||||
// Disabled by default for the Fire/Frostfire spec
|
||||
// To enable, type "co +firestarter"
|
||||
// To disable, type "co -firestarter"
|
||||
FirestarterStrategy::FirestarterStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void FirestarterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"blast wave off cd and medium aoe",
|
||||
{
|
||||
NextAction("reach melee", 25.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
31
src/Ai/Class/Mage/Strategy/FireMageStrategy.h
Normal file
31
src/Ai/Class/Mage/Strategy/FireMageStrategy.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_FIREMAGESTRATEGY_H
|
||||
#define _PLAYERBOT_FIREMAGESTRATEGY_H
|
||||
|
||||
#include "GenericMageStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class FireMageStrategy : public GenericMageStrategy
|
||||
{
|
||||
public:
|
||||
FireMageStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "fire"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
class FirestarterStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
FirestarterStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "firestarter"; }
|
||||
};
|
||||
#endif
|
||||
82
src/Ai/Class/Mage/Strategy/FrostFireMageStrategy.cpp
Normal file
82
src/Ai/Class/Mage/Strategy/FrostFireMageStrategy.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 "FrostFireMageStrategy.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class FrostFireMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FrostFireMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["frostfire bolt"] = &frostfire_bolt;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["pyroblast"] = &pyroblast;
|
||||
creators["combustion"] = &combustion;
|
||||
creators["icy veins"] = &icy_veins;
|
||||
creators["scorch"] = &scorch;
|
||||
creators["living bomb"] = &living_bomb;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* frostfire_bolt(PlayerbotAI*) { return new ActionNode("frostfire bolt", {}, {}, {}); }
|
||||
static ActionNode* fire_blast(PlayerbotAI*) { return new ActionNode("fire blast", {}, {}, {}); }
|
||||
static ActionNode* pyroblast(PlayerbotAI*) { return new ActionNode("pyroblast", {}, {}, {}); }
|
||||
static ActionNode* combustion(PlayerbotAI*) { return new ActionNode("combustion", {}, {}, {}); }
|
||||
static ActionNode* icy_veins(PlayerbotAI*) { return new ActionNode("icy veins", {}, {}, {}); }
|
||||
static ActionNode* scorch(PlayerbotAI*) { return new ActionNode("scorch", {}, {}, {}); }
|
||||
static ActionNode* living_bomb(PlayerbotAI*) { return new ActionNode("living bomb", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
FrostFireMageStrategy::FrostFireMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FrostFireMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> FrostFireMageStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("frostfire bolt", 5.2f),
|
||||
NextAction("fire blast", 5.1f), // cast during movement
|
||||
NextAction("shoot", 5.0f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization =====
|
||||
void FrostFireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericMageStrategy::InitTriggers(triggers);
|
||||
|
||||
// Debuff Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"improved scorch",
|
||||
{
|
||||
NextAction("scorch", 19.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"living bomb",
|
||||
{
|
||||
NextAction("living bomb", 18.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Proc Trigger
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"hot streak",
|
||||
{
|
||||
NextAction("pyroblast", 25.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
23
src/Ai/Class/Mage/Strategy/FrostFireMageStrategy.h
Normal file
23
src/Ai/Class/Mage/Strategy/FrostFireMageStrategy.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_FROSTFIREMAGESTRATEGY_H
|
||||
#define _PLAYERBOT_FROSTFIREMAGESTRATEGY_H
|
||||
|
||||
#include "GenericMageStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class FrostFireMageStrategy : public GenericMageStrategy
|
||||
{
|
||||
public:
|
||||
FrostFireMageStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "frostfire"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
142
src/Ai/Class/Mage/Strategy/FrostMageStrategy.cpp
Normal file
142
src/Ai/Class/Mage/Strategy/FrostMageStrategy.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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 "FrostMageStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
// ===== Action Node Factory =====
|
||||
class FrostMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
FrostMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["cold snap"] = &cold_snap;
|
||||
creators["ice barrier"] = &ice_barrier;
|
||||
creators["summon water elemental"] = &summon_water_elemental;
|
||||
creators["deep freeze"] = &deep_freeze;
|
||||
creators["icy veins"] = &icy_veins;
|
||||
creators["frostbolt"] = &frostbolt;
|
||||
creators["ice lance"] = &ice_lance;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["fireball"] = &fireball;
|
||||
creators["frostfire bolt"] = &frostfire_bolt;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* cold_snap(PlayerbotAI*) { return new ActionNode("cold snap", {}, {}, {}); }
|
||||
static ActionNode* ice_barrier(PlayerbotAI*) { return new ActionNode("ice barrier", {}, {}, {}); }
|
||||
static ActionNode* summon_water_elemental(PlayerbotAI*) { return new ActionNode("summon water elemental", {}, {}, {}); }
|
||||
static ActionNode* deep_freeze(PlayerbotAI*) { return new ActionNode("deep freeze", {}, {}, {}); }
|
||||
static ActionNode* icy_veins(PlayerbotAI*) { return new ActionNode("icy veins", {}, {}, {}); }
|
||||
static ActionNode* frostbolt(PlayerbotAI*) { return new ActionNode("frostbolt", {}, {}, {}); }
|
||||
static ActionNode* ice_lance(PlayerbotAI*) { return new ActionNode("ice lance", {}, {}, {}); }
|
||||
static ActionNode* fire_blast(PlayerbotAI*) { return new ActionNode("fire blast", {}, {}, {}); }
|
||||
static ActionNode* fireball(PlayerbotAI*) { return new ActionNode("fireball", {}, {}, {}); }
|
||||
static ActionNode* frostfire_bolt(PlayerbotAI*) { return new ActionNode("frostfire bolt", {}, {}, {}); }
|
||||
};
|
||||
|
||||
// ===== Single Target Strategy =====
|
||||
FrostMageStrategy::FrostMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new FrostMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
// ===== Default Actions =====
|
||||
std::vector<NextAction> FrostMageStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("frostbolt", 5.4f),
|
||||
NextAction("ice lance", 5.3f), // cast during movement
|
||||
NextAction("fire blast", 5.2f), // cast during movement if ice lance is not learned
|
||||
NextAction("shoot", 5.1f),
|
||||
NextAction("fireball", 5.0f)
|
||||
};
|
||||
}
|
||||
|
||||
// ===== Trigger Initialization ===
|
||||
void FrostMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericMageStrategy::InitTriggers(triggers);
|
||||
|
||||
// Pet/Defensive triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"no pet",
|
||||
{
|
||||
NextAction("summon water elemental", 30.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"has pet",
|
||||
{
|
||||
NextAction("toggle pet spell", 60.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"new pet",
|
||||
{
|
||||
NextAction("set pet stance", 60.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium health",
|
||||
{
|
||||
NextAction("ice barrier", 29.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"being attacked",
|
||||
{
|
||||
NextAction("ice barrier", 29.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Proc/Freeze triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"brain freeze",
|
||||
{
|
||||
NextAction("frostfire bolt", 19.5f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"fingers of frost",
|
||||
{
|
||||
NextAction("deep freeze", 19.0f),
|
||||
NextAction("frostbolt", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"frostbite on target",
|
||||
{
|
||||
NextAction("deep freeze", 19.0f),
|
||||
NextAction("frostbolt", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"frost nova on target",
|
||||
{
|
||||
NextAction("deep freeze", 19.0f),
|
||||
NextAction("frostbolt", 18.0f)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
23
src/Ai/Class/Mage/Strategy/FrostMageStrategy.h
Normal file
23
src/Ai/Class/Mage/Strategy/FrostMageStrategy.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_FROSTMAGESTRATEGY_H
|
||||
#define _PLAYERBOT_FROSTMAGESTRATEGY_H
|
||||
|
||||
#include "GenericMageStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class FrostMageStrategy : public GenericMageStrategy
|
||||
{
|
||||
public:
|
||||
FrostMageStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "frost"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
src/Ai/Class/Mage/Strategy/GenericMageNonCombatStrategy.cpp
Normal file
74
src/Ai/Class/Mage/Strategy/GenericMageNonCombatStrategy.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 "GenericMageNonCombatStrategy.h"
|
||||
#include "AiFactory.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class GenericMageNonCombatStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericMageNonCombatStrategyActionNodeFactory()
|
||||
{
|
||||
creators["molten armor"] = &molten_armor;
|
||||
creators["mage armor"] = &mage_armor;
|
||||
creators["ice armor"] = &ice_armor;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* molten_armor([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("molten armor",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("mage armor") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* mage_armor([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("mage armor",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("ice armor") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* ice_armor([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("ice armor",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("frost armor") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericMageNonCombatStrategy::GenericMageNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericMageNonCombatStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericMageNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("arcane intellect", { NextAction("arcane intellect", 21.0f) }));
|
||||
triggers.push_back(new TriggerNode("no focus magic", { NextAction("focus magic on party", 19.0f) }));
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", 1.0f) }));
|
||||
triggers.push_back(new TriggerNode("no mana gem", { NextAction("conjure mana gem", 20.0f) }));
|
||||
}
|
||||
|
||||
void MageBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("mage armor", { NextAction("mage armor", 19.0f) }));
|
||||
}
|
||||
|
||||
void MageBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("mage armor", { NextAction("molten armor", 19.0f) }));
|
||||
}
|
||||
|
||||
void MageBuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("arcane intellect on party", { NextAction("arcane intellect on party", 20.0f) }));
|
||||
}
|
||||
49
src/Ai/Class/Mage/Strategy/GenericMageNonCombatStrategy.h
Normal file
49
src/Ai/Class/Mage/Strategy/GenericMageNonCombatStrategy.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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_GENERICMAGENONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICMAGENONCOMBATSTRATEGY_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericMageNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericMageNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "nc"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
class MageBuffManaStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageBuffManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bmana"; }
|
||||
};
|
||||
|
||||
class MageBuffDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageBuffDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bdps"; }
|
||||
};
|
||||
|
||||
class MageBuffStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageBuffStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "buff"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
278
src/Ai/Class/Mage/Strategy/GenericMageStrategy.cpp
Normal file
278
src/Ai/Class/Mage/Strategy/GenericMageStrategy.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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 "GenericMageStrategy.h"
|
||||
#include "AiFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RangedCombatStrategy.h"
|
||||
|
||||
class GenericMageStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericMageStrategyActionNodeFactory()
|
||||
{
|
||||
creators["frostbolt"] = &frostbolt;
|
||||
creators["frostfire bolt"] = &frostfire_bolt;
|
||||
creators["ice lance"] = &ice_lance;
|
||||
creators["fire blast"] = &fire_blast;
|
||||
creators["scorch"] = &scorch;
|
||||
creators["frost nova"] = &frost_nova;
|
||||
creators["cone of cold"] = &cone_of_cold;
|
||||
creators["icy veins"] = &icy_veins;
|
||||
creators["combustion"] = &combustion;
|
||||
creators["evocation"] = &evocation;
|
||||
creators["dragon's breath"] = &dragons_breath;
|
||||
creators["blast wave"] = &blast_wave;
|
||||
creators["remove curse"] = &remove_curse;
|
||||
creators["remove curse on party"] = &remove_curse_on_party;
|
||||
creators["fireball"] = &fireball;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* frostbolt([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frostbolt",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("shoot") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* frostfire_bolt([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frostfire bolt",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("fireball") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* ice_lance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("ice lance",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* fire_blast([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("fire blast",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* scorch([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("scorch",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("shoot") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* frost_nova([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("frost nova",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* cone_of_cold([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("cone of cold",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* icy_veins([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("icy veins",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* combustion([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("combustion",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* evocation([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("evocation",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("mana potion") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* dragons_breath([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("dragon's breath",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* blast_wave([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("blast wave",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* remove_curse([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("remove curse",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("remove lesser curse") },
|
||||
/*C*/ {});
|
||||
}
|
||||
|
||||
static ActionNode* remove_curse_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("remove curse on party",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("remove lesser curse on party") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* fireball([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("fireball",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("shoot") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
GenericMageStrategy::GenericMageStrategy(PlayerbotAI* botAI) : RangedCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericMageStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
RangedCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
// Threat Triggers
|
||||
triggers.push_back(new TriggerNode("high threat", { NextAction("mirror image", 60.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium threat", { NextAction("invisibility", 30.0f) }));
|
||||
|
||||
// Defensive Triggers
|
||||
triggers.push_back(new TriggerNode("critical health", { NextAction("ice block", 90.0f) }));
|
||||
triggers.push_back(new TriggerNode("low health", { NextAction("mana shield", 85.0f) }));
|
||||
triggers.push_back(new TriggerNode("fire ward", { NextAction("fire ward", 90.0f) }));
|
||||
triggers.push_back(new TriggerNode("frost ward", { NextAction("frost ward", 90.0f) }));
|
||||
triggers.push_back(new TriggerNode("enemy is close and no firestarter strategy", { NextAction("frost nova", 50.0f) }));
|
||||
triggers.push_back(new TriggerNode("enemy too close for spell and no firestarter strategy", { NextAction("blink back", 35.0f) }));
|
||||
|
||||
// Mana Threshold Triggers
|
||||
Player* bot = botAI->GetBot();
|
||||
if (bot->HasSpell(42985)) // Mana Sapphire
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana sapphire", 90.0f) }));
|
||||
else if (bot->HasSpell(27101)) // Mana Emerald
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana emerald", 90.0f) }));
|
||||
else if (bot->HasSpell(10054)) // Mana Ruby
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana ruby", 90.0f) }));
|
||||
else if (bot->HasSpell(10053)) // Mana Citrine
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana citrine", 90.0f) }));
|
||||
else if (bot->HasSpell(3552)) // Mana Jade
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana jade", 90.0f) }));
|
||||
else if (bot->HasSpell(759)) // Mana Agate
|
||||
triggers.push_back(new TriggerNode("high mana", { NextAction("use mana agate", 90.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("medium mana", { NextAction("mana potion", 90.0f) }));
|
||||
triggers.push_back(new TriggerNode("low mana", { NextAction("evocation", 90.0f) }));
|
||||
|
||||
// Counterspell / Spellsteal Triggers
|
||||
triggers.push_back(new TriggerNode("spellsteal", { NextAction("spellsteal", 40.0f) }));
|
||||
triggers.push_back(new TriggerNode("counterspell on enemy healer", { NextAction("counterspell on enemy healer", 40.0f) }));
|
||||
}
|
||||
|
||||
void MageCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("remove curse", { NextAction("remove curse", 41.0f) }));
|
||||
triggers.push_back(new TriggerNode("remove curse on party", { NextAction("remove curse on party", 40.0f) }));
|
||||
}
|
||||
|
||||
void MageBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Arcane
|
||||
{
|
||||
triggers.push_back(new TriggerNode("arcane power", { NextAction("arcane power", 29.0f) }));
|
||||
triggers.push_back(new TriggerNode("icy veins", { NextAction("icy veins", 28.5f) }));
|
||||
triggers.push_back(new TriggerNode("mirror image", { NextAction("mirror image", 28.0f) }));
|
||||
}
|
||||
else if (tab == 1)
|
||||
{
|
||||
if (bot->HasSpell(44614) /*Frostfire Bolt*/ && bot->HasAura(15047) /*Ice Shards*/)
|
||||
{ // Frostfire
|
||||
triggers.push_back(new TriggerNode("combustion", { NextAction("combustion", 18.0f) }));
|
||||
triggers.push_back(new TriggerNode("icy veins", { NextAction("icy veins", 17.5f) }));
|
||||
triggers.push_back(new TriggerNode("mirror image", { NextAction("mirror image", 17.0f) }));
|
||||
}
|
||||
else
|
||||
{ // Fire
|
||||
triggers.push_back(new TriggerNode("combustion", { NextAction("combustion", 18.0f) }));
|
||||
triggers.push_back(new TriggerNode("mirror image", { NextAction("mirror image", 17.5f) }));
|
||||
}
|
||||
}
|
||||
else if (tab == 2) // Frost
|
||||
{
|
||||
triggers.push_back(new TriggerNode("cold snap", { NextAction("cold snap", 28.0f) }));
|
||||
triggers.push_back(new TriggerNode("icy veins", { NextAction("icy veins", 27.5f) }));
|
||||
triggers.push_back(new TriggerNode("mirror image", { NextAction("mirror image", 26.0f) }));
|
||||
}
|
||||
}
|
||||
|
||||
void MageCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("polymorph", { NextAction("polymorph", 30.0f) }));
|
||||
}
|
||||
|
||||
void MageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("blizzard channel check", { NextAction("cancel channel", 26.0f) }));
|
||||
|
||||
Player* bot = botAI->GetBot();
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
|
||||
if (tab == 0) // Arcane
|
||||
{
|
||||
triggers.push_back(new TriggerNode("flamestrike active and medium aoe", { NextAction("blizzard", 24.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium aoe", {
|
||||
NextAction("flamestrike", 23.0f),
|
||||
NextAction("blizzard", 22.0f) }));
|
||||
triggers.push_back(new TriggerNode("light aoe", { NextAction("arcane explosion", 21.0f) }));
|
||||
}
|
||||
else if (tab == 1) // Fire and Frostfire
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium aoe", {
|
||||
NextAction("dragon's breath", 39.0f),
|
||||
NextAction("blast wave", 38.0f),
|
||||
NextAction("flamestrike", 23.0f),
|
||||
NextAction("blizzard", 22.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("flamestrike active and medium aoe", { NextAction("blizzard", 24.0f) }));
|
||||
triggers.push_back(new TriggerNode("firestarter", { NextAction("flamestrike", 40.0f) }));
|
||||
triggers.push_back(new TriggerNode("living bomb on attackers", { NextAction("living bomb on attackers", 21.0f) }));
|
||||
}
|
||||
else if (tab == 2) // Frost
|
||||
{
|
||||
triggers.push_back(new TriggerNode("flamestrike active and medium aoe", { NextAction("blizzard", 24.0f) }));
|
||||
triggers.push_back(new TriggerNode("medium aoe", {
|
||||
NextAction("flamestrike", 23.0f),
|
||||
NextAction("blizzard", 22.0f) }));
|
||||
triggers.push_back(new TriggerNode("light aoe", { NextAction("cone of cold", 21.0f) }));
|
||||
}
|
||||
}
|
||||
63
src/Ai/Class/Mage/Strategy/GenericMageStrategy.h
Normal file
63
src/Ai/Class/Mage/Strategy/GenericMageStrategy.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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_GENERICMAGESTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICMAGESTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
#include "RangedCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericMageStrategy : public RangedCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericMageStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "mage"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
uint32 GetType() const override
|
||||
{
|
||||
return RangedCombatStrategy::GetType() | STRATEGY_TYPE_RANGED | STRATEGY_TYPE_DPS;
|
||||
}
|
||||
};
|
||||
|
||||
class MageCureStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageCureStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cure"; }
|
||||
};
|
||||
|
||||
class MageBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "boost"; }
|
||||
};
|
||||
|
||||
class MageCcStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
MageCcStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cc"; }
|
||||
};
|
||||
|
||||
class MageAoeStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
MageAoeStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "aoe"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
183
src/Ai/Class/Mage/Trigger/MageTriggers.cpp
Normal file
183
src/Ai/Class/Mage/Trigger/MageTriggers.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 "MageTriggers.h"
|
||||
#include "MageActions.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Player.h"
|
||||
#include "Spell.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "Value.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
bool NoManaGemTrigger::IsActive()
|
||||
{
|
||||
static const std::vector<uint32> gemIds = {
|
||||
33312, // Mana Sapphire
|
||||
22044, // Mana Emerald
|
||||
8008, // Mana Ruby
|
||||
8007, // Mana Citrine
|
||||
5513, // Mana Jade
|
||||
5514 // Mana Agate
|
||||
};
|
||||
Player* bot = botAI->GetBot();
|
||||
for (uint32 gemId : gemIds)
|
||||
{
|
||||
if (bot->GetItemCount(gemId, false) > 0) // false = only in bags
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArcaneIntellectOnPartyTrigger::IsActive()
|
||||
{
|
||||
return BuffOnPartyTrigger::IsActive() && !botAI->HasAura("arcane brilliance", GetTarget());
|
||||
}
|
||||
|
||||
bool ArcaneIntellectTrigger::IsActive()
|
||||
{
|
||||
return BuffTrigger::IsActive() && !botAI->HasAura("arcane brilliance", GetTarget());
|
||||
}
|
||||
|
||||
bool MageArmorTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
return !botAI->HasAura("ice armor", target) && !botAI->HasAura("frost armor", target) &&
|
||||
!botAI->HasAura("molten armor", target) && !botAI->HasAura("mage armor", target);
|
||||
}
|
||||
|
||||
bool FrostNovaOnTargetTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target || !target->IsAlive() || !target->IsInWorld())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return botAI->HasAura(spell, target);
|
||||
}
|
||||
|
||||
bool FrostbiteOnTargetTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target || !target->IsAlive() || !target->IsInWorld())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return botAI->HasAura(spell, target);
|
||||
}
|
||||
|
||||
bool NoFocusMagicTrigger::IsActive()
|
||||
{
|
||||
if (!bot->HasSpell(54646))
|
||||
return false;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return false;
|
||||
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
if (!member || member == bot || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
if (member->HasAura(54646, bot->GetGUID()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeepFreezeCooldownTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
static const uint32 DEEP_FREEZE_SPELL_ID = 44572;
|
||||
|
||||
// If the bot does NOT have Deep Freeze, treat as "on cooldown"
|
||||
if (!bot->HasSpell(DEEP_FREEZE_SPELL_ID))
|
||||
return true;
|
||||
|
||||
// Otherwise, use the default cooldown logic
|
||||
return SpellCooldownTrigger::IsActive();
|
||||
}
|
||||
|
||||
const std::set<uint32> FlamestrikeNearbyTrigger::FLAMESTRIKE_SPELL_IDS = {2120, 2121, 8422, 8423, 10215,
|
||||
10216, 27086, 42925, 42926};
|
||||
|
||||
bool FlamestrikeNearbyTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
for (uint32 spellId : FLAMESTRIKE_SPELL_IDS)
|
||||
{
|
||||
Aura* aura = bot->GetAura(spellId, bot->GetGUID());
|
||||
if (!aura)
|
||||
continue;
|
||||
|
||||
DynamicObject* dynObj = aura->GetDynobjOwner();
|
||||
if (!dynObj)
|
||||
continue;
|
||||
|
||||
float dist = bot->GetDistance2d(dynObj->GetPositionX(), dynObj->GetPositionY());
|
||||
if (dist <= radius)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImprovedScorchTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target || !target->IsAlive() || !target->IsInWorld())
|
||||
return false;
|
||||
|
||||
// List of all spell IDs for Improved Scorch, Winter's Chill, and Shadow Mastery
|
||||
static const uint32 ImprovedScorchExclusiveDebuffs[] = {// Shadow Mastery
|
||||
17794, 17797, 17798, 17799, 17800,
|
||||
// Winter's Chill
|
||||
12579,
|
||||
// Improved Scorch
|
||||
22959};
|
||||
|
||||
for (uint32 spellId : ImprovedScorchExclusiveDebuffs)
|
||||
{
|
||||
if (target->HasAura(spellId))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use default DebuffTrigger logic for the rest (only trigger if debuff is missing or expiring)
|
||||
return DebuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
const std::set<uint32> BlizzardChannelCheckTrigger::BLIZZARD_SPELL_IDS = {
|
||||
10, // Blizzard Rank 1
|
||||
6141, // Blizzard Rank 2
|
||||
8427, // Blizzard Rank 3
|
||||
10185, // Blizzard Rank 4
|
||||
10186, // Blizzard Rank 5
|
||||
10187, // Blizzard Rank 6
|
||||
27085, // Blizzard Rank 7
|
||||
42938, // Blizzard Rank 8
|
||||
42939 // Blizzard Rank 9
|
||||
};
|
||||
|
||||
bool BlizzardChannelCheckTrigger::IsActive()
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
|
||||
// Check if the bot is channeling a spell
|
||||
if (Spell* spell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
{
|
||||
// Only trigger if the spell being channeled is Blizzard
|
||||
if (BLIZZARD_SPELL_IDS.count(spell->m_spellInfo->Id))
|
||||
{
|
||||
uint8 attackerCount = AI_VALUE(uint8, "attacker count");
|
||||
return attackerCount < minEnemies;
|
||||
}
|
||||
}
|
||||
|
||||
// Not channeling Blizzard
|
||||
return false;
|
||||
}
|
||||
344
src/Ai/Class/Mage/Trigger/MageTriggers.h
Normal file
344
src/Ai/Class/Mage/Trigger/MageTriggers.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* 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_MAGETRIGGERS_H
|
||||
#define _PLAYERBOT_MAGETRIGGERS_H
|
||||
|
||||
#include "CureTriggers.h"
|
||||
#include "GenericTriggers.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Trigger.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
// Buff and Out of Combat Triggers
|
||||
|
||||
class ArcaneIntellectOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
ArcaneIntellectOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "arcane intellect", 2 * 2000) {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class ArcaneIntellectTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
ArcaneIntellectTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "arcane intellect", 2 * 2000) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class MageArmorTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
MageArmorTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mage armor", 5 * 2000) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class NoFocusMagicTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoFocusMagicTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no focus magic") {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class IceBarrierTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
IceBarrierTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "ice barrier") {}
|
||||
};
|
||||
|
||||
class NoManaGemTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoManaGemTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no mana gem") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FireWardTrigger : public DeflectSpellTrigger
|
||||
{
|
||||
public:
|
||||
FireWardTrigger(PlayerbotAI* botAI) : DeflectSpellTrigger(botAI, "fire ward") {}
|
||||
};
|
||||
|
||||
class FrostWardTrigger : public DeflectSpellTrigger
|
||||
{
|
||||
public:
|
||||
FrostWardTrigger(PlayerbotAI* botAI) : DeflectSpellTrigger(botAI, "frost ward") {}
|
||||
};
|
||||
|
||||
// Proc and Boost Triggers
|
||||
|
||||
class HotStreakTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
HotStreakTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "hot streak") {}
|
||||
};
|
||||
|
||||
class FirestarterTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
FirestarterTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "firestarter") {}
|
||||
};
|
||||
|
||||
class MissileBarrageTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
MissileBarrageTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "missile barrage") {}
|
||||
};
|
||||
|
||||
class ArcaneBlastTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
ArcaneBlastTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "arcane blast") {}
|
||||
};
|
||||
|
||||
class ArcaneBlastStackTrigger : public HasAuraStackTrigger
|
||||
{
|
||||
public:
|
||||
ArcaneBlastStackTrigger(PlayerbotAI* botAI) : HasAuraStackTrigger(botAI, "arcane blast", 4, 1) {}
|
||||
};
|
||||
|
||||
class ArcaneBlast4StacksAndMissileBarrageTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
ArcaneBlast4StacksAndMissileBarrageTrigger(PlayerbotAI* ai)
|
||||
: TwoTriggers(ai, "arcane blast stack", "missile barrage")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CombustionTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
CombustionTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "combustion") {}
|
||||
};
|
||||
|
||||
class IcyVeinsCooldownTrigger : public SpellCooldownTrigger
|
||||
{
|
||||
public:
|
||||
IcyVeinsCooldownTrigger(PlayerbotAI* botAI) : SpellCooldownTrigger(botAI, "icy veins") {}
|
||||
};
|
||||
|
||||
class DeepFreezeCooldownTrigger : public SpellCooldownTrigger
|
||||
{
|
||||
public:
|
||||
DeepFreezeCooldownTrigger(PlayerbotAI* botAI) : SpellCooldownTrigger(botAI, "deep freeze") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class ColdSnapTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
ColdSnapTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "icy veins on cd", "deep freeze on cd") {}
|
||||
};
|
||||
|
||||
class MirrorImageTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
MirrorImageTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "mirror image") {}
|
||||
};
|
||||
|
||||
class IcyVeinsTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
IcyVeinsTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "icy veins") {}
|
||||
};
|
||||
|
||||
class ArcanePowerTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
ArcanePowerTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "arcane power") {}
|
||||
};
|
||||
class PresenceOfMindTrigger : public BoostTrigger
|
||||
{
|
||||
public:
|
||||
PresenceOfMindTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "presence of mind") {}
|
||||
};
|
||||
|
||||
// CC, Interrupt, and Dispel Triggers
|
||||
|
||||
class PolymorphTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
PolymorphTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "polymorph") {}
|
||||
};
|
||||
|
||||
class RemoveCurseTrigger : public NeedCureTrigger
|
||||
{
|
||||
public:
|
||||
RemoveCurseTrigger(PlayerbotAI* botAI) : NeedCureTrigger(botAI, "remove curse", DISPEL_CURSE) {}
|
||||
};
|
||||
|
||||
class PartyMemberRemoveCurseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
PartyMemberRemoveCurseTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "remove curse", DISPEL_CURSE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class SpellstealTrigger : public TargetAuraDispelTrigger
|
||||
{
|
||||
public:
|
||||
SpellstealTrigger(PlayerbotAI* botAI) : TargetAuraDispelTrigger(botAI, "spellsteal", DISPEL_MAGIC) {}
|
||||
};
|
||||
|
||||
class CounterspellEnemyHealerTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
CounterspellEnemyHealerTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "counterspell") {}
|
||||
};
|
||||
|
||||
class CounterspellInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
CounterspellInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "counterspell") {}
|
||||
};
|
||||
|
||||
// Damage and Debuff Triggers
|
||||
|
||||
class LivingBombTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
LivingBombTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "living bomb", 1, true) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class LivingBombOnAttackersTrigger : public DebuffOnAttackerTrigger
|
||||
{
|
||||
public:
|
||||
LivingBombOnAttackersTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "living bomb", true) {}
|
||||
bool IsActive() override { return BuffTrigger::IsActive(); }
|
||||
};
|
||||
|
||||
class FireballTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FireballTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "fireball", 1, true) {}
|
||||
};
|
||||
|
||||
class ImprovedScorchTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
ImprovedScorchTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "improved scorch", 1, true, 0.5f) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class PyroblastTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
PyroblastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "pyroblast", 1, true) {}
|
||||
};
|
||||
|
||||
class FrostfireBoltTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FrostfireBoltTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frostfire bolt", 1, true) {}
|
||||
};
|
||||
|
||||
class FingersOfFrostTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
FingersOfFrostTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "fingers of frost") {}
|
||||
};
|
||||
|
||||
class BrainFreezeTrigger : public HasAuraTrigger
|
||||
{
|
||||
public:
|
||||
BrainFreezeTrigger(PlayerbotAI* botAI) : HasAuraTrigger(botAI, "fireball!") {}
|
||||
};
|
||||
|
||||
class FrostNovaOnTargetTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FrostNovaOnTargetTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frost nova", 1, false) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FrostbiteOnTargetTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
FrostbiteOnTargetTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "frostbite", 1, false) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class FlamestrikeNearbyTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
FlamestrikeNearbyTrigger(PlayerbotAI* botAI, float radius = 30.0f)
|
||||
: Trigger(botAI, "flamestrike nearby"), radius(radius)
|
||||
{
|
||||
}
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
float radius;
|
||||
static const std::set<uint32> FLAMESTRIKE_SPELL_IDS;
|
||||
};
|
||||
|
||||
class FlamestrikeBlizzardTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
FlamestrikeBlizzardTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "flamestrike nearby", "medium aoe") {}
|
||||
};
|
||||
|
||||
class BlizzardChannelCheckTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
BlizzardChannelCheckTrigger(PlayerbotAI* botAI, uint32 minEnemies = 2)
|
||||
: Trigger(botAI, "blizzard channel check"), minEnemies(minEnemies) {}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
protected:
|
||||
uint32 minEnemies;
|
||||
static const std::set<uint32> BLIZZARD_SPELL_IDS;
|
||||
};
|
||||
|
||||
class BlastWaveOffCdTrigger : public SpellNoCooldownTrigger
|
||||
{
|
||||
public:
|
||||
BlastWaveOffCdTrigger(PlayerbotAI* botAI) : SpellNoCooldownTrigger(botAI, "blast wave") {}
|
||||
};
|
||||
|
||||
class BlastWaveOffCdTriggerAndMediumAoeTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
BlastWaveOffCdTriggerAndMediumAoeTrigger(PlayerbotAI* ai) : TwoTriggers(ai, "blast wave off cd", "medium aoe") {}
|
||||
};
|
||||
|
||||
class NoFirestarterStrategyTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
NoFirestarterStrategyTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no firestarter strategy") {}
|
||||
|
||||
bool IsActive() override
|
||||
{
|
||||
return !botAI->HasStrategy("firestarter", BOT_STATE_COMBAT);
|
||||
}
|
||||
};
|
||||
|
||||
class EnemyIsCloseAndNoFirestarterStrategyTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
EnemyIsCloseAndNoFirestarterStrategyTrigger(PlayerbotAI* botAI)
|
||||
: TwoTriggers(botAI, "enemy is close", "no firestarter strategy") {}
|
||||
};
|
||||
|
||||
class EnemyTooCloseForSpellAndNoFirestarterStrategyTrigger : public TwoTriggers
|
||||
{
|
||||
public:
|
||||
EnemyTooCloseForSpellAndNoFirestarterStrategyTrigger(PlayerbotAI* botAI)
|
||||
: TwoTriggers(botAI, "enemy too close for spell", "no firestarter strategy") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
505
src/Ai/Class/Paladin/Action/PaladinActions.cpp
Normal file
505
src/Ai/Class/Paladin/Action/PaladinActions.cpp
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 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 "PaladinActions.h"
|
||||
|
||||
#include "AiFactory.h"
|
||||
#include "Event.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "../../../../../src/server/scripts/Spells/spell_generic.cpp"
|
||||
#include "GenericBuffUtils.h"
|
||||
#include "Config.h"
|
||||
#include "Group.h"
|
||||
#include "ObjectAccessor.h"
|
||||
|
||||
using ai::buff::MakeAuraQualifierForBuff;
|
||||
using ai::buff::UpgradeToGroupIfAppropriate;
|
||||
|
||||
// Helper : detect tank role on the target (player bot or not) return true if spec is tank or if the bot have tank strategies (bear/tank/tank face).
|
||||
static inline bool IsTankRole(Player* p)
|
||||
{
|
||||
if (!p) return false;
|
||||
if (p->HasTankSpec())
|
||||
return true;
|
||||
if (PlayerbotAI* otherAI = GET_PLAYERBOT_AI(p))
|
||||
{
|
||||
if (otherAI->HasStrategy("tank", BOT_STATE_NON_COMBAT) ||
|
||||
otherAI->HasStrategy("tank", BOT_STATE_COMBAT) ||
|
||||
otherAI->HasStrategy("tank face", BOT_STATE_NON_COMBAT) ||
|
||||
otherAI->HasStrategy("tank face", BOT_STATE_COMBAT) ||
|
||||
otherAI->HasStrategy("bear", BOT_STATE_NON_COMBAT) ||
|
||||
otherAI->HasStrategy("bear", BOT_STATE_COMBAT))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Added for solo paladin patch : determine if he's the only paladin on party
|
||||
static inline bool IsOnlyPaladinInGroup(Player* bot)
|
||||
{
|
||||
if (!bot) return false;
|
||||
Group* g = bot->GetGroup();
|
||||
if (!g) return true; // solo
|
||||
uint32 pals = 0u;
|
||||
for (GroupReference* r = g->GetFirstMember(); r; r = r->next())
|
||||
{
|
||||
Player* p = r->GetSource();
|
||||
if (!p || !p->IsInWorld()) continue;
|
||||
if (p->getClass() == CLASS_PALADIN) ++pals;
|
||||
}
|
||||
return pals == 1u;
|
||||
}
|
||||
|
||||
static inline bool GroupHasTankOfClass(Group* g, uint8 classId)
|
||||
{
|
||||
return GroupHasTankOfClass(g, static_cast<Classes>(classId));
|
||||
}
|
||||
|
||||
inline std::string const GetActualBlessingOfMight(Unit* target)
|
||||
{
|
||||
if (!target->ToPlayer())
|
||||
{
|
||||
return "blessing of might";
|
||||
}
|
||||
|
||||
int tab = AiFactory::GetPlayerSpecTab(target->ToPlayer());
|
||||
switch (target->getClass())
|
||||
{
|
||||
case CLASS_MAGE:
|
||||
case CLASS_PRIEST:
|
||||
case CLASS_WARLOCK:
|
||||
return "blessing of wisdom";
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab == SHAMAN_TAB_ELEMENTAL || tab == SHAMAN_TAB_RESTORATION)
|
||||
{
|
||||
return "blessing of wisdom";
|
||||
}
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
if (tab == DRUID_TAB_RESTORATION || tab == DRUID_TAB_BALANCE)
|
||||
{
|
||||
return "blessing of wisdom";
|
||||
}
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (tab == PALADIN_TAB_HOLY)
|
||||
{
|
||||
return "blessing of wisdom";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return "blessing of might";
|
||||
}
|
||||
|
||||
inline std::string const GetActualBlessingOfWisdom(Unit* target)
|
||||
{
|
||||
if (!target->ToPlayer())
|
||||
{
|
||||
return "blessing of might";
|
||||
}
|
||||
int tab = AiFactory::GetPlayerSpecTab(target->ToPlayer());
|
||||
switch (target->getClass())
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
case CLASS_ROGUE:
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
case CLASS_HUNTER:
|
||||
return "blessing of might";
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab == SHAMAN_TAB_ENHANCEMENT)
|
||||
{
|
||||
return "blessing of might";
|
||||
}
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
if (tab == DRUID_TAB_FERAL)
|
||||
{
|
||||
return "blessing of might";
|
||||
}
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (tab == PALADIN_TAB_PROTECTION || tab == PALADIN_TAB_RETRIBUTION)
|
||||
{
|
||||
return "blessing of might";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return "blessing of wisdom";
|
||||
}
|
||||
|
||||
inline std::string const GetActualBlessingOfSanctuary(Unit* target, Player* bot)
|
||||
{
|
||||
if (!bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY))
|
||||
return "";
|
||||
|
||||
Player* tp = target->ToPlayer();
|
||||
if (!tp)
|
||||
return "";
|
||||
|
||||
if (auto* ai = GET_PLAYERBOT_AI(bot))
|
||||
{
|
||||
if (Unit* mt = ai->GetAiObjectContext()->GetValue<Unit*>("main tank")->Get())
|
||||
{
|
||||
if (mt == target)
|
||||
return "blessing of sanctuary";
|
||||
}
|
||||
}
|
||||
|
||||
if (tp->HasTankSpec())
|
||||
return "blessing of sanctuary";
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
Value<Unit*>* CastBlessingOnPartyAction::GetTargetValue()
|
||||
{
|
||||
|
||||
return context->GetValue<Unit*>("party member without aura", MakeAuraQualifierForBuff(spell));
|
||||
}
|
||||
|
||||
bool CastBlessingOfMightAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
std::string castName = GetActualBlessingOfMight(target);
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
return botAI->CastSpell(castName, target);
|
||||
}
|
||||
|
||||
Value<Unit*>* CastBlessingOfMightOnPartyAction::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(
|
||||
"party member without aura",
|
||||
"blessing of might,greater blessing of might,blessing of wisdom,greater blessing of wisdom,blessing of sanctuary,greater blessing of sanctuary"
|
||||
);
|
||||
}
|
||||
|
||||
bool CastBlessingOfMightOnPartyAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
std::string castName = GetActualBlessingOfMight(target);
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
return botAI->CastSpell(castName, target);
|
||||
}
|
||||
|
||||
bool CastBlessingOfWisdomAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
std::string castName = GetActualBlessingOfWisdom(target);
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
return botAI->CastSpell(castName, target);
|
||||
}
|
||||
|
||||
Value<Unit*>* CastBlessingOfWisdomOnPartyAction::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(
|
||||
"party member without aura",
|
||||
"blessing of wisdom,greater blessing of wisdom,blessing of might,greater blessing of might,blessing of sanctuary,greater blessing of sanctuary"
|
||||
);
|
||||
}
|
||||
|
||||
bool CastBlessingOfWisdomOnPartyAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Player* targetPlayer = target->ToPlayer();
|
||||
|
||||
if (Group* g = bot->GetGroup())
|
||||
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
|
||||
return false;
|
||||
|
||||
if (botAI->HasStrategy("bmana", BOT_STATE_NON_COMBAT) &&
|
||||
targetPlayer && IsTankRole(targetPlayer))
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Wisdom/bmana] Skip tank {} (Kings only)", target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string castName = GetActualBlessingOfWisdom(target);
|
||||
if (castName.empty())
|
||||
return false;
|
||||
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
return botAI->CastSpell(castName, target);
|
||||
}
|
||||
|
||||
Value<Unit*>* CastBlessingOfSanctuaryOnPartyAction::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(
|
||||
"party member without aura",
|
||||
"blessing of sanctuary,greater blessing of sanctuary"
|
||||
);
|
||||
}
|
||||
|
||||
bool CastBlessingOfSanctuaryOnPartyAction::Execute(Event event)
|
||||
{
|
||||
if (!bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY))
|
||||
return false;
|
||||
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
{
|
||||
// Fallback: GetTarget() can be null if no one needs a buff.
|
||||
// Keep a valid pointer for the checks/logs that follow.
|
||||
target = bot;
|
||||
}
|
||||
|
||||
Player* targetPlayer = target ? target->ToPlayer() : nullptr;
|
||||
|
||||
// Small helpers to check relevant auras
|
||||
const auto HasKingsAura = [&](Unit* u) -> bool {
|
||||
return botAI->HasAura("blessing of kings", u) || botAI->HasAura("greater blessing of kings", u);
|
||||
};
|
||||
const auto HasSanctAura = [&](Unit* u) -> bool {
|
||||
return botAI->HasAura("blessing of sanctuary", u) || botAI->HasAura("greater blessing of sanctuary", u);
|
||||
};
|
||||
|
||||
if (Group* g = bot->GetGroup())
|
||||
{
|
||||
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Sanct] Initial target not in group, ignoring");
|
||||
target = bot;
|
||||
targetPlayer = bot->ToPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
if (Player* self = bot->ToPlayer())
|
||||
{
|
||||
bool selfHasSanct = HasSanctAura(self);
|
||||
bool needSelf = IsTankRole(self) && !selfHasSanct;
|
||||
|
||||
LOG_DEBUG("playerbots", "[Sanct] {} isTank={} selfHasSanct={} needSelf={}",
|
||||
bot->GetName(), IsTankRole(self), selfHasSanct, needSelf);
|
||||
|
||||
if (needSelf)
|
||||
{
|
||||
target = self;
|
||||
targetPlayer = self;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to re-target a valid tank in group if needed
|
||||
bool targetOk = false;
|
||||
if (targetPlayer)
|
||||
{
|
||||
bool hasSanct = HasSanctAura(targetPlayer);
|
||||
targetOk = IsTankRole(targetPlayer) && !hasSanct;
|
||||
}
|
||||
|
||||
if (!targetOk)
|
||||
{
|
||||
if (Group* g = bot->GetGroup())
|
||||
{
|
||||
for (GroupReference* gref = g->GetFirstMember(); gref; gref = gref->next())
|
||||
{
|
||||
Player* p = gref->GetSource();
|
||||
if (!p) continue;
|
||||
if (!p->IsInWorld() || !p->IsAlive()) continue;
|
||||
if (!IsTankRole(p)) continue;
|
||||
|
||||
bool hasSanct = HasSanctAura(p);
|
||||
if (!hasSanct)
|
||||
{
|
||||
target = p; // prioritize this tank
|
||||
targetPlayer = p;
|
||||
targetOk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool hasKings = HasKingsAura(target);
|
||||
bool hasSanct = HasSanctAura(target);
|
||||
bool knowSanct = bot->HasSpell(SPELL_BLESSING_OF_SANCTUARY);
|
||||
LOG_DEBUG("playerbots", "[Sanct] Final target={} hasKings={} hasSanct={} knowSanct={}",
|
||||
target->GetName(), hasKings, hasSanct, knowSanct);
|
||||
}
|
||||
|
||||
std::string castName = GetActualBlessingOfSanctuary(target, bot);
|
||||
// If internal logic didn't recognize the tank (e.g., bear druid), force single-target Sanctuary
|
||||
if (castName.empty())
|
||||
{
|
||||
if (targetPlayer)
|
||||
{
|
||||
if (IsTankRole(targetPlayer))
|
||||
castName = "blessing of sanctuary"; // force single-target
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (targetPlayer && !IsTankRole(targetPlayer))
|
||||
{
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
}
|
||||
else
|
||||
{
|
||||
castName = "blessing of sanctuary";
|
||||
}
|
||||
|
||||
bool ok = botAI->CastSpell(castName, target);
|
||||
LOG_DEBUG("playerbots", "[Sanct] Cast {} on {} result={}", castName, target->GetName(), ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
Value<Unit*>* CastBlessingOfKingsOnPartyAction::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(
|
||||
"party member without aura",
|
||||
"blessing of kings,greater blessing of kings,blessing of sanctuary,greater blessing of sanctuary"
|
||||
);
|
||||
}
|
||||
|
||||
bool CastBlessingOfKingsOnPartyAction::Execute(Event event)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
Group* g = bot->GetGroup();
|
||||
if (!g)
|
||||
return false;
|
||||
|
||||
// Added for patch solo paladin, never buff itself to not remove his sanctuary buff
|
||||
if (botAI->HasStrategy("bstats", BOT_STATE_NON_COMBAT) && IsOnlyPaladinInGroup(bot))
|
||||
{
|
||||
if (target->GetGUID() == bot->GetGUID())
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Kings/bstats-solo] Skip self to keep Sanctuary on {}", bot->GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// End solo paladin patch
|
||||
|
||||
Player* targetPlayer = target->ToPlayer();
|
||||
if (targetPlayer && !g->IsMember(targetPlayer->GetGUID()))
|
||||
return false;
|
||||
|
||||
const bool hasBmana = botAI->HasStrategy("bmana", BOT_STATE_NON_COMBAT);
|
||||
const bool hasBstats = botAI->HasStrategy("bstats", BOT_STATE_NON_COMBAT);
|
||||
|
||||
if (hasBmana)
|
||||
{
|
||||
if (!targetPlayer || !IsTankRole(targetPlayer))
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Kings/bmana] Skip non-tank {}", target->GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetPlayer)
|
||||
{
|
||||
const bool isTank = IsTankRole(targetPlayer);
|
||||
const bool hasSanctFromMe =
|
||||
target->HasAura(SPELL_BLESSING_OF_SANCTUARY, bot->GetGUID()) ||
|
||||
target->HasAura(SPELL_GREATER_BLESSING_OF_SANCTUARY, bot->GetGUID());
|
||||
const bool hasSanctAny =
|
||||
botAI->HasAura("blessing of sanctuary", target) ||
|
||||
botAI->HasAura("greater blessing of sanctuary", target);
|
||||
|
||||
if (isTank && hasSanctFromMe)
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Kings] Skip: {} has my Sanctuary and is a tank", target->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasBstats && isTank && hasSanctAny)
|
||||
{
|
||||
LOG_DEBUG("playerbots", "[Kings] Skip (bstats): {} already has Sanctuary and is a tank", target->GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string castName = "blessing of kings";
|
||||
|
||||
bool allowGreater = true;
|
||||
|
||||
if (hasBmana)
|
||||
allowGreater = false;
|
||||
|
||||
if (allowGreater && hasBstats && targetPlayer)
|
||||
{
|
||||
switch (targetPlayer->getClass())
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
case CLASS_PALADIN:
|
||||
case CLASS_DRUID:
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
allowGreater = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowGreater)
|
||||
{
|
||||
auto RP = ai::chat::MakeGroupAnnouncer(bot);
|
||||
castName = ai::buff::UpgradeToGroupIfAppropriate(bot, botAI, castName, /*announceOnMissing=*/true, RP);
|
||||
}
|
||||
|
||||
return botAI->CastSpell(castName, target);
|
||||
}
|
||||
|
||||
bool CastSealSpellAction::isUseful() { return AI_VALUE2(bool, "combat", "self target"); }
|
||||
|
||||
Value<Unit*>* CastTurnUndeadAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
|
||||
|
||||
Unit* CastRighteousDefenseAction::GetTarget()
|
||||
{
|
||||
Unit* current_target = AI_VALUE(Unit*, "current target");
|
||||
if (!current_target)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return current_target->GetVictim();
|
||||
}
|
||||
|
||||
bool CastDivineSacrificeAction::isUseful()
|
||||
{
|
||||
return GetTarget() && (GetTarget() != nullptr) && CastSpellAction::isUseful() &&
|
||||
!botAI->HasAura("divine guardian", GetTarget(), false, false, -1, true);
|
||||
}
|
||||
|
||||
bool CastCancelDivineSacrificeAction::Execute(Event event)
|
||||
{
|
||||
botAI->RemoveAura("divine sacrifice");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastCancelDivineSacrificeAction::isUseful()
|
||||
{
|
||||
return botAI->HasAura("divine sacrifice", GetTarget(), false, true, -1, true);
|
||||
}
|
||||
431
src/Ai/Class/Paladin/Action/PaladinActions.h
Normal file
431
src/Ai/Class/Paladin/Action/PaladinActions.h
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* 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_PALADINACTIONS_H
|
||||
#define _PLAYERBOT_PALADINACTIONS_H
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
|
||||
// seals
|
||||
BUFF_ACTION(CastSealOfRighteousnessAction, "seal of righteousness");
|
||||
BUFF_ACTION(CastSealOfJusticeAction, "seal of justice");
|
||||
BUFF_ACTION(CastSealOfLightAction, "seal of light");
|
||||
BUFF_ACTION(CastSealOfWisdomAction, "seal of wisdom");
|
||||
BUFF_ACTION(CastSealOfCommandAction, "seal of command");
|
||||
BUFF_ACTION(CastSealOfVengeanceAction, "seal of vengeance");
|
||||
BUFF_ACTION(CastSealOfCorruptionAction, "seal of corruption");
|
||||
|
||||
// judgements
|
||||
SPELL_ACTION(CastJudgementAction, "judgement");
|
||||
|
||||
SPELL_ACTION(CastJudgementOfLightAction, "judgement of light");
|
||||
SPELL_ACTION(CastJudgementOfWisdomAction, "judgement of wisdom");
|
||||
SPELL_ACTION(CastJudgementOfJusticeAction, "judgement of justice");
|
||||
|
||||
// auras
|
||||
BUFF_ACTION(CastDevotionAuraAction, "devotion aura");
|
||||
BUFF_ACTION(CastRetributionAuraAction, "retribution aura");
|
||||
BUFF_ACTION(CastConcentrationAuraAction, "concentration aura");
|
||||
BUFF_ACTION(CastShadowResistanceAuraAction, "shadow resistance aura");
|
||||
BUFF_ACTION(CastFrostResistanceAuraAction, "frost resistance aura");
|
||||
BUFF_ACTION(CastFireResistanceAuraAction, "fire resistance aura");
|
||||
BUFF_ACTION(CastCrusaderAuraAction, "crusader aura");
|
||||
BUFF_ACTION(CastSanctityAuraAction, "sanctity aura");
|
||||
|
||||
SPELL_ACTION(CastHolyShockAction, "holy shock");
|
||||
|
||||
// consecration
|
||||
MELEE_ACTION(CastConsecrationAction, "consecration");
|
||||
|
||||
// repentance
|
||||
SNARE_ACTION(CastRepentanceSnareAction, "repentance");
|
||||
DEBUFF_ACTION(CastRepentanceAction, "repentance");
|
||||
ENEMY_HEALER_ACTION(CastRepentanceOnHealerAction, "repentance");
|
||||
|
||||
// hamme of wrath
|
||||
SPELL_ACTION(CastHammerOfWrathAction, "hammer of wrath");
|
||||
|
||||
// buffs
|
||||
BUFF_ACTION(CastDivineFavorAction, "divine favor");
|
||||
|
||||
// blessings
|
||||
|
||||
// fury
|
||||
BUFF_ACTION(CastRighteousFuryAction, "righteous fury");
|
||||
|
||||
class CastDivineStormAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivineStormAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "divine storm") {}
|
||||
};
|
||||
|
||||
class CastCrusaderStrikeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastCrusaderStrikeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "crusader strike") {}
|
||||
};
|
||||
|
||||
class CastSealSpellAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSealSpellAction(PlayerbotAI* botAI, std::string const name) : CastBuffSpellAction(botAI, name) {}
|
||||
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastBlessingOfMightAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfMightAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "blessing of might") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastBlessingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOnPartyAction(PlayerbotAI* botAI, std::string const name) : BuffOnPartyAction(botAI, name), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class CastBlessingOfMightOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfMightOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "blessing of might") {}
|
||||
|
||||
std::string const getName() override { return "blessing of might on party"; }
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastBlessingOfWisdomAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfWisdomAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "blessing of wisdom") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastBlessingOfWisdomOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfWisdomOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "blessing of wisdom") {}
|
||||
|
||||
std::string const getName() override { return "blessing of wisdom on party"; }
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastBlessingOfKingsAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfKingsAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "blessing of kings") {}
|
||||
};
|
||||
|
||||
class CastBlessingOfKingsOnPartyAction : public CastBlessingOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfKingsOnPartyAction(PlayerbotAI* botAI) : CastBlessingOnPartyAction(botAI, "blessing of kings") {}
|
||||
|
||||
std::string const getName() override { return "blessing of kings on party"; }
|
||||
Value<Unit*>* GetTargetValue() override; // added for Sanctuary priority
|
||||
bool Execute(Event event) override; // added for 2 paladins logic
|
||||
};
|
||||
|
||||
class CastBlessingOfSanctuaryAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfSanctuaryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "blessing of sanctuary") {}
|
||||
};
|
||||
|
||||
class CastBlessingOfSanctuaryOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfSanctuaryOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "blessing of sanctuary")
|
||||
{
|
||||
}
|
||||
|
||||
std::string const getName() override { return "blessing of sanctuary on party"; }
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class CastHolyLightAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastHolyLightAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "holy light") {}
|
||||
};
|
||||
|
||||
class CastHolyShockOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyShockOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "holy shock", 25.0f, HealingManaEfficiency::LOW)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastHolyLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyLightOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "holy light", 50.0f, HealingManaEfficiency::MEDIUM)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastFlashOfLightAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastFlashOfLightAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "flash of light") {}
|
||||
};
|
||||
|
||||
class CastFlashOfLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastFlashOfLightOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "flash of light", 15.0f, HealingManaEfficiency::HIGH)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastLayOnHandsAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastLayOnHandsAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "lay on hands") {}
|
||||
};
|
||||
|
||||
class CastLayOnHandsOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastLayOnHandsOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "lay on hands") {}
|
||||
};
|
||||
|
||||
class CastDivineProtectionAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivineProtectionAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "divine protection") {}
|
||||
};
|
||||
|
||||
class CastDivineProtectionOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastDivineProtectionOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "divine protection") {}
|
||||
|
||||
std::string const getName() override { return "divine protection on party"; }
|
||||
};
|
||||
|
||||
class CastDivineShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivineShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "divine shield") {}
|
||||
};
|
||||
|
||||
class CastHolyWrathAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastHolyWrathAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "holy wrath") {}
|
||||
};
|
||||
|
||||
class CastHammerOfJusticeAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastHammerOfJusticeAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class CastHammerOfTheRighteousAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
CastHammerOfTheRighteousAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "hammer of the righteous") {}
|
||||
};
|
||||
|
||||
class CastPurifyPoisonAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastPurifyPoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "purify") {}
|
||||
};
|
||||
|
||||
class CastPurifyDiseaseAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastPurifyDiseaseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "purify") {}
|
||||
};
|
||||
|
||||
class CastPurifyPoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPurifyPoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "purify", DISPEL_POISON) {}
|
||||
|
||||
std::string const getName() override { return "purify poison on party"; }
|
||||
};
|
||||
|
||||
class CastPurifyDiseaseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPurifyDiseaseOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "purify", DISPEL_DISEASE) {}
|
||||
|
||||
std::string const getName() override { return "purify disease on party"; }
|
||||
};
|
||||
|
||||
class CastHandOfReckoningAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastHandOfReckoningAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "hand of reckoning") {}
|
||||
};
|
||||
|
||||
class CastRighteousDefenseAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastRighteousDefenseAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "righteous defense") {}
|
||||
virtual Unit* GetTarget() override;
|
||||
};
|
||||
|
||||
class CastCleansePoisonAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCleansePoisonAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse") {}
|
||||
};
|
||||
|
||||
class CastCleanseDiseaseAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCleanseDiseaseAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse") {}
|
||||
};
|
||||
|
||||
class CastCleanseMagicAction : public CastCureSpellAction
|
||||
{
|
||||
public:
|
||||
CastCleanseMagicAction(PlayerbotAI* botAI) : CastCureSpellAction(botAI, "cleanse") {}
|
||||
};
|
||||
|
||||
class CastCleansePoisonOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleansePoisonOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cleanse", DISPEL_POISON) {}
|
||||
|
||||
std::string const getName() override { return "cleanse poison on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseDiseaseOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseDiseaseOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cleanse", DISPEL_DISEASE) {}
|
||||
|
||||
std::string const getName() override { return "cleanse disease on party"; }
|
||||
};
|
||||
|
||||
class CastCleanseMagicOnPartyAction : public CurePartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastCleanseMagicOnPartyAction(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, "cleanse", DISPEL_MAGIC) {}
|
||||
|
||||
std::string const getName() override { return "cleanse magic on party"; }
|
||||
};
|
||||
|
||||
BEGIN_SPELL_ACTION(CastAvengersShieldAction, "avenger's shield")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
BEGIN_SPELL_ACTION(CastExorcismAction, "exorcism")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
class CastHolyShieldAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastHolyShieldAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "holy shield") {}
|
||||
};
|
||||
|
||||
class CastRedemptionAction : public ResurrectPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRedemptionAction(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, "redemption") {}
|
||||
};
|
||||
|
||||
class CastHammerOfJusticeOnEnemyHealerAction : public CastSpellOnEnemyHealerAction
|
||||
{
|
||||
public:
|
||||
CastHammerOfJusticeOnEnemyHealerAction(PlayerbotAI* botAI)
|
||||
: CastSpellOnEnemyHealerAction(botAI, "hammer of justice")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CastHammerOfJusticeSnareAction : public CastSnareSpellAction
|
||||
{
|
||||
public:
|
||||
CastHammerOfJusticeSnareAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class CastTurnUndeadAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastTurnUndeadAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "turn undead") {}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
};
|
||||
|
||||
PROTECT_ACTION(CastBlessingOfProtectionProtectAction, "blessing of protection");
|
||||
|
||||
class CastDivinePleaAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivinePleaAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "divine plea") {}
|
||||
};
|
||||
|
||||
class ShieldOfRighteousnessAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
ShieldOfRighteousnessAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "shield of righteousness") {}
|
||||
};
|
||||
|
||||
class CastBeaconOfLightOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastBeaconOfLightOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "beacon of light", true) {}
|
||||
};
|
||||
|
||||
class CastSacredShieldOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastSacredShieldOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "sacred shield", false) {}
|
||||
};
|
||||
|
||||
class CastAvengingWrathAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastAvengingWrathAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "avenging wrath") {}
|
||||
};
|
||||
|
||||
class CastDivineIlluminationAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivineIlluminationAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "divine illumination") {}
|
||||
};
|
||||
|
||||
class CastDivineSacrificeAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivineSacrificeAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "divine sacrifice") {}
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastCancelDivineSacrificeAction : public Action
|
||||
{
|
||||
public:
|
||||
CastCancelDivineSacrificeAction(PlayerbotAI* botAI) : Action(botAI, "cancel divine sacrifice") {}
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
#endif
|
||||
457
src/Ai/Class/Paladin/PaladinAiObjectContext.cpp
Normal file
457
src/Ai/Class/Paladin/PaladinAiObjectContext.cpp
Normal file
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
* 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 "PaladinAiObjectContext.h"
|
||||
|
||||
#include "DpsPaladinStrategy.h"
|
||||
#include "GenericPaladinNonCombatStrategy.h"
|
||||
#include "HealPaladinStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "OffhealRetPaladinStrategy.h"
|
||||
#include "PaladinActions.h"
|
||||
#include "PaladinBuffStrategies.h"
|
||||
#include "PaladinTriggers.h"
|
||||
#include "Playerbots.h"
|
||||
#include "TankPaladinStrategy.h"
|
||||
|
||||
class PaladinStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
PaladinStrategyFactoryInternal()
|
||||
{
|
||||
creators["nc"] = &PaladinStrategyFactoryInternal::nc;
|
||||
creators["cure"] = &PaladinStrategyFactoryInternal::cure;
|
||||
creators["boost"] = &PaladinStrategyFactoryInternal::boost;
|
||||
creators["cc"] = &PaladinStrategyFactoryInternal::cc;
|
||||
creators["bthreat"] = &PaladinStrategyFactoryInternal::bthreat;
|
||||
creators["healer dps"] = &PaladinStrategyFactoryInternal::healer_dps;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* nc(PlayerbotAI* botAI) { return new GenericPaladinNonCombatStrategy(botAI); }
|
||||
static Strategy* cure(PlayerbotAI* botAI) { return new PaladinCureStrategy(botAI); }
|
||||
static Strategy* boost(PlayerbotAI* botAI) { return new PaladinBoostStrategy(botAI); }
|
||||
static Strategy* cc(PlayerbotAI* botAI) { return new PaladinCcStrategy(botAI); }
|
||||
static Strategy* bthreat(PlayerbotAI* botAI) { return new PaladinBuffThreatStrategy(botAI); }
|
||||
static Strategy* healer_dps(PlayerbotAI* botAI) { return new PaladinHealerDpsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class PaladinResistanceStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
PaladinResistanceStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["rshadow"] = &PaladinResistanceStrategyFactoryInternal::rshadow;
|
||||
creators["rfrost"] = &PaladinResistanceStrategyFactoryInternal::rfrost;
|
||||
creators["rfire"] = &PaladinResistanceStrategyFactoryInternal::rfire;
|
||||
creators["baoe"] = &PaladinResistanceStrategyFactoryInternal::baoe;
|
||||
creators["barmor"] = &PaladinResistanceStrategyFactoryInternal::barmor;
|
||||
creators["bcast"] = &PaladinResistanceStrategyFactoryInternal::bcast;
|
||||
creators["bspeed"] = &PaladinResistanceStrategyFactoryInternal::bspeed;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* rshadow(PlayerbotAI* botAI) { return new PaladinShadowResistanceStrategy(botAI); }
|
||||
static Strategy* rfrost(PlayerbotAI* botAI) { return new PaladinFrostResistanceStrategy(botAI); }
|
||||
static Strategy* rfire(PlayerbotAI* botAI) { return new PaladinFireResistanceStrategy(botAI); }
|
||||
static Strategy* baoe(PlayerbotAI* botAI) { return new PaladinBuffAoeStrategy(botAI); }
|
||||
static Strategy* barmor(PlayerbotAI* botAI) { return new PaladinBuffArmorStrategy(botAI); }
|
||||
static Strategy* bcast(PlayerbotAI* botAI) { return new PaladinBuffCastStrategy(botAI); }
|
||||
static Strategy* bspeed(PlayerbotAI* botAI) { return new PaladinBuffSpeedStrategy(botAI); }
|
||||
};
|
||||
|
||||
class PaladinBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
PaladinBuffStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["bhealth"] = &PaladinBuffStrategyFactoryInternal::bhealth;
|
||||
creators["bmana"] = &PaladinBuffStrategyFactoryInternal::bmana;
|
||||
creators["bdps"] = &PaladinBuffStrategyFactoryInternal::bdps;
|
||||
creators["bstats"] = &PaladinBuffStrategyFactoryInternal::bstats;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* bhealth(PlayerbotAI* botAI) { return new PaladinBuffHealthStrategy(botAI); }
|
||||
static Strategy* bmana(PlayerbotAI* botAI) { return new PaladinBuffManaStrategy(botAI); }
|
||||
static Strategy* bdps(PlayerbotAI* botAI) { return new PaladinBuffDpsStrategy(botAI); }
|
||||
static Strategy* bstats(PlayerbotAI* botAI) { return new PaladinBuffStatsStrategy(botAI); }
|
||||
};
|
||||
|
||||
class PaladinCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
PaladinCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["tank"] = &PaladinCombatStrategyFactoryInternal::tank;
|
||||
creators["dps"] = &PaladinCombatStrategyFactoryInternal::dps;
|
||||
creators["heal"] = &PaladinCombatStrategyFactoryInternal::heal;
|
||||
creators["offheal"] = &PaladinCombatStrategyFactoryInternal::offheal;
|
||||
}
|
||||
|
||||
private:
|
||||
static Strategy* tank(PlayerbotAI* botAI) { return new TankPaladinStrategy(botAI); }
|
||||
static Strategy* dps(PlayerbotAI* botAI) { return new DpsPaladinStrategy(botAI); }
|
||||
static Strategy* heal(PlayerbotAI* botAI) { return new HealPaladinStrategy(botAI); }
|
||||
static Strategy* offheal(PlayerbotAI* botAI) { return new OffhealRetPaladinStrategy(botAI); }
|
||||
};
|
||||
|
||||
class PaladinTriggerFactoryInternal : public NamedObjectContext<Trigger>
|
||||
{
|
||||
public:
|
||||
PaladinTriggerFactoryInternal()
|
||||
{
|
||||
creators["judgement"] = &PaladinTriggerFactoryInternal::judgement;
|
||||
creators["judgement of wisdom"] = &PaladinTriggerFactoryInternal::judgement_of_wisdom;
|
||||
creators["judgement of light"] = &PaladinTriggerFactoryInternal::judgement_of_light;
|
||||
creators["blessing"] = &PaladinTriggerFactoryInternal::blessing;
|
||||
creators["seal"] = &PaladinTriggerFactoryInternal::seal;
|
||||
creators["art of war"] = &PaladinTriggerFactoryInternal::art_of_war;
|
||||
creators["blessing on party"] = &PaladinTriggerFactoryInternal::blessing_on_party;
|
||||
creators["crusader aura"] = &PaladinTriggerFactoryInternal::crusader_aura;
|
||||
creators["retribution aura"] = &PaladinTriggerFactoryInternal::retribution_aura;
|
||||
creators["devotion aura"] = &PaladinTriggerFactoryInternal::devotion_aura;
|
||||
creators["sanctity aura"] = &PaladinTriggerFactoryInternal::sanctity_aura;
|
||||
creators["concentration aura"] = &PaladinTriggerFactoryInternal::concentration_aura;
|
||||
creators["shadow resistance aura"] = &PaladinTriggerFactoryInternal::shadow_resistance_aura;
|
||||
creators["frost resistance aura"] = &PaladinTriggerFactoryInternal::frost_resistance_aura;
|
||||
creators["fire resistance aura"] = &PaladinTriggerFactoryInternal::fire_resistance_aura;
|
||||
creators["hammer of justice snare"] = &PaladinTriggerFactoryInternal::hammer_of_justice_snare;
|
||||
creators["hammer of justice interrupt"] = &PaladinTriggerFactoryInternal::hammer_of_justice_interrupt;
|
||||
creators["cleanse cure disease"] = &PaladinTriggerFactoryInternal::CleanseCureDisease;
|
||||
creators["cleanse party member cure disease"] = &PaladinTriggerFactoryInternal::CleanseCurePartyMemberDisease;
|
||||
creators["cleanse cure poison"] = &PaladinTriggerFactoryInternal::CleanseCurePoison;
|
||||
creators["cleanse party member cure poison"] = &PaladinTriggerFactoryInternal::CleanseCurePartyMemberPoison;
|
||||
creators["cleanse cure magic"] = &PaladinTriggerFactoryInternal::CleanseCureMagic;
|
||||
creators["cleanse party member cure magic"] = &PaladinTriggerFactoryInternal::CleanseCurePartyMemberMagic;
|
||||
creators["righteous fury"] = &PaladinTriggerFactoryInternal::righteous_fury;
|
||||
creators["holy shield"] = &PaladinTriggerFactoryInternal::holy_shield;
|
||||
creators["hammer of justice on enemy healer"] =
|
||||
&PaladinTriggerFactoryInternal::hammer_of_justice_on_enemy_target;
|
||||
creators["hammer of justice on snare target"] =
|
||||
&PaladinTriggerFactoryInternal::hammer_of_justice_on_snare_target;
|
||||
creators["divine favor"] = &PaladinTriggerFactoryInternal::divine_favor;
|
||||
creators["turn undead"] = &PaladinTriggerFactoryInternal::turn_undead;
|
||||
creators["avenger's shield"] = &PaladinTriggerFactoryInternal::avenger_shield;
|
||||
creators["consecration"] = &PaladinTriggerFactoryInternal::consecration;
|
||||
creators["repentance on enemy healer"] = &PaladinTriggerFactoryInternal::repentance_on_enemy_healer;
|
||||
creators["repentance on snare target"] = &PaladinTriggerFactoryInternal::repentance_on_snare_target;
|
||||
creators["repentance interrupt"] = &PaladinTriggerFactoryInternal::repentance_interrupt;
|
||||
creators["beacon of light on main tank"] = &PaladinTriggerFactoryInternal::beacon_of_light_on_main_tank;
|
||||
creators["sacred shield on main tank"] = &PaladinTriggerFactoryInternal::sacred_shield_on_main_tank;
|
||||
|
||||
creators["blessing of kings on party"] = &PaladinTriggerFactoryInternal::blessing_of_kings_on_party;
|
||||
creators["blessing of wisdom on party"] = &PaladinTriggerFactoryInternal::blessing_of_wisdom_on_party;
|
||||
creators["blessing of might on party"] = &PaladinTriggerFactoryInternal::blessing_of_might_on_party;
|
||||
creators["blessing of sanctuary on party"] = &PaladinTriggerFactoryInternal::blessing_of_sanctuary_on_party;
|
||||
|
||||
creators["avenging wrath"] = &PaladinTriggerFactoryInternal::avenging_wrath;
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* turn_undead(PlayerbotAI* botAI) { return new TurnUndeadTrigger(botAI); }
|
||||
static Trigger* divine_favor(PlayerbotAI* botAI) { return new DivineFavorTrigger(botAI); }
|
||||
static Trigger* holy_shield(PlayerbotAI* botAI) { return new HolyShieldTrigger(botAI); }
|
||||
static Trigger* righteous_fury(PlayerbotAI* botAI) { return new RighteousFuryTrigger(botAI); }
|
||||
static Trigger* judgement(PlayerbotAI* botAI) { return new JudgementTrigger(botAI); }
|
||||
static Trigger* judgement_of_wisdom(PlayerbotAI* botAI) { return new JudgementOfWisdomTrigger(botAI); }
|
||||
static Trigger* judgement_of_light(PlayerbotAI* botAI) { return new JudgementOfLightTrigger(botAI); }
|
||||
static Trigger* blessing(PlayerbotAI* botAI) { return new BlessingTrigger(botAI); }
|
||||
static Trigger* seal(PlayerbotAI* botAI) { return new SealTrigger(botAI); }
|
||||
static Trigger* art_of_war(PlayerbotAI* botAI) { return new ArtOfWarTrigger(botAI); }
|
||||
static Trigger* blessing_on_party(PlayerbotAI* botAI) { return new BlessingOnPartyTrigger(botAI); }
|
||||
static Trigger* crusader_aura(PlayerbotAI* botAI) { return new CrusaderAuraTrigger(botAI); }
|
||||
static Trigger* retribution_aura(PlayerbotAI* botAI) { return new RetributionAuraTrigger(botAI); }
|
||||
static Trigger* devotion_aura(PlayerbotAI* botAI) { return new DevotionAuraTrigger(botAI); }
|
||||
static Trigger* sanctity_aura(PlayerbotAI* botAI) { return new SanctityAuraTrigger(botAI); }
|
||||
static Trigger* concentration_aura(PlayerbotAI* botAI) { return new ConcentrationAuraTrigger(botAI); }
|
||||
static Trigger* shadow_resistance_aura(PlayerbotAI* botAI) { return new ShadowResistanceAuraTrigger(botAI); }
|
||||
static Trigger* frost_resistance_aura(PlayerbotAI* botAI) { return new FrostResistanceAuraTrigger(botAI); }
|
||||
static Trigger* fire_resistance_aura(PlayerbotAI* botAI) { return new FireResistanceAuraTrigger(botAI); }
|
||||
static Trigger* hammer_of_justice_snare(PlayerbotAI* botAI) { return new HammerOfJusticeSnareTrigger(botAI); }
|
||||
static Trigger* hammer_of_justice_interrupt(PlayerbotAI* botAI)
|
||||
{
|
||||
return new HammerOfJusticeInterruptSpellTrigger(botAI);
|
||||
}
|
||||
static Trigger* CleanseCureDisease(PlayerbotAI* botAI) { return new CleanseCureDiseaseTrigger(botAI); }
|
||||
static Trigger* CleanseCurePartyMemberDisease(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CleanseCurePartyMemberDiseaseTrigger(botAI);
|
||||
}
|
||||
static Trigger* CleanseCurePoison(PlayerbotAI* botAI) { return new CleanseCurePoisonTrigger(botAI); }
|
||||
static Trigger* CleanseCurePartyMemberPoison(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CleanseCurePartyMemberPoisonTrigger(botAI);
|
||||
}
|
||||
static Trigger* CleanseCureMagic(PlayerbotAI* botAI) { return new CleanseCureMagicTrigger(botAI); }
|
||||
static Trigger* CleanseCurePartyMemberMagic(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CleanseCurePartyMemberMagicTrigger(botAI);
|
||||
}
|
||||
static Trigger* hammer_of_justice_on_enemy_target(PlayerbotAI* botAI)
|
||||
{
|
||||
return new HammerOfJusticeEnemyHealerTrigger(botAI);
|
||||
}
|
||||
static Trigger* hammer_of_justice_on_snare_target(PlayerbotAI* botAI)
|
||||
{
|
||||
return new HammerOfJusticeSnareTrigger(botAI);
|
||||
}
|
||||
static Trigger* avenger_shield(PlayerbotAI* botAI) { return new AvengerShieldTrigger(botAI); }
|
||||
static Trigger* consecration(PlayerbotAI* botAI) { return new ConsecrationTrigger(botAI); }
|
||||
static Trigger* repentance_on_enemy_healer(PlayerbotAI* botAI) { return new RepentanceOnHealerTrigger(botAI); }
|
||||
static Trigger* repentance_on_snare_target(PlayerbotAI* botAI) { return new RepentanceSnareTrigger(botAI); }
|
||||
static Trigger* repentance_interrupt(PlayerbotAI* botAI) { return new RepentanceInterruptTrigger(botAI); }
|
||||
static Trigger* beacon_of_light_on_main_tank(PlayerbotAI* ai) { return new BeaconOfLightOnMainTankTrigger(ai); }
|
||||
static Trigger* sacred_shield_on_main_tank(PlayerbotAI* ai) { return new SacredShieldOnMainTankTrigger(ai); }
|
||||
|
||||
static Trigger* blessing_of_kings_on_party(PlayerbotAI* botAI) { return new BlessingOfKingsOnPartyTrigger(botAI); }
|
||||
static Trigger* blessing_of_wisdom_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new BlessingOfWisdomOnPartyTrigger(botAI);
|
||||
}
|
||||
static Trigger* blessing_of_might_on_party(PlayerbotAI* botAI) { return new BlessingOfMightOnPartyTrigger(botAI); }
|
||||
static Trigger* blessing_of_sanctuary_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new BlessingOfSanctuaryOnPartyTrigger(botAI);
|
||||
}
|
||||
|
||||
static Trigger* avenging_wrath(PlayerbotAI* botAI) { return new AvengingWrathTrigger(botAI); }
|
||||
};
|
||||
|
||||
class PaladinAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
PaladinAiObjectContextInternal()
|
||||
{
|
||||
creators["seal of command"] = &PaladinAiObjectContextInternal::seal_of_command;
|
||||
creators["seal of vengeance"] = &PaladinAiObjectContextInternal::seal_of_vengeance;
|
||||
creators["seal of corruption"] = &PaladinAiObjectContextInternal::seal_of_corruption;
|
||||
creators["blessing of might"] = &PaladinAiObjectContextInternal::blessing_of_might;
|
||||
creators["blessing of wisdom"] = &PaladinAiObjectContextInternal::blessing_of_wisdom;
|
||||
creators["blessing of kings"] = &PaladinAiObjectContextInternal::blessing_of_kings;
|
||||
creators["blessing of sanctuary"] = &PaladinAiObjectContextInternal::blessing_of_sanctuary;
|
||||
creators["divine storm"] = &PaladinAiObjectContextInternal::divine_storm;
|
||||
creators["blessing of kings on party"] = &PaladinAiObjectContextInternal::blessing_of_kings_on_party;
|
||||
creators["blessing of might on party"] = &PaladinAiObjectContextInternal::blessing_of_might_on_party;
|
||||
creators["blessing of wisdom on party"] = &PaladinAiObjectContextInternal::blessing_of_wisdom_on_party;
|
||||
creators["blessing of sanctuary on party"] = &PaladinAiObjectContextInternal::blessing_of_sanctuary_on_party;
|
||||
creators["redemption"] = &PaladinAiObjectContextInternal::redemption;
|
||||
creators["crusader strike"] = &PaladinAiObjectContextInternal::crusader_strike;
|
||||
creators["crusader aura"] = &PaladinAiObjectContextInternal::crusader_aura;
|
||||
creators["seal of light"] = &PaladinAiObjectContextInternal::seal_of_light;
|
||||
creators["devotion aura"] = &PaladinAiObjectContextInternal::devotion_aura;
|
||||
creators["concentration aura"] = &PaladinAiObjectContextInternal::concentration_aura;
|
||||
creators["holy wrath"] = &PaladinAiObjectContextInternal::holy_wrath;
|
||||
creators["consecration"] = &PaladinAiObjectContextInternal::consecration;
|
||||
creators["cleanse disease"] = &PaladinAiObjectContextInternal::cleanse_disease;
|
||||
creators["cleanse poison"] = &PaladinAiObjectContextInternal::cleanse_poison;
|
||||
creators["cleanse magic"] = &PaladinAiObjectContextInternal::cleanse_magic;
|
||||
creators["purify disease"] = &PaladinAiObjectContextInternal::purify_disease;
|
||||
creators["purify poison"] = &PaladinAiObjectContextInternal::purify_poison;
|
||||
creators["cleanse poison on party"] = &PaladinAiObjectContextInternal::cleanse_poison_on_party;
|
||||
creators["cleanse disease on party"] = &PaladinAiObjectContextInternal::cleanse_disease_on_party;
|
||||
creators["cleanse magic on party"] = &PaladinAiObjectContextInternal::cleanse_magic_on_party;
|
||||
creators["purify poison on party"] = &PaladinAiObjectContextInternal::purify_poison_on_party;
|
||||
creators["purify disease on party"] = &PaladinAiObjectContextInternal::purify_disease_on_party;
|
||||
creators["seal of wisdom"] = &PaladinAiObjectContextInternal::seal_of_wisdom;
|
||||
creators["seal of justice"] = &PaladinAiObjectContextInternal::seal_of_justice;
|
||||
creators["seal of righteousness"] = &PaladinAiObjectContextInternal::seal_of_righteousness;
|
||||
creators["flash of light"] = &PaladinAiObjectContextInternal::flash_of_light;
|
||||
creators["hand of reckoning"] = &PaladinAiObjectContextInternal::hand_of_reckoning;
|
||||
creators["avenger's shield"] = &PaladinAiObjectContextInternal::avengers_shield;
|
||||
creators["exorcism"] = &PaladinAiObjectContextInternal::exorcism;
|
||||
creators["judgement"] = &PaladinAiObjectContextInternal::judgement;
|
||||
creators["judgement of light"] = &PaladinAiObjectContextInternal::judgement_of_light;
|
||||
creators["judgement of wisdom"] = &PaladinAiObjectContextInternal::judgement_of_wisdom;
|
||||
creators["divine shield"] = &PaladinAiObjectContextInternal::divine_shield;
|
||||
creators["divine protection"] = &PaladinAiObjectContextInternal::divine_protection;
|
||||
creators["divine protection on party"] = &PaladinAiObjectContextInternal::divine_protection_on_party;
|
||||
creators["hammer of justice"] = &PaladinAiObjectContextInternal::hammer_of_justice;
|
||||
creators["flash of light on party"] = &PaladinAiObjectContextInternal::flash_of_light_on_party;
|
||||
creators["holy light"] = &PaladinAiObjectContextInternal::holy_light;
|
||||
creators["holy light on party"] = &PaladinAiObjectContextInternal::holy_light_on_party;
|
||||
creators["lay on hands"] = &PaladinAiObjectContextInternal::lay_on_hands;
|
||||
creators["lay on hands on party"] = &PaladinAiObjectContextInternal::lay_on_hands_on_party;
|
||||
creators["judgement of justice"] = &PaladinAiObjectContextInternal::judgement_of_justice;
|
||||
creators["hammer of wrath"] = &PaladinAiObjectContextInternal::hammer_of_wrath;
|
||||
creators["holy shield"] = &PaladinAiObjectContextInternal::holy_shield;
|
||||
creators["hammer of the righteous"] = &PaladinAiObjectContextInternal::hammer_of_the_righteous;
|
||||
creators["retribution aura"] = &PaladinAiObjectContextInternal::retribution_aura;
|
||||
creators["shadow resistance aura"] = &PaladinAiObjectContextInternal::shadow_resistance_aura;
|
||||
creators["frost resistance aura"] = &PaladinAiObjectContextInternal::frost_resistance_aura;
|
||||
creators["fire resistance aura"] = &PaladinAiObjectContextInternal::fire_resistance_aura;
|
||||
creators["righteous fury"] = &PaladinAiObjectContextInternal::righteous_fury;
|
||||
creators["hammer of justice on enemy healer"] =
|
||||
&PaladinAiObjectContextInternal::hammer_of_justice_on_enemy_healer;
|
||||
creators["hammer of justice on snare target"] =
|
||||
&PaladinAiObjectContextInternal::hammer_of_justice_on_snare_target;
|
||||
creators["divine favor"] = &PaladinAiObjectContextInternal::divine_favor;
|
||||
creators["turn undead"] = &PaladinAiObjectContextInternal::turn_undead;
|
||||
creators["blessing of protection on party"] = &PaladinAiObjectContextInternal::blessing_of_protection_on_party;
|
||||
creators["righteous defense"] = &PaladinAiObjectContextInternal::righteous_defense;
|
||||
creators["repentance"] = &PaladinAiObjectContextInternal::repentance;
|
||||
creators["repentance on snare target"] = &PaladinAiObjectContextInternal::repentance_on_snare_target;
|
||||
creators["repentance on enemy healer"] = &PaladinAiObjectContextInternal::repentance_on_enemy_healer;
|
||||
creators["sanctity aura"] = &PaladinAiObjectContextInternal::sanctity_aura;
|
||||
creators["holy shock"] = &PaladinAiObjectContextInternal::holy_shock;
|
||||
creators["holy shock on party"] = &PaladinAiObjectContextInternal::holy_shock_on_party;
|
||||
creators["divine plea"] = &PaladinAiObjectContextInternal::divine_plea;
|
||||
creators["shield of righteousness"] = &PaladinAiObjectContextInternal::shield_of_righteousness;
|
||||
creators["beacon of light on main tank"] = &PaladinAiObjectContextInternal::beacon_of_light_on_main_tank;
|
||||
creators["sacred shield on main tank"] = &PaladinAiObjectContextInternal::sacred_shield_on_main_tank;
|
||||
creators["avenging wrath"] = &PaladinAiObjectContextInternal::avenging_wrath;
|
||||
creators["divine illumination"] = &PaladinAiObjectContextInternal::divine_illumination;
|
||||
creators["divine sacrifice"] = &PaladinAiObjectContextInternal::divine_sacrifice;
|
||||
creators["cancel divine sacrifice"] = &PaladinAiObjectContextInternal::cancel_divine_sacrifice;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* blessing_of_protection_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastBlessingOfProtectionProtectAction(botAI);
|
||||
}
|
||||
static Action* turn_undead(PlayerbotAI* botAI) { return new CastTurnUndeadAction(botAI); }
|
||||
static Action* divine_favor(PlayerbotAI* botAI) { return new CastDivineFavorAction(botAI); }
|
||||
static Action* righteous_fury(PlayerbotAI* botAI) { return new CastRighteousFuryAction(botAI); }
|
||||
static Action* seal_of_command(PlayerbotAI* botAI) { return new CastSealOfCommandAction(botAI); }
|
||||
static Action* seal_of_vengeance(PlayerbotAI* botAI) { return new CastSealOfVengeanceAction(botAI); }
|
||||
static Action* seal_of_corruption(PlayerbotAI* botAI) { return new CastSealOfCorruptionAction(botAI); }
|
||||
static Action* blessing_of_sanctuary(PlayerbotAI* botAI) { return new CastBlessingOfSanctuaryAction(botAI); }
|
||||
static Action* blessing_of_might(PlayerbotAI* botAI) { return new CastBlessingOfMightAction(botAI); }
|
||||
static Action* blessing_of_wisdom(PlayerbotAI* botAI) { return new CastBlessingOfWisdomAction(botAI); }
|
||||
static Action* blessing_of_kings(PlayerbotAI* botAI) { return new CastBlessingOfKingsAction(botAI); }
|
||||
static Action* divine_storm(PlayerbotAI* botAI) { return new CastDivineStormAction(botAI); }
|
||||
static Action* blessing_of_kings_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastBlessingOfKingsOnPartyAction(botAI);
|
||||
}
|
||||
static Action* blessing_of_might_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastBlessingOfMightOnPartyAction(botAI);
|
||||
}
|
||||
static Action* blessing_of_wisdom_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastBlessingOfWisdomOnPartyAction(botAI);
|
||||
}
|
||||
static Action* blessing_of_sanctuary_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastBlessingOfSanctuaryOnPartyAction(botAI);
|
||||
}
|
||||
static Action* redemption(PlayerbotAI* botAI) { return new CastRedemptionAction(botAI); }
|
||||
static Action* crusader_strike(PlayerbotAI* botAI) { return new CastCrusaderStrikeAction(botAI); }
|
||||
static Action* crusader_aura(PlayerbotAI* botAI) { return new CastCrusaderAuraAction(botAI); }
|
||||
static Action* seal_of_light(PlayerbotAI* botAI) { return new CastSealOfLightAction(botAI); }
|
||||
static Action* devotion_aura(PlayerbotAI* botAI) { return new CastDevotionAuraAction(botAI); }
|
||||
static Action* concentration_aura(PlayerbotAI* botAI) { return new CastConcentrationAuraAction(botAI); }
|
||||
static Action* holy_wrath(PlayerbotAI* botAI) { return new CastHolyWrathAction(botAI); }
|
||||
static Action* consecration(PlayerbotAI* botAI) { return new CastConsecrationAction(botAI); }
|
||||
static Action* cleanse_poison(PlayerbotAI* botAI) { return new CastCleansePoisonAction(botAI); }
|
||||
static Action* cleanse_disease(PlayerbotAI* botAI) { return new CastCleanseDiseaseAction(botAI); }
|
||||
static Action* cleanse_magic(PlayerbotAI* botAI) { return new CastCleanseMagicAction(botAI); }
|
||||
static Action* purify_poison(PlayerbotAI* botAI) { return new CastPurifyPoisonAction(botAI); }
|
||||
static Action* purify_disease(PlayerbotAI* botAI) { return new CastPurifyDiseaseAction(botAI); }
|
||||
static Action* cleanse_poison_on_party(PlayerbotAI* botAI) { return new CastCleansePoisonOnPartyAction(botAI); }
|
||||
static Action* cleanse_disease_on_party(PlayerbotAI* botAI) { return new CastCleanseDiseaseOnPartyAction(botAI); }
|
||||
static Action* cleanse_magic_on_party(PlayerbotAI* botAI) { return new CastCleanseMagicOnPartyAction(botAI); }
|
||||
static Action* purify_poison_on_party(PlayerbotAI* botAI) { return new CastPurifyPoisonOnPartyAction(botAI); }
|
||||
static Action* purify_disease_on_party(PlayerbotAI* botAI) { return new CastPurifyDiseaseOnPartyAction(botAI); }
|
||||
static Action* seal_of_wisdom(PlayerbotAI* botAI) { return new CastSealOfWisdomAction(botAI); }
|
||||
static Action* seal_of_justice(PlayerbotAI* botAI) { return new CastSealOfJusticeAction(botAI); }
|
||||
static Action* seal_of_righteousness(PlayerbotAI* botAI) { return new CastSealOfRighteousnessAction(botAI); }
|
||||
static Action* flash_of_light(PlayerbotAI* botAI) { return new CastFlashOfLightAction(botAI); }
|
||||
static Action* hand_of_reckoning(PlayerbotAI* botAI) { return new CastHandOfReckoningAction(botAI); }
|
||||
static Action* avengers_shield(PlayerbotAI* botAI) { return new CastAvengersShieldAction(botAI); }
|
||||
static Action* exorcism(PlayerbotAI* botAI) { return new CastExorcismAction(botAI); }
|
||||
static Action* judgement(PlayerbotAI* botAI) { return new CastJudgementAction(botAI); }
|
||||
static Action* judgement_of_light(PlayerbotAI* botAI) { return new CastJudgementOfLightAction(botAI); }
|
||||
static Action* judgement_of_wisdom(PlayerbotAI* botAI) { return new CastJudgementOfWisdomAction(botAI); }
|
||||
static Action* divine_shield(PlayerbotAI* botAI) { return new CastDivineShieldAction(botAI); }
|
||||
static Action* divine_protection(PlayerbotAI* botAI) { return new CastDivineProtectionAction(botAI); }
|
||||
static Action* divine_protection_on_party(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastDivineProtectionOnPartyAction(botAI);
|
||||
}
|
||||
static Action* hammer_of_justice(PlayerbotAI* botAI) { return new CastHammerOfJusticeAction(botAI); }
|
||||
static Action* flash_of_light_on_party(PlayerbotAI* botAI) { return new CastFlashOfLightOnPartyAction(botAI); }
|
||||
static Action* holy_light(PlayerbotAI* botAI) { return new CastHolyLightAction(botAI); }
|
||||
static Action* holy_light_on_party(PlayerbotAI* botAI) { return new CastHolyLightOnPartyAction(botAI); }
|
||||
static Action* lay_on_hands(PlayerbotAI* botAI) { return new CastLayOnHandsAction(botAI); }
|
||||
static Action* lay_on_hands_on_party(PlayerbotAI* botAI) { return new CastLayOnHandsOnPartyAction(botAI); }
|
||||
static Action* judgement_of_justice(PlayerbotAI* botAI) { return new CastJudgementOfJusticeAction(botAI); }
|
||||
static Action* hammer_of_wrath(PlayerbotAI* botAI) { return new CastHammerOfWrathAction(botAI); }
|
||||
static Action* holy_shield(PlayerbotAI* botAI) { return new CastHolyShieldAction(botAI); }
|
||||
static Action* hammer_of_the_righteous(PlayerbotAI* botAI) { return new CastHammerOfTheRighteousAction(botAI); }
|
||||
static Action* retribution_aura(PlayerbotAI* botAI) { return new CastRetributionAuraAction(botAI); }
|
||||
static Action* shadow_resistance_aura(PlayerbotAI* botAI) { return new CastShadowResistanceAuraAction(botAI); }
|
||||
static Action* frost_resistance_aura(PlayerbotAI* botAI) { return new CastFrostResistanceAuraAction(botAI); }
|
||||
static Action* fire_resistance_aura(PlayerbotAI* botAI) { return new CastFireResistanceAuraAction(botAI); }
|
||||
static Action* hammer_of_justice_on_enemy_healer(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastHammerOfJusticeOnEnemyHealerAction(botAI);
|
||||
}
|
||||
static Action* hammer_of_justice_on_snare_target(PlayerbotAI* botAI)
|
||||
{
|
||||
return new CastHammerOfJusticeSnareAction(botAI);
|
||||
}
|
||||
static Action* righteous_defense(PlayerbotAI* botAI) { return new CastRighteousDefenseAction(botAI); }
|
||||
static Action* repentance(PlayerbotAI* botAI) { return new CastRepentanceAction(botAI); }
|
||||
static Action* repentance_on_snare_target(PlayerbotAI* botAI) { return new CastRepentanceSnareAction(botAI); }
|
||||
static Action* repentance_on_enemy_healer(PlayerbotAI* botAI) { return new CastRepentanceOnHealerAction(botAI); }
|
||||
static Action* sanctity_aura(PlayerbotAI* botAI) { return new CastSanctityAuraAction(botAI); }
|
||||
static Action* holy_shock(PlayerbotAI* botAI) { return new CastHolyShockAction(botAI); }
|
||||
static Action* holy_shock_on_party(PlayerbotAI* botAI) { return new CastHolyShockOnPartyAction(botAI); }
|
||||
static Action* divine_plea(PlayerbotAI* ai) { return new CastDivinePleaAction(ai); }
|
||||
static Action* shield_of_righteousness(PlayerbotAI* ai) { return new ShieldOfRighteousnessAction(ai); }
|
||||
static Action* beacon_of_light_on_main_tank(PlayerbotAI* ai) { return new CastBeaconOfLightOnMainTankAction(ai); }
|
||||
static Action* sacred_shield_on_main_tank(PlayerbotAI* ai) { return new CastSacredShieldOnMainTankAction(ai); }
|
||||
static Action* avenging_wrath(PlayerbotAI* ai) { return new CastAvengingWrathAction(ai); }
|
||||
static Action* divine_illumination(PlayerbotAI* ai) { return new CastDivineIlluminationAction(ai); }
|
||||
static Action* divine_sacrifice(PlayerbotAI* ai) { return new CastDivineSacrificeAction(ai); }
|
||||
static Action* cancel_divine_sacrifice(PlayerbotAI* ai) { return new CastCancelDivineSacrificeAction(ai); }
|
||||
};
|
||||
|
||||
SharedNamedObjectContextList<Strategy> PaladinAiObjectContext::sharedStrategyContexts;
|
||||
SharedNamedObjectContextList<Action> PaladinAiObjectContext::sharedActionContexts;
|
||||
SharedNamedObjectContextList<Trigger> PaladinAiObjectContext::sharedTriggerContexts;
|
||||
SharedNamedObjectContextList<UntypedValue> PaladinAiObjectContext::sharedValueContexts;
|
||||
|
||||
PaladinAiObjectContext::PaladinAiObjectContext(PlayerbotAI* botAI)
|
||||
: AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts)
|
||||
{
|
||||
}
|
||||
|
||||
void PaladinAiObjectContext::BuildSharedContexts()
|
||||
{
|
||||
BuildSharedStrategyContexts(sharedStrategyContexts);
|
||||
BuildSharedActionContexts(sharedActionContexts);
|
||||
BuildSharedTriggerContexts(sharedTriggerContexts);
|
||||
BuildSharedValueContexts(sharedValueContexts);
|
||||
}
|
||||
|
||||
void PaladinAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList<Strategy>& strategyContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedStrategyContexts(strategyContexts);
|
||||
strategyContexts.Add(new PaladinStrategyFactoryInternal());
|
||||
strategyContexts.Add(new PaladinCombatStrategyFactoryInternal());
|
||||
strategyContexts.Add(new PaladinBuffStrategyFactoryInternal());
|
||||
strategyContexts.Add(new PaladinResistanceStrategyFactoryInternal());
|
||||
}
|
||||
|
||||
void PaladinAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList<Action>& actionContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedActionContexts(actionContexts);
|
||||
actionContexts.Add(new PaladinAiObjectContextInternal());
|
||||
}
|
||||
|
||||
void PaladinAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList<Trigger>& triggerContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedTriggerContexts(triggerContexts);
|
||||
triggerContexts.Add(new PaladinTriggerFactoryInternal());
|
||||
}
|
||||
|
||||
void PaladinAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList<UntypedValue>& valueContexts)
|
||||
{
|
||||
AiObjectContext::BuildSharedValueContexts(valueContexts);
|
||||
}
|
||||
30
src/Ai/Class/Paladin/PaladinAiObjectContext.h
Normal file
30
src/Ai/Class/Paladin/PaladinAiObjectContext.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_PALADINAIOBJECTCONTEXT_H
|
||||
#define _PLAYERBOT_PALADINAIOBJECTCONTEXT_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class PaladinAiObjectContext : public AiObjectContext
|
||||
{
|
||||
public:
|
||||
PaladinAiObjectContext(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
|
||||
212
src/Ai/Class/Paladin/Strategy/DpsPaladinStrategy.cpp
Normal file
212
src/Ai/Class/Paladin/Strategy/DpsPaladinStrategy.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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 "DpsPaladinStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class DpsPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
DpsPaladinStrategyActionNodeFactory()
|
||||
{
|
||||
creators["sanctity aura"] = &sanctity_aura;
|
||||
creators["retribution aura"] = &retribution_aura;
|
||||
creators["seal of corruption"] = &seal_of_corruption;
|
||||
creators["seal of vengeance"] = &seal_of_vengeance;
|
||||
creators["seal of command"] = &seal_of_command;
|
||||
creators["blessing of might"] = &blessing_of_might;
|
||||
creators["crusader strike"] = &crusader_strike;
|
||||
creators["repentance"] = &repentance;
|
||||
creators["repentance on enemy healer"] = &repentance_on_enemy_healer;
|
||||
creators["repentance on snare target"] = &repentance_on_snare_target;
|
||||
creators["repentance of shield"] = &repentance_or_shield;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* seal_of_corruption([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of corruption",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of vengeance") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_vengeance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of vengeance",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of command") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_command([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of command",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* blessing_of_might([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"blessing of might",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("blessing of kings") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* crusader_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"crusader strike",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* repentance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"repentance",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("hammer of justice") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* repentance_on_enemy_healer([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"repentance on enemy healer",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("hammer of justice on enemy healer") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* repentance_on_snare_target([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"repentance on snare target",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("hammer of justice on snare target") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* sanctity_aura([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"sanctity aura",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("retribution aura") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* retribution_aura([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"retribution aura",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("devotion aura") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* repentance_or_shield([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"repentance",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("divine shield") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
DpsPaladinStrategy::DpsPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new DpsPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> DpsPaladinStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("hammer of wrath", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("judgement of wisdom", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("crusader strike", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("divine storm", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("consecration", ACTION_DEFAULT + 0.1f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void DpsPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericPaladinStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"art of war",
|
||||
{
|
||||
NextAction("exorcism", ACTION_DEFAULT + 0.2f)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"seal",
|
||||
{
|
||||
NextAction("seal of corruption", ACTION_HIGH)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("seal of wisdom", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"avenging wrath",
|
||||
{
|
||||
NextAction("avenging wrath", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("divine storm", ACTION_HIGH + 4),
|
||||
NextAction("consecration", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("reach melee", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Paladin/Strategy/DpsPaladinStrategy.h
Normal file
24
src/Ai/Class/Paladin/Strategy/DpsPaladinStrategy.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_DPSPALADINSTRATEGY_H
|
||||
#define _PLAYERBOT_DPSPALADINSTRATEGY_H
|
||||
|
||||
#include "GenericPaladinStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class DpsPaladinStrategy : public GenericPaladinStrategy
|
||||
{
|
||||
public:
|
||||
DpsPaladinStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "dps"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_MELEE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 "GenericPaladinNonCombatStrategy.h"
|
||||
|
||||
#include "GenericPaladinStrategyActionNodeFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "AiFactory.h"
|
||||
|
||||
GenericPaladinNonCombatStrategy::GenericPaladinNonCombatStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericPaladinNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("party member dead", { NextAction("redemption", ACTION_CRITICAL_HEAL + 10) }));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", { NextAction("flash of light on party", 25.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member medium health", { NextAction("flash of light on party", 26.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member low health", { NextAction("holy light on party", 27.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member critical health", { NextAction("holy light on party", 28.0f) }));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
if (specTab == 0 || specTab == 1) // Holy or Protection
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", 1.0f) }));
|
||||
if (specTab == 2) // Retribution
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply stone", 1.0f) }));
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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_GENERICPALADINNONCOMBATSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICPALADINNONCOMBATSTRATEGY_H
|
||||
|
||||
#include "NonCombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericPaladinNonCombatStrategy : public NonCombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericPaladinNonCombatStrategy(PlayerbotAI* botAI);
|
||||
|
||||
std::string const getName() override { return "nc"; }
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
87
src/Ai/Class/Paladin/Strategy/GenericPaladinStrategy.cpp
Normal file
87
src/Ai/Class/Paladin/Strategy/GenericPaladinStrategy.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 "GenericPaladinStrategy.h"
|
||||
|
||||
#include "GenericPaladinStrategyActionNodeFactory.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
GenericPaladinStrategy::GenericPaladinStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new GenericPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
void GenericPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("critical health", { NextAction("divine shield",
|
||||
ACTION_HIGH + 5) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("hammer of justice interrupt",
|
||||
{ NextAction("hammer of justice", ACTION_INTERRUPT) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"hammer of justice on enemy healer",
|
||||
{ NextAction("hammer of justice on enemy healer", ACTION_INTERRUPT) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"hammer of justice on snare target",
|
||||
{ NextAction("hammer of justice on snare target", ACTION_INTERRUPT) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"critical health", { NextAction("lay on hands", ACTION_EMERGENCY) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("party member critical health",
|
||||
{ NextAction("lay on hands on party", ACTION_EMERGENCY + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"protect party member",
|
||||
{ NextAction("blessing of protection on party", ACTION_EMERGENCY + 2) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("high mana", { NextAction("divine plea", ACTION_HIGH) }));
|
||||
}
|
||||
|
||||
void PaladinCureStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"cleanse cure disease", { NextAction("cleanse disease", ACTION_DISPEL + 2) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("cleanse party member cure disease",
|
||||
{ NextAction("cleanse disease on party", ACTION_DISPEL + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"cleanse cure poison", { NextAction("cleanse poison", ACTION_DISPEL + 2) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("cleanse party member cure poison",
|
||||
{ NextAction("cleanse poison on party", ACTION_DISPEL + 1) }));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"cleanse cure magic", { NextAction("cleanse magic", ACTION_DISPEL + 2) }));
|
||||
triggers.push_back(
|
||||
new TriggerNode("cleanse party member cure magic",
|
||||
{ NextAction("cleanse magic on party", ACTION_DISPEL + 1) }));
|
||||
}
|
||||
|
||||
void PaladinBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
|
||||
// triggers.push_back(new TriggerNode("divine favor", { NextAction("divine favor",
|
||||
// ACTION_HIGH + 1) }));
|
||||
}
|
||||
|
||||
void PaladinCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("turn undead", { NextAction("turn undead", ACTION_HIGH + 1) }));
|
||||
}
|
||||
|
||||
void PaladinHealerDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("healer should attack",
|
||||
{
|
||||
NextAction("hammer of wrath", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("holy shock", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("shield of righteousness", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("judgement of light", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("consecration", ACTION_DEFAULT + 0.2f),
|
||||
NextAction("exorcism", ACTION_DEFAULT+ 0.1f),
|
||||
}));
|
||||
}
|
||||
58
src/Ai/Class/Paladin/Strategy/GenericPaladinStrategy.h
Normal file
58
src/Ai/Class/Paladin/Strategy/GenericPaladinStrategy.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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_GENERICPALADINSTRATEGY_H
|
||||
#define _PLAYERBOT_GENERICPALADINSTRATEGY_H
|
||||
|
||||
#include "CombatStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericPaladinStrategy : public CombatStrategy
|
||||
{
|
||||
public:
|
||||
GenericPaladinStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "paladin"; }
|
||||
};
|
||||
|
||||
class PaladinCureStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinCureStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cure"; }
|
||||
};
|
||||
|
||||
class PaladinBoostStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBoostStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "boost"; }
|
||||
};
|
||||
|
||||
class PaladinCcStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinCcStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "cc"; }
|
||||
};
|
||||
|
||||
class PaladinHealerDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "healer dps"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* 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_GENERICPALADINSTRATEGYACTIONNODEFACTORY_H
|
||||
#define _PLAYERBOT_GENERICPALADINSTRATEGYACTIONNODEFACTORY_H
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class GenericPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
GenericPaladinStrategyActionNodeFactory()
|
||||
{
|
||||
// creators["seal of light"] = &seal_of_light;
|
||||
creators["cleanse poison"] = &cleanse_poison;
|
||||
creators["cleanse disease"] = &cleanse_disease;
|
||||
creators["cleanse magic"] = &cleanse_magic;
|
||||
creators["cleanse poison on party"] = &cleanse_poison_on_party;
|
||||
creators["cleanse disease on party"] = &cleanse_disease_on_party;
|
||||
creators["seal of wisdom"] = &seal_of_wisdom;
|
||||
creators["seal of justice"] = &seal_of_justice;
|
||||
creators["hand of reckoning"] = &hand_of_reckoning;
|
||||
creators["judgement"] = &judgement;
|
||||
creators["judgement of wisdom"] = &judgement_of_wisdom;
|
||||
creators["divine shield"] = &divine_shield;
|
||||
creators["flash of light"] = &flash_of_light;
|
||||
creators["flash of light on party"] = &flash_of_light_on_party;
|
||||
creators["holy wrath"] = &holy_wrath;
|
||||
creators["lay on hands"] = &lay_on_hands;
|
||||
creators["lay on hands on party"] = &lay_on_hands_on_party;
|
||||
creators["hammer of wrath"] = &hammer_of_wrath;
|
||||
creators["retribution aura"] = &retribution_aura;
|
||||
creators["blessing of kings"] = &blessing_of_kings;
|
||||
creators["blessing of wisdom"] = &blessing_of_wisdom;
|
||||
creators["blessing of kings on party"] = &blessing_of_kings_on_party;
|
||||
creators["blessing of wisdom on party"] = &blessing_of_wisdom_on_party;
|
||||
creators["blessing of sanctuary on party"] = &blessing_of_sanctuary_on_party;
|
||||
creators["blessing of sanctuary"] = &blessing_of_sanctuary;
|
||||
creators["seal of command"] = &seal_of_command;
|
||||
creators["taunt spell"] = &hand_of_reckoning;
|
||||
creators["righteous defense"] = &righteous_defense;
|
||||
creators["avenger's shield"] = &avengers_shield;
|
||||
creators["divine sacrifice"] = &divine_sacrifice;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* blessing_of_sanctuary(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of sanctuary",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* blessing_of_kings(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of kings",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* blessing_of_wisdom(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of wisdom",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* blessing_of_kings_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of kings on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* blessing_of_wisdom_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of wisdom on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* blessing_of_sanctuary_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("blessing of sanctuary on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* retribution_aura(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("retribution aura",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("devotion aura") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* lay_on_hands(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("lay on hands",
|
||||
/*P*/ {},
|
||||
/*A*/ {}, // { NextAction("divine shield"), new
|
||||
// NextAction("flash of light"), NULL),
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* lay_on_hands_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("lay on hands on party",
|
||||
/*P*/ {},
|
||||
/*A*/ {}, // { NextAction("flash of light"), NULL),
|
||||
/*C*/ {});
|
||||
}
|
||||
// static ActionNode* seal_of_light(PlayerbotAI* /* ai */)
|
||||
// {
|
||||
// return new ActionNode ("seal of light",
|
||||
// /*P*/ NULL,
|
||||
// /*A*/ { NextAction("seal of justice"), NULL),
|
||||
// /*C*/ NULL);
|
||||
// }
|
||||
static ActionNode* cleanse_poison(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("cleanse poison",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("purify poison") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* cleanse_magic(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("cleanse magic",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* cleanse_disease(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("cleanse disease",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("purify disease") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* cleanse_poison_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("cleanse poison on party",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("purify poison on party") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* cleanse_disease_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("cleanse disease on party",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("purify disease on party") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* seal_of_wisdom(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode ("seal of wisdom",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* seal_of_justice(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("seal of justice",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* hand_of_reckoning(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("hand of reckoning",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("righteous defense") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* righteous_defense(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("righteous defense",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("avenger's shield") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* avengers_shield(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("avenger's shield",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("judgement of wisdom") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* divine_sacrifice(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("divine sacrifice",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ { NextAction("cancel divine sacrifice") });
|
||||
}
|
||||
static ActionNode* judgement_of_wisdom(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("judgement of wisdom",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("judgement of light") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* judgement(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("judgement",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* divine_shield(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("divine shield",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("divine protection") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* flash_of_light(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("flash of light",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("holy light") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* flash_of_light_on_party(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("flash of light on party",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("holy light on party") },
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* holy_wrath(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("holy wrath",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* hammer_of_wrath(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("hammer of wrath",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {});
|
||||
}
|
||||
static ActionNode* seal_of_command(PlayerbotAI* /* ai */)
|
||||
{
|
||||
return new ActionNode("seal of command",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {});
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
124
src/Ai/Class/Paladin/Strategy/HealPaladinStrategy.cpp
Normal file
124
src/Ai/Class/Paladin/Strategy/HealPaladinStrategy.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 "HealPaladinStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class HealPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
};
|
||||
|
||||
HealPaladinStrategy::HealPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new HealPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> HealPaladinStrategy::getDefaultActions()
|
||||
{
|
||||
return { NextAction("judgement of light", ACTION_DEFAULT) };
|
||||
}
|
||||
|
||||
void HealPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericPaladinStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"seal",
|
||||
{
|
||||
NextAction("seal of wisdom", ACTION_HIGH)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium mana",
|
||||
{
|
||||
NextAction("divine illumination", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("divine favor", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member to heal out of spell range",
|
||||
{
|
||||
NextAction("reach party member to heal", ACTION_EMERGENCY + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium group heal setting",
|
||||
{
|
||||
NextAction("divine sacrifice", ACTION_CRITICAL_HEAL + 5),
|
||||
NextAction("avenging wrath", ACTION_HIGH + 4),
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member critical health",
|
||||
{
|
||||
NextAction("holy shock on party", ACTION_CRITICAL_HEAL + 6),
|
||||
NextAction("divine sacrifice", ACTION_CRITICAL_HEAL + 5),
|
||||
NextAction("holy light on party", ACTION_CRITICAL_HEAL + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member low health",
|
||||
{
|
||||
NextAction("holy light on party", ACTION_MEDIUM_HEAL + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member medium health",
|
||||
{
|
||||
NextAction("holy light on party", ACTION_LIGHT_HEAL + 9),
|
||||
NextAction("flash of light on party", ACTION_LIGHT_HEAL + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member almost full health",
|
||||
{
|
||||
NextAction("flash of light on party", ACTION_LIGHT_HEAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"beacon of light on main tank",
|
||||
{
|
||||
NextAction("beacon of light on main tank", ACTION_CRITICAL_HEAL + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"sacred shield on main tank",
|
||||
{
|
||||
NextAction("sacred shield on main tank", ACTION_CRITICAL_HEAL + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
24
src/Ai/Class/Paladin/Strategy/HealPaladinStrategy.h
Normal file
24
src/Ai/Class/Paladin/Strategy/HealPaladinStrategy.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_HEALPALADINSTRATEGY_H
|
||||
#define _PLAYERBOT_HEALPALADINSTRATEGY_H
|
||||
|
||||
#include "GenericPaladinStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class HealPaladinStrategy : public GenericPaladinStrategy
|
||||
{
|
||||
public:
|
||||
HealPaladinStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "heal"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_HEAL | STRATEGY_TYPE_RANGED; }
|
||||
};
|
||||
|
||||
#endif
|
||||
243
src/Ai/Class/Paladin/Strategy/OffhealRetPaladinStrategy.cpp
Normal file
243
src/Ai/Class/Paladin/Strategy/OffhealRetPaladinStrategy.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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 "OffhealRetPaladinStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class OffhealRetPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
OffhealRetPaladinStrategyActionNodeFactory()
|
||||
{
|
||||
creators["retribution aura"] = &retribution_aura;
|
||||
creators["seal of corruption"] = &seal_of_corruption;
|
||||
creators["seal of vengeance"] = &seal_of_vengeance;
|
||||
creators["seal of command"] = &seal_of_command;
|
||||
creators["blessing of might"] = &blessing_of_might;
|
||||
creators["crusader strike"] = &crusader_strike;
|
||||
creators["divine plea"] = &divine_plea;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* retribution_aura([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"retribution aura",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("devotion aura") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_corruption([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of corruption",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of vengeance") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_vengeance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of vengeance",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of command") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_command([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of command",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* blessing_of_might([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"blessing of might",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("blessing of kings") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* crusader_strike([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"crusader strike",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* divine_plea([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"divine plea",
|
||||
/*P*/ {},
|
||||
/*A*/ {},
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
OffhealRetPaladinStrategy::OffhealRetPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new OffhealRetPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> OffhealRetPaladinStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("hammer of wrath", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("judgement of wisdom", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("crusader strike", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("divine storm", ACTION_DEFAULT + 0.3f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void OffhealRetPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericPaladinStrategy::InitTriggers(triggers);
|
||||
|
||||
// Damage Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"seal",
|
||||
{
|
||||
NextAction("seal of corruption", ACTION_HIGH)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("seal of wisdom", ACTION_HIGH + 5),
|
||||
NextAction("divine plea", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"art of war",
|
||||
{
|
||||
NextAction("exorcism", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"avenging wrath",
|
||||
{
|
||||
NextAction("avenging wrath", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("divine storm", ACTION_HIGH + 4),
|
||||
NextAction("consecration", ACTION_HIGH + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("reach melee", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"retribution aura",
|
||||
{
|
||||
NextAction("retribution aura", ACTION_NORMAL)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"blessing of might",
|
||||
{
|
||||
NextAction("blessing of might", ACTION_NORMAL + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("holy light", ACTION_CRITICAL_HEAL + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Healing Triggers
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member critical health",
|
||||
{
|
||||
NextAction("holy shock on party", ACTION_CRITICAL_HEAL + 6),
|
||||
NextAction("holy light on party", ACTION_CRITICAL_HEAL + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member low health",
|
||||
{
|
||||
NextAction("holy light on party", ACTION_MEDIUM_HEAL + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member medium health",
|
||||
{
|
||||
NextAction("flash of light on party", ACTION_LIGHT_HEAL + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member almost full health",
|
||||
{
|
||||
NextAction("flash of light on party", ACTION_LIGHT_HEAL + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"party member to heal out of spell range",
|
||||
{
|
||||
NextAction("reach party member to heal", ACTION_EMERGENCY + 3)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"beacon of light on main tank",
|
||||
{
|
||||
NextAction("beacon of light on main tank", ACTION_CRITICAL_HEAL + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
27
src/Ai/Class/Paladin/Strategy/OffhealRetPaladinStrategy.h
Normal file
27
src/Ai/Class/Paladin/Strategy/OffhealRetPaladinStrategy.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_OFFHEALRETPALADINSTRATEGY_H
|
||||
#define _PLAYERBOT_OFFHEALRETPALADINSTRATEGY_H
|
||||
|
||||
#include "GenericPaladinStrategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class OffhealRetPaladinStrategy : public GenericPaladinStrategy
|
||||
{
|
||||
public:
|
||||
OffhealRetPaladinStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "offheal"; }
|
||||
std::vector<NextAction> getDefaultActions() override;
|
||||
uint32 GetType() const override
|
||||
{
|
||||
return STRATEGY_TYPE_COMBAT | STRATEGY_TYPE_DPS | STRATEGY_TYPE_HEAL | STRATEGY_TYPE_MELEE;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
94
src/Ai/Class/Paladin/Strategy/PaladinBuffStrategies.cpp
Normal file
94
src/Ai/Class/Paladin/Strategy/PaladinBuffStrategies.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 "PaladinBuffStrategies.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
void PaladinBuffManaStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("blessing of wisdom on party",
|
||||
{ NextAction("blessing of wisdom on party", 11.0f) }));
|
||||
|
||||
triggers.push_back(new TriggerNode("blessing of kings on party",
|
||||
{ NextAction("blessing of kings on party", 10.5f) }));
|
||||
}
|
||||
|
||||
void PaladinBuffHealthStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("blessing of sanctuary on party",
|
||||
{ NextAction("blessing of sanctuary on party", 11.0f) }));
|
||||
}
|
||||
|
||||
void PaladinBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("blessing of might on party",
|
||||
{ NextAction("blessing of might on party", 11.0f) }));
|
||||
}
|
||||
|
||||
void PaladinShadowResistanceStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("shadow resistance aura",
|
||||
{ NextAction("shadow resistance aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinFrostResistanceStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(
|
||||
new TriggerNode("frost resistance aura",
|
||||
{ NextAction("frost resistance aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinFireResistanceStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"fire resistance aura", { NextAction("fire resistance aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinBuffArmorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("devotion aura",
|
||||
{ NextAction("devotion aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinBuffAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"retribution aura", { NextAction("retribution aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinBuffCastStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"concentration aura", { NextAction("concentration aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinBuffSpeedStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"crusader aura", { NextAction("crusader aura", ACTION_NORMAL) }));
|
||||
}
|
||||
|
||||
void PaladinBuffThreatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"righteous fury", { NextAction("righteous fury", ACTION_HIGH + 8) }));
|
||||
}
|
||||
|
||||
void PaladinBuffStatsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
// First Sanctuary (prio > Kings)
|
||||
triggers.push_back(
|
||||
new TriggerNode("blessing of sanctuary on party",
|
||||
{ NextAction("blessing of sanctuary on party", 12.0f) }));
|
||||
|
||||
// After Kings
|
||||
triggers.push_back(
|
||||
new TriggerNode("blessing of kings on party",
|
||||
{ NextAction("blessing of kings on party", 11.0f) }));
|
||||
}
|
||||
121
src/Ai/Class/Paladin/Strategy/PaladinBuffStrategies.h
Normal file
121
src/Ai/Class/Paladin/Strategy/PaladinBuffStrategies.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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_PALADINBUFFSTRATEGIES_H
|
||||
#define _PLAYERBOT_PALADINBUFFSTRATEGIES_H
|
||||
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class PaladinBuffManaStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bmana"; }
|
||||
};
|
||||
|
||||
class PaladinBuffHealthStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffHealthStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bhealth"; }
|
||||
};
|
||||
|
||||
class PaladinBuffDpsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bdps"; }
|
||||
};
|
||||
|
||||
class PaladinBuffArmorStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffArmorStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "barmor"; }
|
||||
};
|
||||
|
||||
class PaladinBuffAoeStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffAoeStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "baoe"; }
|
||||
};
|
||||
|
||||
class PaladinBuffCastStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffCastStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bcast"; }
|
||||
};
|
||||
|
||||
class PaladinBuffSpeedStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffSpeedStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bspeed"; }
|
||||
};
|
||||
|
||||
class PaladinBuffThreatStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffThreatStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bthreat"; }
|
||||
};
|
||||
|
||||
class PaladinBuffStatsStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinBuffStatsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "bstats"; }
|
||||
};
|
||||
|
||||
class PaladinShadowResistanceStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinShadowResistanceStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "rshadow"; }
|
||||
};
|
||||
|
||||
class PaladinFrostResistanceStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinFrostResistanceStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "rfrost"; }
|
||||
};
|
||||
|
||||
class PaladinFireResistanceStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
PaladinFireResistanceStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return "rfire"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
201
src/Ai/Class/Paladin/Strategy/TankPaladinStrategy.cpp
Normal file
201
src/Ai/Class/Paladin/Strategy/TankPaladinStrategy.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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 "TankPaladinStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class TankPaladinStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
TankPaladinStrategyActionNodeFactory()
|
||||
{
|
||||
creators["seal of corruption"] = &seal_of_corruption;
|
||||
creators["seal of vengeance"] = &seal_of_vengeance;
|
||||
creators["seal of command"] = &seal_of_command;
|
||||
creators["hand of reckoning"] = &hand_of_reckoning;
|
||||
creators["taunt spell"] = &hand_of_reckoning;
|
||||
}
|
||||
|
||||
private:
|
||||
static ActionNode* seal_of_command([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of command",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of corruption") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
static ActionNode* seal_of_corruption([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of corruption",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of vengeance") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* seal_of_vengeance([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"seal of vengeance",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("seal of righteousness") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
|
||||
static ActionNode* hand_of_reckoning([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode(
|
||||
"hand of reckoning",
|
||||
/*P*/ {},
|
||||
/*A*/ { NextAction("righteous defense") },
|
||||
/*C*/ {}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
TankPaladinStrategy::TankPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStrategy(botAI)
|
||||
{
|
||||
actionNodeFactories.Add(new TankPaladinStrategyActionNodeFactory());
|
||||
}
|
||||
|
||||
std::vector<NextAction> TankPaladinStrategy::getDefaultActions()
|
||||
{
|
||||
return {
|
||||
NextAction("shield of righteousness", ACTION_DEFAULT + 0.6f),
|
||||
NextAction("hammer of the righteous", ACTION_DEFAULT + 0.5f),
|
||||
NextAction("judgement of wisdom", ACTION_DEFAULT + 0.4f),
|
||||
NextAction("melee", ACTION_DEFAULT)
|
||||
};
|
||||
}
|
||||
|
||||
void TankPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericPaladinStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"seal",
|
||||
{
|
||||
NextAction("seal of corruption", ACTION_HIGH)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low mana",
|
||||
{
|
||||
NextAction("seal of wisdom", ACTION_HIGH + 9)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(new TriggerNode(
|
||||
"light aoe",
|
||||
{
|
||||
NextAction("avenger's shield", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium aoe",
|
||||
{
|
||||
NextAction("consecration", ACTION_HIGH + 7),
|
||||
NextAction("avenger's shield", ACTION_HIGH + 6)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"lose aggro",
|
||||
{
|
||||
NextAction("hand of reckoning", ACTION_HIGH + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium health",
|
||||
{ NextAction("holy shield", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"low health",
|
||||
{
|
||||
NextAction("holy shield", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"critical health",
|
||||
{
|
||||
NextAction("holy shield", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"avenging wrath",
|
||||
{
|
||||
NextAction("avenging wrath", ACTION_HIGH + 2)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"target critical health",
|
||||
{
|
||||
NextAction("hammer of wrath", ACTION_CRITICAL_HEAL)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"righteous fury",
|
||||
{
|
||||
NextAction("righteous fury", ACTION_HIGH + 8)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"medium group heal setting",
|
||||
{
|
||||
NextAction("divine sacrifice", ACTION_HIGH + 5)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enough mana",
|
||||
{
|
||||
NextAction("consecration", ACTION_HIGH + 4)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"not facing target",
|
||||
{
|
||||
NextAction("set facing", ACTION_NORMAL + 7)
|
||||
}
|
||||
)
|
||||
);
|
||||
triggers.push_back(
|
||||
new TriggerNode(
|
||||
"enemy out of melee",
|
||||
{
|
||||
NextAction("reach melee", ACTION_HIGH + 1)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user