Core/Spells: Fixed npcs channeling spells with SPELL_ATTR5_ALLOW_ACTIONS_DURING_CHANNEL being prevented from casting other spells during that time
This commit is contained in:
@@ -2192,11 +2192,7 @@ void Unit::DoMeleeAttackIfReady()
|
||||
return;
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
Spell* channeledSpell = GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
if (!channeledSpell || !channeledSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_ALLOW_ACTIONS_DURING_CHANNEL))
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
Unit* victim = GetVictim();
|
||||
if (!victim)
|
||||
@@ -3127,7 +3123,9 @@ void Unit::SetCurrentCastSpell(Spell* pSpell)
|
||||
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] &&
|
||||
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetSpellInfo()->Id != 75)
|
||||
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
|
||||
AddUnitState(UNIT_STATE_CASTING);
|
||||
|
||||
if (!pSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_ALLOW_ACTIONS_DURING_CHANNEL))
|
||||
AddUnitState(UNIT_STATE_CASTING);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -3204,7 +3202,8 @@ void Unit::FinishSpell(CurrentSpellTypes spellType, SpellCastResult result /*= S
|
||||
spell->finish(result);
|
||||
}
|
||||
|
||||
bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAutorepeat, bool isAutoshoot, bool skipInstant) const
|
||||
bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled /*= false*/, bool skipAutorepeat /*= false*/, bool isAutoshoot /*= false*/,
|
||||
bool skipInstant /*= true*/, bool skipChanneledAllowingActions /*= false*/) const
|
||||
{
|
||||
// We don't do loop here to explicitly show that melee spell is excluded.
|
||||
// Maybe later some special spells will be excluded too.
|
||||
@@ -3216,7 +3215,7 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu
|
||||
{
|
||||
if (!skipInstant || m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
|
||||
{
|
||||
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)))
|
||||
if (!isAutoshoot || !m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3224,7 +3223,8 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu
|
||||
if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
|
||||
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED))
|
||||
{
|
||||
if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)))
|
||||
if ((!isAutoshoot || !m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)) &&
|
||||
(!skipChanneledAllowingActions || !m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->HasAttribute(SPELL_ATTR5_ALLOW_ACTIONS_DURING_CHANNEL)))
|
||||
return true;
|
||||
}
|
||||
// autorepeat spells may be finished or delayed, but they are still considered cast
|
||||
@@ -3266,23 +3266,19 @@ int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const
|
||||
|
||||
bool Unit::IsMovementPreventedByCasting() const
|
||||
{
|
||||
// can always move when not casting
|
||||
if (!HasUnitState(UNIT_STATE_CASTING))
|
||||
return false;
|
||||
|
||||
if (Spell* spell = m_currentSpells[CURRENT_GENERIC_SPELL])
|
||||
if (CanCastSpellWhileMoving(spell->GetSpellInfo()) || spell->getState() == SPELL_STATE_FINISHED ||
|
||||
!spell->m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement))
|
||||
return false;
|
||||
if (!CanCastSpellWhileMoving(spell->GetSpellInfo())
|
||||
&& spell->getState() == SPELL_STATE_PREPARING && spell->m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement))
|
||||
return true;
|
||||
|
||||
// channeled spells during channel stage (after the initial cast timer) allow movement with a specific spell attribute
|
||||
// channeled spells during channel stage (after the initial cast timer) allow movement without Moving channel interrupt flag
|
||||
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
|
||||
if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
|
||||
if (spell->GetSpellInfo()->IsMoveAllowedChannel() || CanCastSpellWhileMoving(spell->GetSpellInfo()))
|
||||
return false;
|
||||
if (!CanCastSpellWhileMoving(spell->GetSpellInfo())
|
||||
&& ((spell->getState() == SPELL_STATE_PREPARING && spell->m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement))
|
||||
|| spell->getState() == SPELL_STATE_CHANNELING && !spell->GetSpellInfo()->IsMoveAllowedChannel()))
|
||||
return true;
|
||||
|
||||
// prohibit movement for all other spell casts
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Unit::CanCastSpellWhileMoving(SpellInfo const* spellInfo) const
|
||||
|
||||
@@ -1471,7 +1471,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
// set withDelayed to true to account delayed spells as cast
|
||||
// delayed+channeled spells are always accounted as cast
|
||||
// we can skip channeled or delayed checks using flags
|
||||
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false, bool isAutoshoot = false, bool skipInstant = true) const;
|
||||
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false, bool isAutoshoot = false,
|
||||
bool skipInstant = true, bool skipChanneledAllowingActions = false) const;
|
||||
|
||||
// set withDelayed to true to interrupt delayed spells too
|
||||
// delayed+channeled spells are always interrupted
|
||||
|
||||
@@ -3932,7 +3932,7 @@ void Spell::_cast(bool skipCheck)
|
||||
SetDelayStart(0);
|
||||
|
||||
if (Unit* unitCaster = m_caster->ToUnit())
|
||||
if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
|
||||
if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true, false, true, true))
|
||||
unitCaster->ClearUnitState(UNIT_STATE_CASTING);
|
||||
}
|
||||
else
|
||||
@@ -4376,7 +4376,7 @@ void Spell::finish(SpellCastResult result)
|
||||
if (m_spellInfo->IsChanneled())
|
||||
unitCaster->UpdateInterruptMask();
|
||||
|
||||
if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
|
||||
if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true, false, true, true))
|
||||
unitCaster->ClearUnitState(UNIT_STATE_CASTING);
|
||||
|
||||
// Unsummon summon as possessed creatures on spell cancel
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
* Combat timers requires to be revisited, mainly player class abilities, half of timers are guessed
|
||||
* Move spell script of spell 43421 to this file
|
||||
* Currently we generate random companions after every wipe, doubt it is correct
|
||||
* We interrupt Siphon Soul instantly to allow casting player class abilities, that's a hack
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
@@ -359,7 +358,6 @@ struct boss_hexlord_malacrass : public BossAI
|
||||
break;
|
||||
case SPELL_SIPHON_SOUL:
|
||||
Talk(SAY_CHARM);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
break;
|
||||
case SPELL_DRAIN_POWER:
|
||||
Talk(SAY_DRAIN_POWER);
|
||||
|
||||
Reference in New Issue
Block a user