diff --git a/src/Ai/Base/ActionContext.h b/src/Ai/Base/ActionContext.h index 6431ee87c..55081b443 100644 --- a/src/Ai/Base/ActionContext.h +++ b/src/Ai/Base/ActionContext.h @@ -163,6 +163,7 @@ public: creators["war stomp"] = &ActionContext::war_stomp; creators["blood fury"] = &ActionContext::blood_fury; creators["berserking"] = &ActionContext::berserking; + creators["every man for himself"] = &ActionContext::every_man_for_himself; creators["use trinket"] = &ActionContext::use_trinket; creators["auto talents"] = &ActionContext::auto_talents; creators["auto share quest"] = &ActionContext::auto_share_quest; @@ -357,6 +358,7 @@ private: static Action* war_stomp(PlayerbotAI* botAI) { return new CastWarStompAction(botAI); } static Action* blood_fury(PlayerbotAI* botAI) { return new CastBloodFuryAction(botAI); } static Action* berserking(PlayerbotAI* botAI) { return new CastBerserkingAction(botAI); } + static Action* every_man_for_himself(PlayerbotAI* botAI) { return new CastEveryManForHimselfAction(botAI); } static Action* use_trinket(PlayerbotAI* botAI) { return new UseTrinketAction(botAI); } static Action* auto_talents(PlayerbotAI* botAI) { return new AutoSetTalentsAction(botAI); } static Action* auto_share_quest(PlayerbotAI* ai) { return new AutoShareQuestAction(ai); } diff --git a/src/Ai/Base/Actions/GenericSpellActions.cpp b/src/Ai/Base/Actions/GenericSpellActions.cpp index 148bc6d3c..392d18500 100644 --- a/src/Ai/Base/Actions/GenericSpellActions.cpp +++ b/src/Ai/Base/Actions/GenericSpellActions.cpp @@ -311,6 +311,30 @@ bool CastVehicleSpellAction::Execute(Event /*event*/) return botAI->CastVehicleSpell(spellId, GetTarget()); } +bool CastEveryManForHimselfAction::isPossible() +{ + uint32 spellId = AI_VALUE2(uint32, "spell id", spell); + if (!spellId) + return false; + + if (!bot->HasSpell(spellId)) + return false; + + if (bot->HasSpellCooldown(spellId)) + return false; + + return true; +} + +bool CastEveryManForHimselfAction::isUseful() +{ + return bot->HasAuraType(SPELL_AURA_MOD_STUN) || + bot->HasAuraType(SPELL_AURA_MOD_FEAR) || + bot->HasAuraType(SPELL_AURA_MOD_ROOT) || + bot->HasAuraType(SPELL_AURA_MOD_CONFUSE) || + bot->HasAuraType(SPELL_AURA_MOD_CHARM); +} + bool UseTrinketAction::Execute(Event /*event*/) { Item* trinket1 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET1); diff --git a/src/Ai/Base/Actions/GenericSpellActions.h b/src/Ai/Base/Actions/GenericSpellActions.h index 9aa83f62d..fdc0dcdcf 100644 --- a/src/Ai/Base/Actions/GenericSpellActions.h +++ b/src/Ai/Base/Actions/GenericSpellActions.h @@ -284,6 +284,16 @@ public: CastBerserkingAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "berserking") {} }; +class CastEveryManForHimselfAction : public CastSpellAction +{ +public: + CastEveryManForHimselfAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "every man for himself") {} + + std::string const GetTargetName() override { return "self target"; } + bool isPossible() override; + bool isUseful() override; +}; + class UseTrinketAction : public Action { public: diff --git a/src/Ai/Base/Strategy/RacialsStrategy.cpp b/src/Ai/Base/Strategy/RacialsStrategy.cpp index dc6d5bc48..753302c35 100644 --- a/src/Ai/Base/Strategy/RacialsStrategy.cpp +++ b/src/Ai/Base/Strategy/RacialsStrategy.cpp @@ -34,6 +34,9 @@ void RacialsStrategy::InitTriggers(std::vector& triggers) NextAction("berserking", ACTION_NORMAL + 5), NextAction("use trinket", ACTION_NORMAL + 4) })); + triggers.push_back(new TriggerNode( + "loss of control", { NextAction("every man for himself", ACTION_EMERGENCY + 1) })); + } RacialsStrategy::RacialsStrategy(PlayerbotAI* botAI) : Strategy(botAI) diff --git a/src/Ai/Base/Trigger/GenericTriggers.cpp b/src/Ai/Base/Trigger/GenericTriggers.cpp index 209766be7..8cee6bef0 100644 --- a/src/Ai/Base/Trigger/GenericTriggers.cpp +++ b/src/Ai/Base/Trigger/GenericTriggers.cpp @@ -464,6 +464,15 @@ bool AttackerCountTrigger::IsActive() { return AI_VALUE(uint8, "attacker count") bool HasAuraTrigger::IsActive() { return botAI->HasAura(getName(), GetTarget(), false, false, -1, true); } +bool LossOfControlTrigger::IsActive() +{ + return bot->HasAuraType(SPELL_AURA_MOD_STUN) || + bot->HasAuraType(SPELL_AURA_MOD_FEAR) || + bot->HasAuraType(SPELL_AURA_MOD_ROOT) || + bot->HasAuraType(SPELL_AURA_MOD_CONFUSE) || + bot->HasAuraType(SPELL_AURA_MOD_CHARM); +} + bool HasAuraStackTrigger::IsActive() { Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true, stack); diff --git a/src/Ai/Base/Trigger/GenericTriggers.h b/src/Ai/Base/Trigger/GenericTriggers.h index 7b884fbf0..68fc4b61f 100644 --- a/src/Ai/Base/Trigger/GenericTriggers.h +++ b/src/Ai/Base/Trigger/GenericTriggers.h @@ -746,6 +746,14 @@ public: bool IsActive() override; }; +class LossOfControlTrigger : public Trigger +{ +public: + LossOfControlTrigger(PlayerbotAI* botAI) : Trigger(botAI, "loss of control", 1) {} + + bool IsActive() override; +}; + class IsSwimmingTrigger : public Trigger { public: diff --git a/src/Ai/Base/TriggerContext.h b/src/Ai/Base/TriggerContext.h index d4f8ac3b7..ca662f3d4 100644 --- a/src/Ai/Base/TriggerContext.h +++ b/src/Ai/Base/TriggerContext.h @@ -59,6 +59,7 @@ public: creators["party member almost full health"] = &TriggerContext::PartyMemberAlmostFullHealth; creators["generic boost"] = &TriggerContext::generic_boost; + creators["loss of control"] = &TriggerContext::loss_of_control; creators["protect party member"] = &TriggerContext::protect_party_member; @@ -363,6 +364,7 @@ private: return new PartyMemberAlmostFullHealthTrigger(botAI); } static Trigger* generic_boost(PlayerbotAI* botAI) { return new GenericBoostTrigger(botAI); } + static Trigger* loss_of_control(PlayerbotAI* botAI) { return new LossOfControlTrigger(botAI); } static Trigger* PartyMemberCriticalHealth(PlayerbotAI* botAI) { return new PartyMemberCriticalHealthTrigger(botAI);