mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-02-21 02:20:00 +01:00
Hello everybody, I saw that the hunter class had one strategy for all 3 specs, and decided to create specialized strategies for each one. Here is a list of the changes: conf\playerbots.conf.dist: Redid the talent trees and glyphs slightly, for more consistent dps src\AiFactory.cpp: Changed the default strategies assigned for each spec. src\strategy\hunter\BeastMasteryHunterStrategy.cpp and src\strategy\hunter\BeastMasteryHunterStrategy.h: Strategy for BM hunters. Includes all of the original logic from DpsHunterStrategy, with the addition of kill command, bestial wrath, and intimidation. src\strategy\hunter\DpsHunterStrategy.cpp and src\strategy\hunter\DpsHunterStrategy.h: Old Dps strategy used for all 3 specs - removed. src\strategy\hunter\GenericHunterStrategy.cpp and src\strategy\hunter\GenericHunterStrategy.h: Tidied up code, added Dragonhawk passthrough to hawk, moved rapid fire to inittriggers for generichunterstrategy and increased its priority (it is still a boost trigger, so it will function the same). src\strategy\hunter\HunterActions.cpp: Added isuseful check for aspect of the hawk, to ensure it is never cast if the bot knows aspect of the dragonhawk. Added isuseful check for arcane shot to never use it after explosive shot is learned (so the hunter can use it as it levels survival, but drops it after that). Also added a check for arcane shot, so it won't use it above 435 armor pen rating (steady shot is superior after this arp). Added isuseful check for immolation trap so it won't use it after explosive shot is learned. src\strategy\hunter\HunterActions.h: General cleanup/alignment of actions based on type. Added TTL checks to all DoTs and debuffs - hunters weren't using hunter's mark, serpent sting, black arrow, explosive shot on enemies that it thought would die too soon. Black Arrow - added a strategy check here as well so the bot won't use it at all if trap weave is enabled. There was already a check in the trigger, but it was still getting cast, so I added this check. Explosive Shot Rank 4, 3, 2, 1 actions- Added these so the hunter can downrank explosive shot dynamically based on the level when lock and load procs. So if the hunter is level 70, and a lock and load proc happens, it will fire rank 2 - rank 1 - rank 2, similar to how the level 80 version will fire 4-3-4. src\strategy\hunter\HunterAiObjectContext.cpp: Added strategy support for bm, mm, and surv (and their aoes) Added trigger support for kill command, explosive shot, lock and load, silencing shot (as an spellcasting interrupt), and intimidation Added action support for the 4 ranks of explosive shot and intimidation. src\strategy\hunter\HunterTriggers.cpp: Kill command was completely non-functional because there was no buff trigger associated with it. Adding this will correct that, and the hunter will use kill command. src\strategy\hunter\HunterTriggers.h: Added Kill command, silencing shot, intimidation, lock and load, and explosive shot triggers. src\strategy\hunter\MarksmanshipHunterStrategy.cpp and src\strategy\hunter\MarksmanshipHunterStrategy.h: Strategy for MM hunters. Includes all of the original logic from DpsHunterStrategy, with the addition of kill command, silencing shot, chimera shot, and aimed shot. src\strategy\hunter\SurvivalHunterStrategy.cpp and src\strategy\hunter\SurvivalHunterStrategy.h: Strategy for Survival hunters. Includes all of the original logic from DpsHunterStrategy, with the addition of kill command, explosive shot, black arrow, aimed shot, lock and load triggers + downranking explosive shot.
452 lines
12 KiB
C++
452 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
|
*/
|
|
|
|
#ifndef _PLAYERBOT_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;
|
|
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
|