feat: add UnitCastingInfo/UnitChannelInfo Lua API and fix SMSG_CAST_FAILED events

Expose cast/channel state to Lua addons via UnitCastingInfo(unit) and
UnitChannelInfo(unit), matching the WoW API signature (name, text, texture,
startTime, endTime, isTradeSkill, castID, notInterruptible). Works for
player, target, focus, and pet units using existing UnitCastState tracking.

Also fix handleCastFailed (SMSG_CAST_FAILED, Classic/TBC path) to fire
UNIT_SPELLCAST_FAILED and UNIT_SPELLCAST_STOP events — previously only
the WotLK SMSG_CAST_RESULT path fired these, leaving Classic/TBC addons
unaware of cast failures.

Adds isChannel field to UnitCastState and getCastTimeTotal() accessor.
This commit is contained in:
Kelsi 2026-03-22 15:05:29 -07:00
parent 1482694495
commit ce4f93dfcb
3 changed files with 91 additions and 0 deletions

View file

@ -7519,6 +7519,7 @@ void GameHandler::handlePacket(network::Packet& packet) {
} else {
auto& s = unitCastStates_[chanCaster];
s.casting = true;
s.isChannel = true;
s.spellId = chanSpellId;
s.timeTotal = chanTotalMs / 1000.0f;
s.timeRemaining = s.timeTotal;
@ -19363,6 +19364,13 @@ void GameHandler::handleCastFailed(network::Packet& packet) {
if (auto* sfx = renderer->getUiSoundManager())
sfx->playError();
}
// Fire UNIT_SPELLCAST_FAILED + UNIT_SPELLCAST_STOP so Lua addons can react
if (addonEventCallback_) {
addonEventCallback_("UNIT_SPELLCAST_FAILED", {"player", std::to_string(data.spellId)});
addonEventCallback_("UNIT_SPELLCAST_STOP", {"player", std::to_string(data.spellId)});
}
if (spellCastFailedCallback_) spellCastFailedCallback_(data.spellId);
}
static audio::SpellSoundManager::MagicSchool schoolMaskToMagicSchool(uint32_t mask) {
@ -19383,6 +19391,7 @@ void GameHandler::handleSpellStart(network::Packet& packet) {
if (data.casterUnit != playerGuid && data.castTime > 0) {
auto& s = unitCastStates_[data.casterUnit];
s.casting = true;
s.isChannel = false;
s.spellId = data.spellId;
s.timeTotal = data.castTime / 1000.0f;
s.timeRemaining = s.timeTotal;