mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-21 20:00:48 +00:00
Drive nameplate castbars off UNIT_SPELLCAST_*
ClassicAPI now fires UNIT_SPELLCAST_* for nameplate tokens, so populate the
per-GUID castState cache from UNIT_SPELLCAST_{START,CHANNEL_START} (poll
PollCastInfo for the timing the payload omits) and clear it on
{STOP,CHANNEL_STOP} -- the remote poll fires STOP for natural end, interrupt,
and cancel alike. Replaces the nampower SPELL_{START,FAILED}_OTHER path; the
^nameplate arg1 gate ignores the target/focus/party fires of the same events,
and the NAME_PLATE_UNIT_ADDED seed still catches a plate spawning mid-cast.
Nameplate cast detection is now nampower-free.
This commit is contained in:
+37
-41
@@ -64,18 +64,19 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
|
|
||||||
local raidGuidCache = {} -- guid -> name (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED)
|
local raidGuidCache = {} -- guid -> name (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED)
|
||||||
|
|
||||||
-- Per-GUID cast state, populated by nampower's SPELL_START_OTHER events and
|
-- Per-GUID cast state, populated from ClassicAPI's UNIT_SPELLCAST_* events
|
||||||
-- cleared on SPELL_FAILED_OTHER / plate removal / expiry. This replaces the
|
-- (which now fire for nameplate tokens) and cleared on STOP / plate removal /
|
||||||
-- old per-tick C_Spell poll on every visible plate: cast detection is now
|
-- expiry. This replaces the old per-tick C_Spell poll on every visible plate:
|
||||||
-- event driven, and GetCastInfo just reads this cache.
|
-- cast detection is event driven, and GetCastInfo just reads this cache.
|
||||||
local castState = {}
|
local castState = {}
|
||||||
-- guid -> nameplate, maintained on NAME_PLATE_UNIT_ADDED/_REMOVED so a cast
|
-- guid -> nameplate, maintained on NAME_PLATE_UNIT_ADDED/_REMOVED so a cast
|
||||||
-- event can find its plate in O(1) and only cache casts we actually show.
|
-- event can find its plate in O(1) and only cache casts we actually show.
|
||||||
local plateByGuid = {}
|
local plateByGuid = {}
|
||||||
|
|
||||||
-- One-shot C_Spell poll. Only used to seed a plate that spawns while its
|
-- One-shot C_Spell poll. Builds the cast struct for a UNIT_SPELLCAST_* event
|
||||||
-- unit is already mid-cast (its SPELL_START_OTHER fired before the plate
|
-- (the payload carries no timing) and seeds a plate that spawns while its unit
|
||||||
-- existed). Never called per frame.
|
-- is already mid-cast (its START fired before the plate existed). Picks cast
|
||||||
|
-- vs channel itself. Never called per frame.
|
||||||
local function PollCastInfo(unit)
|
local function PollCastInfo(unit)
|
||||||
if not unit then return nil end
|
if not unit then return nil end
|
||||||
local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit)
|
local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit)
|
||||||
@@ -477,8 +478,10 @@ nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
|||||||
nameplates:RegisterEvent("UNIT_AURA")
|
nameplates:RegisterEvent("UNIT_AURA")
|
||||||
nameplates:RegisterEvent("UNIT_FLAGS")
|
nameplates:RegisterEvent("UNIT_FLAGS")
|
||||||
nameplates:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
nameplates:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
||||||
nameplates:RegisterEvent("SPELL_START_OTHER")
|
nameplates:RegisterEvent("UNIT_SPELLCAST_START")
|
||||||
nameplates:RegisterEvent("SPELL_FAILED_OTHER")
|
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
||||||
|
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||||
|
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
||||||
|
|
||||||
nameplates:SetScript("OnEvent", function()
|
nameplates:SetScript("OnEvent", function()
|
||||||
-- Stop event handling during logout to prevent crash 132
|
-- Stop event handling during logout to prevent crash 132
|
||||||
@@ -562,9 +565,9 @@ nameplates:RegisterEvent("SPELL_FAILED_OTHER")
|
|||||||
plate.nameplate.unit = arg1
|
plate.nameplate.unit = arg1
|
||||||
if guid then
|
if guid then
|
||||||
plateByGuid[guid] = plate.nameplate
|
plateByGuid[guid] = plate.nameplate
|
||||||
-- Seed: the unit may already be mid-cast (its SPELL_START_OTHER fired
|
-- Seed: the unit may already be mid-cast (its UNIT_SPELLCAST_START
|
||||||
-- before this plate existed). One poll here catches that; ongoing
|
-- fired before this plate existed). One poll here catches that;
|
||||||
-- casts arrive via the event.
|
-- ongoing casts arrive via the event.
|
||||||
castState[guid] = PollCastInfo(arg1)
|
castState[guid] = PollCastInfo(arg1)
|
||||||
end
|
end
|
||||||
nameplates.OnShow(plate)
|
nameplates.OnShow(plate)
|
||||||
@@ -609,39 +612,32 @@ nameplates:RegisterEvent("SPELL_FAILED_OTHER")
|
|||||||
if pn then pn.eventcache = true end
|
if pn then pn.eventcache = true end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "SPELL_START_OTHER" then
|
elseif event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START" then
|
||||||
-- nampower: arg2=spellId, arg3=casterGuid, arg6=castTime(ms),
|
-- ClassicAPI fires UNIT_SPELLCAST_* per unit token, including the caster's
|
||||||
-- arg7=channel duration(ms, 0 if not a channel), arg8=spellType
|
-- "nameplateN". The payload has no timing, so poll it (PollCastInfo picks
|
||||||
-- (1 = channel). Cache the cast only for a unit we have a plate for, so
|
-- cast vs channel) and cache -- only for a unit we have a plate for, so
|
||||||
-- the table stays bounded to on-screen casters.
|
-- the table stays bounded to on-screen casters.
|
||||||
local casterGuid = arg3
|
if arg1 and strfind(arg1, "^nameplate") then
|
||||||
local plate = casterGuid and plateByGuid[casterGuid]
|
local guid = UnitGUID(arg1)
|
||||||
if plate then
|
local plate = guid and plateByGuid[guid]
|
||||||
local isChannel = arg8 == 1
|
if plate then
|
||||||
local durationMs = isChannel and arg7 or arg6
|
castState[guid] = PollCastInfo(arg1)
|
||||||
if durationMs and durationMs > 0 then
|
if castState[guid] then
|
||||||
local spellId = arg2
|
plate.castUpdate = true -- bypass the throttle so the bar shows now
|
||||||
local now = GetTime()
|
end
|
||||||
castState[casterGuid] = {
|
|
||||||
spellName = C_Spell.GetSpellName(spellId),
|
|
||||||
spellID = spellId,
|
|
||||||
icon = C_Spell.GetSpellTexture(spellId),
|
|
||||||
startTime = now,
|
|
||||||
endTime = now + durationMs / 1000,
|
|
||||||
duration = durationMs / 1000,
|
|
||||||
isChannel = isChannel,
|
|
||||||
}
|
|
||||||
plate.castUpdate = true -- bypass the throttle so the bar shows now
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "SPELL_FAILED_OTHER" then
|
elseif event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||||||
-- nampower: arg1=casterGuid, arg2=spellId. Clear on interrupt/failure.
|
-- Cast/channel ended (natural, interrupted, or cancelled -- the poll fires
|
||||||
local casterGuid = arg1
|
-- STOP for all three). Clear the cached cast and refresh its plate.
|
||||||
if casterGuid and castState[casterGuid] then
|
if arg1 and strfind(arg1, "^nameplate") then
|
||||||
castState[casterGuid] = nil
|
local guid = UnitGUID(arg1)
|
||||||
local plate = plateByGuid[casterGuid]
|
if guid and castState[guid] then
|
||||||
if plate then plate.castUpdate = true end
|
castState[guid] = nil
|
||||||
|
local plate = plateByGuid[guid]
|
||||||
|
if plate then plate.castUpdate = true end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "UNIT_AURA" then
|
elseif event == "UNIT_AURA" then
|
||||||
|
|||||||
Reference in New Issue
Block a user