From 6886a5bf2bbdc6eb6a87fe48e389b38926c6a813 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 3 Oct 2024 12:34:47 +0800 Subject: [PATCH] [Spell] Interruption healing spell if target with full health --- src/PlayerbotAI.cpp | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 816dd266..501d5a79 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -43,6 +43,7 @@ #include "SharedDefines.h" #include "SocialMgr.h" #include "SpellAuraEffects.h" +#include "SpellInfo.h" #include "Transport.h" #include "Unit.h" #include "UpdateTime.h" @@ -318,12 +319,43 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) currentSpell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL); if (currentSpell && currentSpell->getState() == SPELL_STATE_PREPARING) { + const SpellInfo* spellInfo = currentSpell->GetSpellInfo(); + + // interrupt if target is dead if (currentSpell->m_targets.GetUnitTarget() && !currentSpell->m_targets.GetUnitTarget()->IsAlive() && - currentSpell->GetSpellInfo() && !currentSpell->GetSpellInfo()->IsAllowingDeadTarget()) + spellInfo && !spellInfo->IsAllowingDeadTarget()) { - bot->InterruptSpell(CURRENT_GENERIC_SPELL); + InterruptSpell(); SetNextCheckDelay(sPlayerbotAIConfig->reactDelay); } + + bool isHeal = false; + bool isSingleTarget = true; + + for (uint8 i = 0; i < 3; ++i) + { + if (!spellInfo->Effects[i].Effect) + continue; + + if (spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL || + spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL_MAX_HEALTH || + spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL_MECHANICAL) + isHeal = true; + + if ((spellInfo->Effects[i].TargetA.GetTarget() && spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_TARGET_ALLY) || + (spellInfo->Effects[i].TargetB.GetTarget() && spellInfo->Effects[i].TargetB.GetTarget() != TARGET_UNIT_TARGET_ALLY)) + { + isSingleTarget = false; + } + } + // interrupt if target ally has full health (heal by other member) + if (isHeal && isSingleTarget && currentSpell->m_targets.GetUnitTarget() && currentSpell->m_targets.GetUnitTarget()->IsFullHealth()) + { + InterruptSpell(); + SetNextCheckDelay(sPlayerbotAIConfig->reactDelay); + } + + // wait for spell cast return; } @@ -3733,15 +3765,12 @@ void PlayerbotAI::WaitForSpellCast(Spell* spell) void PlayerbotAI::InterruptSpell() { - for (uint8 type = CURRENT_MELEE_SPELL; type < CURRENT_CHANNELED_SPELL; type++) + for (uint8 type = CURRENT_MELEE_SPELL; type <= CURRENT_CHANNELED_SPELL; type++) { Spell* spell = bot->GetCurrentSpell((CurrentSpellTypes)type); if (!spell) continue; - if (spell->m_spellInfo->IsPositive()) - continue; - bot->InterruptSpell((CurrentSpellTypes)type); WorldPacket data(SMSG_SPELL_FAILURE, 8 + 1 + 4 + 1);