mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-21 20:46:22 +00:00
Fix stuck on knockback, enhance movement & flee and trap weave strats (#980)
* Hunter trap weave strats * Do not allow actions to stack * Remove trap weave by default * Refactor on Engine Co-authored-by: SaW <swerkhoven@outlook.com> * Remove unused funcs in Queue * Remove ExpireActionTime config --------- Co-authored-by: SaW <swerkhoven@outlook.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "GenericHunterStrategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
class GenericHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
creators["wing clip"] = &wing_clip;
|
||||
creators["mongoose bite"] = &mongoose_bite;
|
||||
creators["raptor strike"] = &raptor_strike;
|
||||
creators["explosive trap"] = &explosive_trap;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -70,6 +72,15 @@ private:
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* explosive_trap([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("explosive trap",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("immolation trap"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GenericHunterStrategy::GenericHunterStrategy(PlayerbotAI* botAI) : CombatStrategy(botAI)
|
||||
@@ -82,8 +93,11 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
CombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy within melee",
|
||||
NextAction::array(0, new NextAction("wing clip", ACTION_HIGH + 1),
|
||||
new NextAction("mongoose bite", ACTION_HIGH), nullptr)));
|
||||
NextAction::array(0,
|
||||
new NextAction("explosive trap", ACTION_MOVE + 7),
|
||||
new NextAction("mongoose bite", ACTION_HIGH + 2),
|
||||
new NextAction("wing clip", ACTION_HIGH + 1),
|
||||
nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("medium threat", NextAction::array(0, new NextAction("feign death", 35.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("hunters pet medium health",
|
||||
@@ -93,7 +107,10 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode("aspect of the viper",
|
||||
NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
|
||||
triggers.push_back(new TriggerNode("enemy too close for auto shot",
|
||||
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||
NextAction::array(0,
|
||||
new NextAction("disengage", ACTION_MOVE + 5),
|
||||
new NextAction("flee", ACTION_MOVE + 4),
|
||||
nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("low tank threat",
|
||||
NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
|
||||
@@ -124,3 +141,14 @@ void HunterCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode(
|
||||
"freezing trap", NextAction::array(0, new NextAction("freezing trap on cc", ACTION_HIGH + 3), nullptr)));
|
||||
}
|
||||
|
||||
void HunterTrapWeaveStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"immolation trap no cd", NextAction::array(0, new NextAction("reach melee", ACTION_HIGH + 3), nullptr)));
|
||||
|
||||
// triggers.push_back(new TriggerNode(
|
||||
// "scare beast", NextAction::array(0, new NextAction("scare beast on cc", ACTION_HIGH + 3), nullptr)));
|
||||
// triggers.push_back(new TriggerNode(
|
||||
// "freezing trap", NextAction::array(0, new NextAction("freezing trap on cc", ACTION_HIGH + 3), nullptr)));
|
||||
}
|
||||
|
||||
@@ -40,4 +40,14 @@ public:
|
||||
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
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Event.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
bool CastHuntersMarkAction::isUseful() { return CastDebuffSpellAction::isUseful(); }
|
||||
@@ -46,6 +47,22 @@ bool CastAutoShotAction::isUseful()
|
||||
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()); }
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define _PLAYERBOT_HUNTERACTIONS_H
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "Event.h"
|
||||
#include "GenericSpellActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
@@ -84,6 +85,27 @@ END_SPELL_ACTION()
|
||||
BEGIN_RANGED_SPELL_ACTION(CastTranquilizingShotAction, "tranquilizing shot")
|
||||
END_SPELL_ACTION()
|
||||
|
||||
class CastDisengageAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastDisengageAction(PlayerbotAI* botAI): CastSpellAction(botAI, "disengage") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class CastImmolationTrapAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastImmolationTrapAction(PlayerbotAI* botAI): CastSpellAction(botAI, "immolation trap") {}
|
||||
};
|
||||
|
||||
class CastExplosiveTrapAction : public CastSpellAction
|
||||
{
|
||||
public:
|
||||
CastExplosiveTrapAction(PlayerbotAI* botAI): CastSpellAction(botAI, "explosive trap") {}
|
||||
};
|
||||
|
||||
class CastAspectOfTheHawkAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
creators["boost"] = &HunterStrategyFactoryInternal::boost;
|
||||
creators["pet"] = &HunterStrategyFactoryInternal::pet;
|
||||
creators["cc"] = &HunterStrategyFactoryInternal::cc;
|
||||
creators["trap weave"] = &HunterStrategyFactoryInternal::trap_weave;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -35,6 +36,7 @@ private:
|
||||
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); }
|
||||
};
|
||||
|
||||
class HunterBuffStrategyFactoryInternal : public NamedObjectContext<Strategy>
|
||||
@@ -88,6 +90,7 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -122,6 +125,7 @@ private:
|
||||
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); }
|
||||
};
|
||||
|
||||
class HunterAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
@@ -176,6 +180,9 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -225,7 +232,9 @@ private:
|
||||
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); }
|
||||
};
|
||||
|
||||
HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||
|
||||
@@ -5,13 +5,23 @@
|
||||
|
||||
#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"
|
||||
|
||||
bool BlackArrowTrigger::IsActive()
|
||||
{
|
||||
if (botAI->HasStrategy("trap weave", BOT_STATE_COMBAT))
|
||||
return false;
|
||||
|
||||
return DebuffTrigger::IsActive();
|
||||
}
|
||||
|
||||
bool HunterAspectOfTheHawkTrigger::IsActive()
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
|
||||
@@ -75,6 +75,7 @@ class BlackArrowTrigger : public DebuffTrigger
|
||||
{
|
||||
public:
|
||||
BlackArrowTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "black arrow", 1, true) {}
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class HuntersMarkTrigger : public DebuffTrigger
|
||||
@@ -185,4 +186,11 @@ 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") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user