Core/SAI: Fix creatures casting with flag SMARTCAST_COMBAT_MOVE not switching to melee when the school of the spell they are trying to cast gets silenced (and other cases of spell failure) (#25226)

* Core/SAI: Fix creatures casting with flag SMARTCAST_COMBAT_MOVE not switching to melee when the school of the spell they are trying to cast gets silenced (and other cases of spell failure)

* Core/SAI: Retry casting after 500ms if a cast failed

Fixes #24914

(cherry picked from commit 63a6e1e048)
This commit is contained in:
Giacomo Pozzoni
2020-08-09 19:24:15 +00:00
committed by Shauren
parent 26894508ef
commit e11e1938b5
@@ -566,43 +566,17 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
me->InterruptNonMeleeSpells(false);
SpellCastResult result = me->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);
bool spellCastFailed = (result != SPELL_CAST_OK && result != SPELL_FAILED_SPELL_IN_PROGRESS);
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
{
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
bool allowMove = false;
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(e.action.cast.spell, me->GetMap()->GetDifficultyID());
std::vector<SpellPowerCost> costs = spellInfo->CalcPowerCost(me, spellInfo->GetSchoolMask());
bool hasPower = true;
for (SpellPowerCost const& cost : costs)
{
if (cost.Power == POWER_HEALTH)
{
if (me->GetHealth() <= uint32(cost.Amount))
{
hasPower = false;
break;
}
}
else
{
if (me->GetPower(cost.Power) < cost.Amount)
{
hasPower = false;
break;
}
}
}
if (me->GetDistance(target) > spellInfo->GetMaxRange(true) || me->GetDistance(target) < spellInfo->GetMinRange(true) ||
!me->IsWithinLOSInMap(target) ||
!hasPower ||
me->HasUnitFlag(UNIT_FLAG_SILENCED))
allowMove = true;
ENSURE_AI(SmartAI, me->AI())->SetCombatMove(allowMove, true);
ENSURE_AI(SmartAI, me->AI())->SetCombatMove(spellCastFailed, true);
}
me->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);
if (spellCastFailed)
RecalcTimer(e, 500, 500);
}
else if (go)
go->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);