From 310f856932609c777985ea797b649e8d8fbd0440 Mon Sep 17 00:00:00 2001 From: KiK0 Date: Tue, 27 Apr 2021 06:54:58 -0700 Subject: [PATCH] fix(Core/Spells): Do not allow the use of the master's call while the pet is controlled [port from TC] (#5273) --- src/server/game/Spells/Spell.cpp | 13 ----- src/server/scripts/Spells/spell_hunter.cpp | 57 ++++++++++++++++------ 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7bf84ae74..87e68a1d6 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5572,19 +5572,6 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_NOT_DEAD; } } - else if (m_spellInfo->Id == 53271) // Master's Call - { - if (!m_caster->ToPlayer()) - return SPELL_FAILED_BAD_TARGETS; - - Unit* target = m_targets.GetUnitTarget(); - Pet* pet = m_caster->ToPlayer()->GetPet(); - if (!target || !pet || pet->isDead() || target->isDead()) - return SPELL_FAILED_BAD_TARGETS; - - if (!pet->IsWithinLOSInMap(target, LINEOFSIGHT_ALL_CHECKS)) - return SPELL_FAILED_LINE_OF_SIGHT; - } break; } case SPELL_EFFECT_LEARN_SPELL: diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index e1af0e4e8..c0f46d674 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -691,27 +691,54 @@ public: return ValidateSpellInfo({ SPELL_HUNTER_MASTERS_CALL_TRIGGERED }); } + SpellCastResult DoCheckCast() + { + Guardian* pet = GetCaster()->ToPlayer()->GetGuardianPet(); + ASSERT(pet); // checked in Spell::CheckCast + + if (!pet->IsPet() || !pet->IsAlive()) + return SPELL_FAILED_NO_PET; + + // Do a mini Spell::CheckCasterAuras on the pet, no other way of doing this + SpellCastResult result = SPELL_CAST_OK; + uint32 const unitflag = pet->GetUInt32Value(UNIT_FIELD_FLAGS); + if (pet->GetCharmerGUID()) + result = SPELL_FAILED_CHARMED; + else if (unitflag & UNIT_FLAG_STUNNED) + result = SPELL_FAILED_STUNNED; + else if (unitflag & UNIT_FLAG_FLEEING) + result = SPELL_FAILED_FLEEING; + else if (unitflag & UNIT_FLAG_CONFUSED) + result = SPELL_FAILED_CONFUSED; + + if (result != SPELL_CAST_OK) + return result; + + Unit* target = GetExplTargetUnit(); + if (!target) + return SPELL_FAILED_BAD_TARGETS; + + if (!pet->IsWithinLOSInMap(target)) + return SPELL_FAILED_LINE_OF_SIGHT; + + return SPELL_CAST_OK; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->ToPlayer()->GetPet()->CastSpell(GetHitUnit(), GetEffectValue(), true); + } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetHitUnit()) - { - // Cannot be processed while pet is dead - TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE); - //target->CastSpell(target, GetEffectValue(), castMask); - target->CastSpell(target, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, castMask); - // there is a possibility that this effect should access effect 0 (dummy) target, but i dubt that - // it's more likely that on on retail it's possible to call target selector based on dbc values - // anyways, we're using GetExplTargetUnit() here and it's ok - if (Unit* ally = GetExplTargetUnit()) - { - //target->CastSpell(ally, GetEffectValue(), castMask); - target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask); - } - } + GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, true); } void Register() override { + OnCheckCast += SpellCheckCastFn(spell_hun_masters_call_SpellScript::DoCheckCast); + + OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } };