fix: cast/cooldown/unit-cast timers ticked twice per frame

SpellHandler::updateTimers() (added in 209c2577) already ticks down
castTimeRemaining_, unitCastStates_, and spellCooldowns_. But the
GameHandler::update() loop also ticked them manually — causing casts to
complete at 2x speed and cooldowns to expire twice as fast.

Removed the duplicate tick-downs from update(). The GO interaction
completion check remains (client-timed casts need this fallback).
Also uses resetCastState() instead of manually clearing 4 fields,
adds missing castTimeTotal_ reset, and adds loadSpellNameCache()
to getSpellName/getSpellRank (every other DBC getter had it).
This commit is contained in:
Kelsi 2026-03-29 18:21:03 -07:00
parent fc2526fc18
commit b0aa4445a0
2 changed files with 19 additions and 40 deletions

View file

@ -1615,6 +1615,7 @@ void SpellHandler::resetCastState() {
castIsChannel_ = false;
currentCastSpellId_ = 0;
castTimeRemaining_ = 0.0f;
castTimeTotal_ = 0.0f; // Must match castTimeRemaining_ to keep getCastProgress() == 0
craftQueueSpellId_ = 0;
craftQueueRemaining_ = 0;
queuedSpellId_ = 0;
@ -1853,11 +1854,16 @@ float SpellHandler::getSpellDuration(uint32_t spellId) const {
}
const std::string& SpellHandler::getSpellName(uint32_t spellId) const {
// Lazy-load Spell.dbc so callers don't need to know about initialization order.
// Every other DBC-backed getter (getSpellDescription, getSpellSchoolMask, etc.)
// already does this; these two were missed.
loadSpellNameCache();
auto it = owner_.spellNameCache_.find(spellId);
return (it != owner_.spellNameCache_.end()) ? it->second.name : SPELL_EMPTY_STRING;
}
const std::string& SpellHandler::getSpellRank(uint32_t spellId) const {
loadSpellNameCache();
auto it = owner_.spellNameCache_.find(spellId);
return (it != owner_.spellNameCache_.end()) ? it->second.rank : SPELL_EMPTY_STRING;
}