diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 03ddbeb1..90d511e3 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -3717,6 +3717,9 @@ float PlayerbotAI::GetRange(std::string const type) if (type == "heal") return sPlayerbotAIConfig->healDistance; + if (type == "melee") + return sPlayerbotAIConfig->meleeDistance; + return 0; } diff --git a/src/strategy/actions/GenericSpellActions.cpp b/src/strategy/actions/GenericSpellActions.cpp index 6f108ad1..8b53ec7b 100644 --- a/src/strategy/actions/GenericSpellActions.cpp +++ b/src/strategy/actions/GenericSpellActions.cpp @@ -220,6 +220,11 @@ Value* CastDebuffSpellOnAttackerAction::GetTargetValue() return context->GetValue("attacker without aura", spell); } +Value* CastDebuffSpellOnMeleeAttackerAction::GetTargetValue() +{ + return context->GetValue("melee attacker without aura", spell); +} + CastBuffSpellAction::CastBuffSpellAction(PlayerbotAI* botAI, std::string const spell, bool checkIsOwner) : CastAuraSpellAction(botAI, spell, checkIsOwner) { range = botAI->GetRange("spell"); diff --git a/src/strategy/actions/GenericSpellActions.h b/src/strategy/actions/GenericSpellActions.h index d94532fb..95a8fb00 100644 --- a/src/strategy/actions/GenericSpellActions.h +++ b/src/strategy/actions/GenericSpellActions.h @@ -63,6 +63,16 @@ class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction ActionThreatType getThreatType() override { return ActionThreatType::Aoe; } }; +class CastDebuffSpellOnMeleeAttackerAction : public CastAuraSpellAction +{ + public: + CastDebuffSpellOnMeleeAttackerAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = true) : CastAuraSpellAction(botAI, spell, isOwner) { } + + Value* GetTargetValue() override; + std::string const getName() override { return spell + " on attacker"; } + ActionThreatType getThreatType() override { return ActionThreatType::Aoe; } +}; + class CastBuffSpellAction : public CastAuraSpellAction { public: diff --git a/src/strategy/deathknight/DKActions.h b/src/strategy/deathknight/DKActions.h index ff7407c6..b550be7d 100644 --- a/src/strategy/deathknight/DKActions.h +++ b/src/strategy/deathknight/DKActions.h @@ -104,20 +104,20 @@ class CastIcyTouchAction : public CastSpellAction CastIcyTouchAction(PlayerbotAI* ai) : CastSpellAction(ai, "icy touch") {} }; -class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnAttackerAction +class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction { public: - CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "icy touch", true) { } + CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "icy touch", true) { } }; //debuff ps BEGIN_DEBUFF_ACTION(CastPlagueStrikeAction, "plague strike") END_SPELL_ACTION() -class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnAttackerAction +class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction { public: - CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "plague strike", true) { } + CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "plague strike", true) { } }; //debuff diff --git a/src/strategy/deathknight/DKTriggers.h b/src/strategy/deathknight/DKTriggers.h index f588c98e..039dfbdf 100644 --- a/src/strategy/deathknight/DKTriggers.h +++ b/src/strategy/deathknight/DKTriggers.h @@ -15,16 +15,16 @@ BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons"); DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "blood plague"); DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever"); -class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger +class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger { public: - PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "blood plague", true) { } + PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "blood plague", true) { } }; -class IcyTouchDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger +class IcyTouchDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger { public: - IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "frost fever", true) { } + IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "frost fever", true) { } }; class DKPresenceTrigger : public BuffTrigger diff --git a/src/strategy/deathknight/GenericDKStrategy.cpp b/src/strategy/deathknight/GenericDKStrategy.cpp index 66928d39..c098ff76 100644 --- a/src/strategy/deathknight/GenericDKStrategy.cpp +++ b/src/strategy/deathknight/GenericDKStrategy.cpp @@ -169,9 +169,9 @@ void GenericDKStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5), new NextAction("rune tap", ACTION_HIGH + 4), nullptr))); triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("rune tap", ACTION_NORMAL + 4), new NextAction("death strike", ACTION_NORMAL + 3), nullptr))); triggers.push_back(new TriggerNode("icy touch", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr))); - // triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr))); + triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr))); - // triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr))); + triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("high aoe", NextAction::array(0, new NextAction("unholy blight", ACTION_HIGH + 6), new NextAction("death and decay", ACTION_NORMAL + 5), new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("death and decay", ACTION_HIGH + 9), diff --git a/src/strategy/mage/FrostMageStrategy.cpp b/src/strategy/mage/FrostMageStrategy.cpp index 2aef72af..77ee30eb 100644 --- a/src/strategy/mage/FrostMageStrategy.cpp +++ b/src/strategy/mage/FrostMageStrategy.cpp @@ -23,5 +23,5 @@ void FrostMageStrategy::InitTriggers(std::vector& triggers) void FrostMageAoeStrategy::InitTriggers(std::vector& triggers) { - triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr))); + triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr))); } diff --git a/src/strategy/priest/ShadowPriestStrategy.cpp b/src/strategy/priest/ShadowPriestStrategy.cpp index 0d65c443..f8416e96 100644 --- a/src/strategy/priest/ShadowPriestStrategy.cpp +++ b/src/strategy/priest/ShadowPriestStrategy.cpp @@ -44,8 +44,8 @@ void ShadowPriestAoeStrategy::InitTriggers(std::vector& triggers) void ShadowPriestDebuffStrategy::InitTriggers(std::vector& triggers) { triggers.push_back(new TriggerNode("devouring plague", NextAction::array(0, new NextAction("devouring plague", 13.0f), nullptr))); - triggers.push_back(new TriggerNode("vampiric touch", NextAction::array(0, new NextAction("vampiric touch", 11.0f), nullptr))); - triggers.push_back(new TriggerNode("shadow word: pain", NextAction::array(0, new NextAction("shadow word: pain", 12.0f), nullptr))); + triggers.push_back(new TriggerNode("shadow word: pain", NextAction::array(0, new NextAction("shadow word: pain", 11.0f), nullptr))); + triggers.push_back(new TriggerNode("vampiric touch", NextAction::array(0, new NextAction("vampiric touch", 12.0f), nullptr))); // triggers.push_back(new TriggerNode("feedback", NextAction::array(0, new NextAction("feedback", 80.0f), nullptr))); // triggers.push_back(new TriggerNode("hex of weakness", NextAction::array(0, new NextAction("hex of weakness", 10.0f), nullptr))); } diff --git a/src/strategy/triggers/GenericTriggers.cpp b/src/strategy/triggers/GenericTriggers.cpp index 7877ed8b..8948be16 100644 --- a/src/strategy/triggers/GenericTriggers.cpp +++ b/src/strategy/triggers/GenericTriggers.cpp @@ -136,6 +136,11 @@ Value* DebuffOnAttackerTrigger::GetTargetValue() return context->GetValue("attacker without aura", spell); } +Value* DebuffOnMeleeAttackerTrigger::GetTargetValue() +{ + return context->GetValue("melee attacker without aura", spell); +} + bool NoAttackersTrigger::IsActive() { return !AI_VALUE(Unit*, "current target") && AI_VALUE(uint8, "my attacker count") > 0; diff --git a/src/strategy/triggers/GenericTriggers.h b/src/strategy/triggers/GenericTriggers.h index b25965de..f0366025 100644 --- a/src/strategy/triggers/GenericTriggers.h +++ b/src/strategy/triggers/GenericTriggers.h @@ -330,6 +330,15 @@ class DebuffOnAttackerTrigger : public DebuffTrigger std::string const getName() override { return spell + " on attacker"; } }; +class DebuffOnMeleeAttackerTrigger : public DebuffTrigger +{ + public: + DebuffOnMeleeAttackerTrigger(PlayerbotAI* botAI, std::string const spell, bool checkIsOwner = true) : DebuffTrigger(botAI, spell, 1, checkIsOwner) { } + + Value* GetTargetValue() override; + std::string const getName() override { return spell + " on attacker"; } +}; + class BoostTrigger : public BuffTrigger { public: diff --git a/src/strategy/values/AttackerWithoutAuraTargetValue.cpp b/src/strategy/values/AttackerWithoutAuraTargetValue.cpp index 481f3e0f..93664712 100644 --- a/src/strategy/values/AttackerWithoutAuraTargetValue.cpp +++ b/src/strategy/values/AttackerWithoutAuraTargetValue.cpp @@ -8,19 +8,27 @@ Unit* AttackerWithoutAuraTargetValue::Calculate() { GuidVector attackers = botAI->GetAiObjectContext()->GetValue("attackers")->Get(); - Unit* target = botAI->GetAiObjectContext()->GetValue("current target")->Get(); + // Unit* target = botAI->GetAiObjectContext()->GetValue("current target")->Get(); + uint32 max_health = 0; + Unit* result = nullptr; for (ObjectGuid const guid : attackers) { Unit* unit = botAI->GetUnit(guid); - if (!unit || unit == target) + if (!unit || !unit->IsAlive()) continue; - if (bot->GetDistance(unit) > botAI->GetRange("spell")) + if (bot->GetDistance(unit) > botAI->GetRange(range)) continue; - if (!botAI->HasAura(qualifier, unit, false, true)) - return unit; + if (unit->GetHealth() < max_health) { + continue; + } + + if (!botAI->HasAura(qualifier, unit, false, true)) { + max_health = unit->GetHealth(); + result = unit; + } } - return nullptr; + return result; } diff --git a/src/strategy/values/AttackerWithoutAuraTargetValue.h b/src/strategy/values/AttackerWithoutAuraTargetValue.h index 2d84b9ce..66e3b891 100644 --- a/src/strategy/values/AttackerWithoutAuraTargetValue.h +++ b/src/strategy/values/AttackerWithoutAuraTargetValue.h @@ -14,10 +14,17 @@ class Unit; class AttackerWithoutAuraTargetValue : public UnitCalculatedValue, public Qualified { public: - AttackerWithoutAuraTargetValue(PlayerbotAI* botAI) : UnitCalculatedValue(botAI, "attacker without aura") { } + AttackerWithoutAuraTargetValue(PlayerbotAI* botAI, std::string range = "spell") : UnitCalculatedValue(botAI, "attacker without aura"), range(range) { } protected: Unit* Calculate() override; + std::string range; +}; + +class MeleeAttackerWithoutAuraTargetValue : public AttackerWithoutAuraTargetValue +{ + public: + MeleeAttackerWithoutAuraTargetValue(PlayerbotAI* botAI) : AttackerWithoutAuraTargetValue(botAI, "melee") {} }; #endif diff --git a/src/strategy/values/ValueContext.h b/src/strategy/values/ValueContext.h index c8db899a..694bce5a 100644 --- a/src/strategy/values/ValueContext.h +++ b/src/strategy/values/ValueContext.h @@ -116,6 +116,7 @@ class ValueContext : public NamedObjectContext creators["log level"] = &ValueContext::log_level; creators["party member without aura"] = &ValueContext::party_member_without_aura; creators["attacker without aura"] = &ValueContext::attacker_without_aura; + creators["melee attacker without aura"] = &ValueContext::melee_attacker_without_aura; creators["party member to heal"] = &ValueContext::party_member_to_heal; creators["party member to resurrect"] = &ValueContext::party_member_to_resurrect; creators["current target"] = &ValueContext::current_target; @@ -376,6 +377,7 @@ class ValueContext : public NamedObjectContext static UntypedValue* nearest_adds(PlayerbotAI* botAI) { return new NearestAddsValue(botAI); } static UntypedValue* party_member_without_aura(PlayerbotAI* botAI) { return new PartyMemberWithoutAuraValue(botAI); } static UntypedValue* attacker_without_aura(PlayerbotAI* botAI) { return new AttackerWithoutAuraTargetValue(botAI); } + static UntypedValue* melee_attacker_without_aura(PlayerbotAI* botAI) { return new MeleeAttackerWithoutAuraTargetValue(botAI); } static UntypedValue* party_member_to_heal(PlayerbotAI* botAI) { return new PartyMemberToHeal(botAI); } static UntypedValue* party_member_to_resurrect(PlayerbotAI* botAI) { return new PartyMemberToResurrect(botAI); } static UntypedValue* party_member_to_dispel(PlayerbotAI* botAI) { return new PartyMemberToDispel(botAI); } diff --git a/src/strategy/warrior/ArmsWarriorStrategy.cpp b/src/strategy/warrior/ArmsWarriorStrategy.cpp index ab321df6..4643ff63 100644 --- a/src/strategy/warrior/ArmsWarriorStrategy.cpp +++ b/src/strategy/warrior/ArmsWarriorStrategy.cpp @@ -54,5 +54,6 @@ void ArmsWarriorStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_HIGH + 5), nullptr))); + triggers.push_back(new TriggerNode("rend on attacker", NextAction::array(0, new NextAction("rend on attacker", ACTION_HIGH + 5), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr))); } diff --git a/src/strategy/warrior/TankWarriorStrategy.cpp b/src/strategy/warrior/TankWarriorStrategy.cpp index bfb1358d..94af0fcc 100644 --- a/src/strategy/warrior/TankWarriorStrategy.cpp +++ b/src/strategy/warrior/TankWarriorStrategy.cpp @@ -78,5 +78,6 @@ void TankWarriorStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("sword and board", NextAction::array(0, new NextAction("shield slam", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_NORMAL + 1), nullptr))); + triggers.push_back(new TriggerNode("rend on attacker", NextAction::array(0, new NextAction("rend on attacker", ACTION_NORMAL + 1), nullptr))); triggers.push_back(new TriggerNode("protect party member", NextAction::array(0, new NextAction("intervene", ACTION_EMERGENCY), nullptr))); } diff --git a/src/strategy/warrior/WarriorActions.h b/src/strategy/warrior/WarriorActions.h index 099e1ce3..bb89f439 100644 --- a/src/strategy/warrior/WarriorActions.h +++ b/src/strategy/warrior/WarriorActions.h @@ -28,7 +28,14 @@ BUFF_ACTION(CastCommandingShoutAction, "commanding shout"); MELEE_ACTION(CastHeroicStrikeAction, "heroic strike"); REACH_ACTION(CastChargeAction, "charge", 8.0f); DEBUFF_CHECKISOWNER_ACTION(CastRendAction, "rend"); -DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend"); +// DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend"); + +class CastRendOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction +{ + public: + CastRendOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "rend") {} +}; + DEBUFF_ACTION_R(CastThunderClapAction, "thunder clap", 8.0f); SNARE_ACTION(CastThunderClapSnareAction, "thunder clap"); SNARE_ACTION(CastHamstringAction, "hamstring"); diff --git a/src/strategy/warrior/WarriorTriggers.h b/src/strategy/warrior/WarriorTriggers.h index 37ed51eb..a6d72fe3 100644 --- a/src/strategy/warrior/WarriorTriggers.h +++ b/src/strategy/warrior/WarriorTriggers.h @@ -6,6 +6,7 @@ #define _PLAYERBOT_WARRIORTRIGGERS_H #include "GenericTriggers.h" +#include "PlayerbotAI.h" BUFF_TRIGGER(BattleShoutTrigger, "battle shout"); BUFF_TRIGGER(BattleStanceTrigger, "battle stance"); @@ -16,7 +17,14 @@ BUFF_TRIGGER(CommandingShoutTrigger, "commanding shout"); DEBUFF_TRIGGER(DisarmDebuffTrigger, "disarm"); DEBUFF_TRIGGER(SunderArmorDebuffTrigger, "sunder armor"); DEBUFF_TRIGGER(MortalStrikeDebuffTrigger, "mortal strike"); -DEBUFF_ENEMY_TRIGGER(RendDebuffOnAttackerTrigger, "rend"); +// DEBUFF_ENEMY_TRIGGER(RendDebuffOnAttackerTrigger, "rend"); + +class RendDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger +{ + public: + RendDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "rend") {} +}; + CAN_CAST_TRIGGER(RevengeAvailableTrigger, "revenge"); CAN_CAST_TRIGGER(OverpowerAvailableTrigger, "overpower"); BUFF_TRIGGER(RampageAvailableTrigger, "rampage");