aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-05-08 15:54:15 +0200
committerShauren <shauren.trinity@gmail.com>2022-05-08 15:54:15 +0200
commitde592386dcd6ac85feb11d2af85538d62c192696 (patch)
tree07f45b6f56f591408263e8efed672dec74c942d7 /src/server/game/Spells/Spell.cpp
parent538fa8e97ff4b4e36a59e37fd74ea8958e6e30d2 (diff)
Core/Spells: Autorepeat casting fixes
* Fixed cast bars of ranged spells not disappearing when canceled while autoshooting * Replaced hacky 500ms delay on non auto shot autorepeat spells with native spell cast time (wands have 500ms cast time) * Update cooldowns before attempting to cast autorepeat spells (for cases when cooldown ends on the same server tick as cast attempt)
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e207befbf55..1283068269b 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3338,7 +3338,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const& targets, AuraEffect const
// handle just the general SPELL_FAILED_BAD_TARGETS result which is the default result for most DBC target checks
if (_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_CHECK && result == SPELL_FAILED_BAD_TARGETS)
result = SPELL_CAST_OK;
- if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
+ if (result != SPELL_CAST_OK)
{
// Periodic auras should be interrupted when aura triggers a spell which can't be cast
// for example bladestorm aura should be removed on disarm as of patch 3.3.5
@@ -3355,6 +3355,10 @@ SpellCastResult Spell::prepare(SpellCastTargets const& targets, AuraEffect const
else
SendCastResult(result);
+ // queue autorepeat spells for future repeating
+ if (GetCurrentContainer() == CURRENT_AUTOREPEAT_SPELL && m_caster->IsUnit())
+ m_caster->ToUnit()->SetCurrentCastSpell(this);
+
finish(false);
return result;
}
@@ -4084,6 +4088,9 @@ void Spell::SendSpellCooldown()
m_caster->ToUnit()->GetSpellHistory()->HandleCooldowns(m_spellInfo, m_CastItem, this);
else
m_caster->ToUnit()->GetSpellHistory()->HandleCooldowns(m_spellInfo, m_castItemEntry, this);
+
+ if (IsAutoRepeat())
+ m_caster->ToUnit()->resetAttackTimer(RANGED_ATTACK);
}
void Spell::update(uint32 difftime)
@@ -4126,7 +4133,7 @@ void Spell::update(uint32 difftime)
m_timer -= difftime;
}
- if (m_timer == 0 && !m_spellInfo->IsNextMeleeSwingSpell() && !IsAutoRepeat())
+ if (m_timer == 0 && !m_spellInfo->IsNextMeleeSwingSpell())
// don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
cast(!m_casttime);
break;
@@ -4186,6 +4193,10 @@ void Spell::finish(bool ok)
if (!unitCaster)
return;
+ // successful cast of the initial autorepeat spell is moved to idle state so that it is not deleted as long as autorepeat is active
+ if (IsAutoRepeat() && unitCaster->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) == this)
+ m_spellState = SPELL_STATE_IDLE;
+
if (m_spellInfo->IsChanneled())
unitCaster->UpdateInterruptMask();
@@ -5464,12 +5475,18 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
return SPELL_FAILED_NOT_READY;
}
- if (!IsIgnoringCooldowns() && m_caster->ToUnit() && !m_caster->ToUnit()->GetSpellHistory()->IsReady(m_spellInfo, m_castItemEntry))
+ if (!IsIgnoringCooldowns() && m_caster->ToUnit())
{
- if (m_triggeredByAuraSpell)
+ if (!m_caster->ToUnit()->GetSpellHistory()->IsReady(m_spellInfo, m_castItemEntry))
+ {
+ if (m_triggeredByAuraSpell)
+ return SPELL_FAILED_DONT_REPORT;
+ else
+ return SPELL_FAILED_NOT_READY;
+ }
+
+ if ((IsAutoRepeat() || m_spellInfo->CategoryId == 76) && !m_caster->ToUnit()->isAttackReady(RANGED_ATTACK))
return SPELL_FAILED_DONT_REPORT;
- else
- return SPELL_FAILED_NOT_READY;
}
}