Take takes the implementation of Mangos core One Unit::IsNonMeleeSpellCasted() and use it in Mangos core Zero. (#161)

I don't think this is a proper fix, but it does allow a frost bolt to be cast while the previous one is in flight to the target, and the mobs still cast their spells as expected.

With this cahnge it appears the warlock imp now casts fireballs, where it was only doing melee before, but it is casting them way too fast so I don't think this is a complete fix.

This in regards to this bug in the tracker: https://www.getmangos.eu/bug-tracker/mangos-zero/unable-to-cast-next-frost-bolt-while-current-one-is-traveling-r1726/
This commit is contained in:
Booji 2021-11-16 16:39:29 -05:00 committed by GitHub
parent 0b30838d20
commit 53a6a9d176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3732,52 +3732,30 @@ bool Unit::IsClientControlled(Player const* exactClient /*= nullptr*/) const
bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skipAutorepeat, bool forMovement, bool forAutoIgnore) const
{
// We don't do loop here to explicitly show that melee spell is excluded.
// Maybe later some special spells will be excluded too.
// Maybe later some special spells will be excluded too.
// generic spells are casted when they are not finished and not delayed
if (Spell const* genericSpell = m_currentSpells[CURRENT_GENERIC_SPELL])
{
if (genericSpell->getState() != SPELL_STATE_FINISHED)
// generic spells are casted when they are not finished and not delayed
if (m_currentSpells[CURRENT_GENERIC_SPELL] &&
(m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) &&
(withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED))
{
bool specialResult = true;
if (forMovement) // mobs can move during spells without this flag
{
specialResult = genericSpell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT;
}
bool isAutoNonInterrupting = forAutoIgnore && genericSpell->m_spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_RESET_AUTO_ACTIONS);
if (!isAutoNonInterrupting && specialResult && (withDelayed || genericSpell->getState() != SPELL_STATE_TRAVELING))
{
return true;
}
return true;
}
}
// channeled spells may be delayed, but they are still considered casted
if (!skipChanneled)
{
if (Spell const* channeledSpell = m_currentSpells[CURRENT_CHANNELED_SPELL])
{
bool attributeResult = false;
if (!forMovement)
{
attributeResult = channeledSpell->m_spellInfo->HasAttribute(SPELL_ATTR_EX4_CAN_CAST_WHILE_CASTING);
}
bool isAutoNonInterrupting = forAutoIgnore && channeledSpell->m_spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_RESET_AUTO_ACTIONS);
if (!isAutoNonInterrupting && !attributeResult && !channeledSpell->IsTriggered() && (channeledSpell->getState() != SPELL_STATE_FINISHED))
{
return true;
}
}
}
// autorepeat spells may be finished or delayed, but they are still considered casted
if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
else if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED))
{
return true;
}
return forAutoIgnore;
// autorepeat spells may be finished or delayed, but they are still considered casted
else if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
{
return true;
}
return false;
}
void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id)