From e93b1edcd557c4c0a2aa4de5ffd19b391030e300 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 30 Jul 2023 14:33:52 +0800 Subject: [PATCH] fix strategies conflict for rndbot --- src/AiFactory.cpp | 109 +++++++++--------- src/RandomPlayerbotFactory.cpp | 7 ++ src/strategy/druid/CasterDruidStrategy.cpp | 2 +- src/strategy/druid/HealDruidStrategy.cpp | 4 +- src/strategy/generic/CombatStrategy.cpp | 1 + src/strategy/generic/MeleeCombatStrategy.cpp | 4 +- src/strategy/generic/RpgStrategy.cpp | 2 +- src/strategy/hunter/GenericHunterStrategy.cpp | 2 +- src/strategy/mage/GenericMageStrategy.cpp | 1 + src/strategy/paladin/HealPaladinStrategy.cpp | 2 + src/strategy/priest/GenericPriestStrategy.cpp | 4 +- src/strategy/rogue/DpsRogueStrategy.cpp | 10 +- src/strategy/shaman/CasterShamanStrategy.cpp | 4 +- src/strategy/shaman/HealShamanStrategy.cpp | 4 +- src/strategy/values/AttackersValue.cpp | 1 + src/strategy/values/GrindTargetValue.cpp | 2 +- .../warrior/GenericWarriorStrategy.cpp | 2 +- 17 files changed, 82 insertions(+), 79 deletions(-) diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index d13ed067..397374f0 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -12,6 +12,7 @@ #include "DKAiObjectContext.h" #include "PriestAiObjectContext.h" #include "MageAiObjectContext.h" +#include "SharedDefines.h" #include "WarlockAiObjectContext.h" #include "WarriorAiObjectContext.h" #include "ShamanAiObjectContext.h" @@ -275,7 +276,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa else engine->addStrategies("heal", "threat", nullptr); - engine->addStrategies("dps assist", "cure", "ranged", nullptr); + engine->addStrategies("dps assist", "cure", nullptr); break; case CLASS_MAGE: if (tab == 0) @@ -285,65 +286,62 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa else engine->addStrategies("frost", "frost aoe", "threat", nullptr); - engine->addStrategies("dps", "dps assist", "cure", "ranged", nullptr); + engine->addStrategies("dps", "dps assist", "cure", nullptr); break; case CLASS_WARRIOR: if (tab == 2) - engine->addStrategies("tank", "tank assist", "aoe", "close", "mark rti", nullptr); + engine->addStrategies("tank", "tank assist", "aoe", "mark rti", nullptr); else if (player->getLevel() < 30 || tab == 0) - engine->addStrategies("arms", "aoe", "dps assist", "threat", "close", "behind", nullptr); + engine->addStrategies("arms", "aoe", "dps assist", "threat", "behind", nullptr); else - engine->addStrategies("fury", "aoe", "dps assist", "threat", "close", "behind", nullptr); + engine->addStrategies("fury", "aoe", "dps assist", "threat", "behind", nullptr); break; case CLASS_SHAMAN: if (tab == 0) - engine->addStrategies("caster", "caster aoe", "bmana", "threat", "ranged", nullptr); + engine->addStrategies("caster", "caster aoe", "bmana", "threat", nullptr); else if (tab == 2) - engine->addStrategies("heal", "bmana", "ranged", nullptr); + engine->addStrategies("heal", "bmana", nullptr); else - engine->addStrategies("melee", "melee aoe", "bdps", "threat", "close", nullptr); + engine->addStrategies("melee", "melee aoe", "bdps", "threat", nullptr); engine->addStrategies("dps assist", "cure", "totems", nullptr); break; case CLASS_PALADIN: if (tab == 1) - engine->addStrategies("tank", "tank assist", "bthreat", "barmor", "cure", "close", nullptr); + engine->addStrategies("tank", "tank assist", "bthreat", "barmor", "cure", nullptr); else if (tab == 0) engine->addStrategies("heal", "dps assist", "cure", nullptr); else - engine->addStrategies("dps", "dps assist", "cure", "close", "baoe", nullptr); + engine->addStrategies("dps", "dps assist", "cure", "baoe", nullptr); break; case CLASS_DRUID: if (tab == 0) { - engine->addStrategies("caster", "cure", "caster aoe", "threat", "dps assist", "ranged", nullptr); - if (player->getLevel() > 19) - engine->addStrategy("caster debuff"); + engine->addStrategies("caster", "cure", "caster aoe", "threat", "dps assist", nullptr); + engine->addStrategy("caster debuff"); } else if (tab == 2) - engine->addStrategies("heal", "cure", "dps assist", "ranged", nullptr); + engine->addStrategies("heal", "cure", "dps assist", nullptr); else { - engine->removeStrategy("ranged"); engine->removeStrategy("flee"); - engine->addStrategies("bear", "tank assist", "close", nullptr); + engine->addStrategies("bear", "tank assist", nullptr); } break; case CLASS_HUNTER: - engine->addStrategies("dps", "aoe", "bdps", "threat", "dps assist", "ranged", nullptr); - if (player->getLevel() > 19) - engine->addStrategy("dps debuff"); + engine->addStrategies("dps", "aoe", "bdps", "threat", "dps assist", nullptr); + engine->addStrategy("dps debuff"); break; case CLASS_ROGUE: if (tab == ROGUE_TAB_ASSASSINATION) { - engine->addStrategies("melee", "threat", "dps assist", "aoe", "close", "behind", nullptr); + engine->addStrategies("melee", "threat", "dps assist", "aoe", "behind", nullptr); } else { - engine->addStrategies("dps", "threat", "dps assist", "aoe", "close", "behind", nullptr); + engine->addStrategies("dps", "threat", "dps assist", "aoe", "behind", nullptr); } break; case CLASS_WARLOCK: - engine->addStrategies("dps assist", "dps", "dps debuff", "aoe", "ranged", "threat", nullptr); + engine->addStrategies("dps assist", "dps", "dps debuff", "aoe", "threat", nullptr); break; case CLASS_DEATH_KNIGHT: if (tab == 0) @@ -353,8 +351,6 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa else engine->addStrategies("unholy", "unholy aoe", "dps assist", "threat", nullptr); - engine->addStrategies("close", nullptr); - break; } @@ -362,40 +358,39 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa { if (!player->GetGroup()) { - engine->ChangeStrategy(sPlayerbotAIConfig->randomBotCombatStrategies); - - // engine->addStrategy("flee"); + // change for heal spec engine->addStrategy("boost"); - - if (player->getClass() == CLASS_WARLOCK) - { - engine->removeStrategy("ranged"); - } - - if (player->getClass() == CLASS_DRUID && tab == 2) - { - engine->addStrategies("caster", "caster aoe", nullptr); - } - - if (player->getClass() == CLASS_DRUID && tab == 1 && urand(0, 100) > 50 && player->getLevel() > 19) - { - engine->addStrategy("dps"); - } - - if (player->getClass() == CLASS_PRIEST && tab == 1) - { - engine->removeStrategy("heal"); - engine->addStrategies("holy", "shadow debuff", "shadow aoe", "threat", nullptr); - } - - if (player->getClass() == CLASS_SHAMAN && tab == 2) - { - engine->addStrategies("caster", "caster aoe", nullptr); - } - - if (player->getClass() == CLASS_PALADIN && tab == 0) - { - engine->addStrategies("dps", "close", nullptr); + engine->addStrategy("dps assist"); + engine->removeStrategy("threat"); + // engine- + switch (player->getClass()) { + case CLASS_PRIEST: { + if (tab != PRIEST_TAB_SHADOW) { + engine->addStrategies("dps", "shadow debuff", "shadow aoe", nullptr); + } + break; + } + case CLASS_DRUID: { + if (tab == DRUID_TAB_RESTORATION) { + engine->addStrategies("caster", "caster aoe", nullptr); + engine->addStrategy("caster debuff"); + } + break; + } + case CLASS_SHAMAN: { + if (tab == SHAMAN_TAB_RESTORATION) { + engine->addStrategies("caster", "caster aoe", "bmana", nullptr); + } + break; + } + case CLASS_PALADIN: { + if (tab == PALADIN_TAB_HOLY) { + engine->addStrategies("dps", "dps assist", "baoe", nullptr); + } + break; + } + default: + break; } } } diff --git a/src/RandomPlayerbotFactory.cpp b/src/RandomPlayerbotFactory.cpp index da56c955..59fc40cf 100644 --- a/src/RandomPlayerbotFactory.cpp +++ b/src/RandomPlayerbotFactory.cpp @@ -227,6 +227,13 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender) } fields = result->Fetch(); std::string ret = fields[0].Get(); + // check name limitations + if (ObjectMgr::CheckPlayerName(ret) != CHAR_NAME_SUCCESS || + (sObjectMgr->IsReservedName(ret) || sObjectMgr->IsProfanityName(ret))) + { + continue; + } + if (ret.size()) { CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use=1 WHERE name='{}'", ret); } diff --git a/src/strategy/druid/CasterDruidStrategy.cpp b/src/strategy/druid/CasterDruidStrategy.cpp index e6e24b9c..0b2a55e2 100644 --- a/src/strategy/druid/CasterDruidStrategy.cpp +++ b/src/strategy/druid/CasterDruidStrategy.cpp @@ -122,7 +122,7 @@ void CasterDruidStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("eclipse (lunar)", NextAction::array(0, new NextAction("starfire", ACTION_NORMAL + 6), nullptr))); triggers.push_back(new TriggerNode("moonfire", NextAction::array(0, new NextAction("moonfire", ACTION_NORMAL + 4), nullptr))); triggers.push_back(new TriggerNode("medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), NULL))); - triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", 49.0f), NULL))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode( "party member remove curse", NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL))); diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index 36086394..cb386529 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -75,7 +75,5 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) "medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), NULL))); - triggers.push_back(new TriggerNode( - "enemy too close for spell", - NextAction::array(0, new NextAction("flee", 49.0f), NULL))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); } diff --git a/src/strategy/generic/CombatStrategy.cpp b/src/strategy/generic/CombatStrategy.cpp index 96b65e59..7781ebbc 100644 --- a/src/strategy/generic/CombatStrategy.cpp +++ b/src/strategy/generic/CombatStrategy.cpp @@ -12,6 +12,7 @@ void CombatStrategy::InitTriggers(std::vector &triggers) triggers.push_back(new TriggerNode("mounted", NextAction::array(0, new NextAction("check mount state", 54), nullptr))); // triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", 55), nullptr))); triggers.push_back(new TriggerNode("combat stuck", NextAction::array(0, new NextAction("reset", 1.0f), nullptr))); + triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_MOVE + 7), nullptr))); // triggers.push_back(new TriggerNode("combat long stuck", NextAction::array(0, new NextAction("hearthstone", 0.9f), new NextAction("repop", 0.8f), nullptr))); } diff --git a/src/strategy/generic/MeleeCombatStrategy.cpp b/src/strategy/generic/MeleeCombatStrategy.cpp index d59b2990..baf7062d 100644 --- a/src/strategy/generic/MeleeCombatStrategy.cpp +++ b/src/strategy/generic/MeleeCombatStrategy.cpp @@ -9,9 +9,9 @@ void MeleeCombatStrategy::InitTriggers(std::vector &triggers) { CombatStrategy::InitTriggers(triggers); - triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_MOVE + 7), nullptr))); + // triggers.push_back(new TriggerNode("not facing target", NextAction::array(0, new NextAction("set facing", ACTION_MOVE + 7), nullptr))); triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_MOVE + 8), nullptr))); - triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); + // triggers.push_back(new TriggerNode("enemy too close for melee", NextAction::array(0, new NextAction("move out of enemy contact", ACTION_NORMAL + 8), nullptr))); } void SetBehindCombatStrategy::InitTriggers(std::vector &triggers) diff --git a/src/strategy/generic/RpgStrategy.cpp b/src/strategy/generic/RpgStrategy.cpp index b5941084..46ebfd25 100644 --- a/src/strategy/generic/RpgStrategy.cpp +++ b/src/strategy/generic/RpgStrategy.cpp @@ -39,7 +39,7 @@ void RpgStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("rpg", NextAction::array(0, new NextAction("rpg work", 1.001f), nullptr))); triggers.push_back(new TriggerNode("rpg", NextAction::array(0, new NextAction("rpg emote", 1.001f), nullptr))); triggers.push_back(new TriggerNode("has rpg target", NextAction::array(0, new NextAction("rpg cancel", 1.001f), nullptr))); - triggers.push_back(new TriggerNode("rpg taxi", NextAction::array(0, new NextAction("rpg taxi", 1.005f), nullptr))); + // triggers.push_back(new TriggerNode("rpg taxi", NextAction::array(0, new NextAction("rpg taxi", 1.005f), nullptr))); triggers.push_back(new TriggerNode("rpg discover", NextAction::array(0, new NextAction("rpg discover", 1.110f), nullptr))); triggers.push_back(new TriggerNode("rpg start quest", NextAction::array(0, new NextAction("rpg start quest", 1.080f), nullptr))); triggers.push_back(new TriggerNode("rpg end quest", NextAction::array(0, new NextAction("rpg end quest", 1.090f), nullptr))); diff --git a/src/strategy/hunter/GenericHunterStrategy.cpp b/src/strategy/hunter/GenericHunterStrategy.cpp index fb9fee00..84bfcdfb 100644 --- a/src/strategy/hunter/GenericHunterStrategy.cpp +++ b/src/strategy/hunter/GenericHunterStrategy.cpp @@ -78,7 +78,7 @@ void GenericHunterStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_HIGH + 3), NULL))); triggers.push_back(new TriggerNode("misdirection on main tank", NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL))); triggers.push_back(new TriggerNode("tranquilizing shot", NextAction::array(0, new NextAction("tranquilizing shot", 61.0f), NULL))); - + } NextAction** HunterBoostStrategy::getDefaultActions() diff --git a/src/strategy/mage/GenericMageStrategy.cpp b/src/strategy/mage/GenericMageStrategy.cpp index 41535cb7..083b1ccb 100644 --- a/src/strategy/mage/GenericMageStrategy.cpp +++ b/src/strategy/mage/GenericMageStrategy.cpp @@ -131,6 +131,7 @@ void GenericMageStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("evocation", ACTION_EMERGENCY + 5), nullptr))); triggers.push_back(new TriggerNode("fire ward", NextAction::array(0, new NextAction("fire ward", ACTION_EMERGENCY), nullptr))); triggers.push_back(new TriggerNode("frost ward", NextAction::array(0, new NextAction("frost ward", ACTION_EMERGENCY), nullptr))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); } void MageCureStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/paladin/HealPaladinStrategy.cpp b/src/strategy/paladin/HealPaladinStrategy.cpp index ec7eda15..8d12389e 100644 --- a/src/strategy/paladin/HealPaladinStrategy.cpp +++ b/src/strategy/paladin/HealPaladinStrategy.cpp @@ -70,4 +70,6 @@ void HealPaladinStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode( "sacred shield on main tank", NextAction::array(0, new NextAction("sacred shield on main tank", ACTION_CRITICAL_HEAL + 6), NULL))); + + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); } diff --git a/src/strategy/priest/GenericPriestStrategy.cpp b/src/strategy/priest/GenericPriestStrategy.cpp index 17ed3d2f..f0a4b5fd 100644 --- a/src/strategy/priest/GenericPriestStrategy.cpp +++ b/src/strategy/priest/GenericPriestStrategy.cpp @@ -44,9 +44,7 @@ void GenericPriestStrategy::InitTriggers(std::vector& triggers) "low mana", NextAction::array(0, new NextAction("hymn of hope", ACTION_HIGH), NULL))); - triggers.push_back(new TriggerNode( - "enemy too close for spell", - NextAction::array(0, new NextAction("flee", 49.0f), NULL))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr))); } diff --git a/src/strategy/rogue/DpsRogueStrategy.cpp b/src/strategy/rogue/DpsRogueStrategy.cpp index e178645d..83a16c34 100644 --- a/src/strategy/rogue/DpsRogueStrategy.cpp +++ b/src/strategy/rogue/DpsRogueStrategy.cpp @@ -113,9 +113,13 @@ void DpsRogueStrategy::InitTriggers(std::vector& triggers) "light aoe", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), NULL))); - // triggers.push_back(new TriggerNode( - // "enemy out of melee", - // NextAction::array(0, new NextAction("stealth", ACTION_NORMAL + 9), new NextAction("reach melee", ACTION_NORMAL + 8), NULL))); + triggers.push_back(new TriggerNode( + "enemy out of melee", + NextAction::array(0, + new NextAction("stealth", ACTION_NORMAL + 9), + new NextAction("sprint", ACTION_NORMAL + 8), + new NextAction("reach melee", ACTION_NORMAL + 7), + NULL))); triggers.push_back(new TriggerNode( "expose armor", diff --git a/src/strategy/shaman/CasterShamanStrategy.cpp b/src/strategy/shaman/CasterShamanStrategy.cpp index 1c1fc431..8bba7502 100644 --- a/src/strategy/shaman/CasterShamanStrategy.cpp +++ b/src/strategy/shaman/CasterShamanStrategy.cpp @@ -57,9 +57,7 @@ void CasterShamanStrategy::InitTriggers(std::vector& triggers) "no fire totem", NextAction::array(0, new NextAction("totem of wrath", 15.0f), NULL))); - triggers.push_back(new TriggerNode( - "enemy too close for spell", - NextAction::array(0, new NextAction("flee", 49.0f), NULL))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); } void CasterAoeShamanStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/shaman/HealShamanStrategy.cpp b/src/strategy/shaman/HealShamanStrategy.cpp index d9103f42..ea9eee69 100644 --- a/src/strategy/shaman/HealShamanStrategy.cpp +++ b/src/strategy/shaman/HealShamanStrategy.cpp @@ -93,9 +93,7 @@ void HealShamanStrategy::InitTriggers(std::vector& triggers) "earth shield on main tank", NextAction::array(0, new NextAction("earth shield on main tank", ACTION_HIGH + 7), NULL))); - triggers.push_back(new TriggerNode( - "enemy too close for spell", - NextAction::array(0, new NextAction("flee", 49.0f), NULL))); + triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode( "medium mana", diff --git a/src/strategy/values/AttackersValue.cpp b/src/strategy/values/AttackersValue.cpp index d66b1dd1..b39d103e 100644 --- a/src/strategy/values/AttackersValue.cpp +++ b/src/strategy/values/AttackersValue.cpp @@ -150,6 +150,7 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float range) !attacker->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION) && // !(attacker->GetGUID().IsPet() && enemy) && !(attacker->GetCreatureType() == CREATURE_TYPE_CRITTER && !attacker->IsInCombat()) && !(sPlayerbotAIConfig->IsInPvpProhibitedZone(attacker->GetAreaId()) && + bot->CanSeeOrDetect(attacker) && (attacker->GetGUID().IsPlayer() || attacker->GetGUID().IsPet())) && (!c || (!c->IsInEvadeMode() && ((!isMemberBotGroup && botAI->HasStrategy("attack tagged", BOT_STATE_NON_COMBAT)) || leaderHasThreat || (!c->hasLootRecipient() && (!c->GetVictim() || (c->GetVictim() && ((!c->GetVictim()->IsPlayer() || bot->IsInSameGroupWith(c->GetVictim()->ToPlayer())) || (botAI->GetMaster() && c->GetVictim() == botAI->GetMaster()))))) || c->isTappedBy(bot)))); diff --git a/src/strategy/values/GrindTargetValue.cpp b/src/strategy/values/GrindTargetValue.cpp index b0d854a4..001db54c 100644 --- a/src/strategy/values/GrindTargetValue.cpp +++ b/src/strategy/values/GrindTargetValue.cpp @@ -53,7 +53,7 @@ Unit* GrindTargetValue::FindTargetForGrinding(uint32 assistCount) if (!unit) continue; - + if (!bot->IsHostileTo(unit) && unit->GetNpcFlags() != UNIT_NPC_FLAG_NONE) { continue; } diff --git a/src/strategy/warrior/GenericWarriorStrategy.cpp b/src/strategy/warrior/GenericWarriorStrategy.cpp index f0ffe3b8..405267b2 100644 --- a/src/strategy/warrior/GenericWarriorStrategy.cpp +++ b/src/strategy/warrior/GenericWarriorStrategy.cpp @@ -13,7 +13,7 @@ GenericWarriorStrategy::GenericWarriorStrategy(PlayerbotAI* botAI) : CombatStrat void GenericWarriorStrategy::InitTriggers(std::vector& triggers) { CombatStrategy::InitTriggers(triggers); - + triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("reach melee", ACTION_NORMAL + 8), nullptr))); /*triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("shield bash", NextAction::array(0, new NextAction("shield bash", ACTION_INTERRUPT + 4), nullptr))); triggers.push_back(new TriggerNode("shield bash on enemy healer", NextAction::array(0, new NextAction("shield bash on enemy healer", ACTION_INTERRUPT + 3), nullptr)));