diff --git a/api/unitframes.lua b/api/unitframes.lua index ea80b0d9..b8991e81 100644 --- a/api/unitframes.lua +++ b/api/unitframes.lua @@ -362,7 +362,7 @@ pfUI.events:RegisterCallback("aggro:changed", function(_, old, new) if frame.aggro then local guid = UnitGUID(frame.label .. frame.id) if guid and (guid == old or guid == new) then - frame.update_combat = true + pfUI.uf:QueueUpdate(frame, "combat") end end end @@ -498,10 +498,18 @@ function pfUI.uf:UpdateVisibility() self.chain = visibility ~= "hide" and unitstr:match("^(.+)target$") or nil if self.chain then local guid = UnitName(unitstr) and UnitGUID(unitstr) - if guid ~= self.unitguid then self.update_full = true end + if guid ~= self.unitguid then pfUI.uf:QueueUpdate(self, "full") end self.unitguid = guid self:RegisterUnitEvents(guid and CHAIN_TOKENS[unitstr] and unitstr or guid) else + -- A pet frame's token gets the pet's unit events, but a new pet behind it + -- (summoned, or remapped by raid.lua) comes with none of its own; the + -- visibility timer's GUID compare turns it into the full refresh. + if self.tick then + local guid = UnitGUID(unitstr) + if guid ~= self.unitguid then pfUI.uf:QueueUpdate(self, "full") end + self.unitguid = guid + end self:RegisterUnitEvents(visibility ~= "hide" and unitstr or nil) end self:RegisterChainEvents(self.chain) @@ -786,6 +794,7 @@ function pfUI.uf:UpdateConfig() f.combatfeedback = true else f.feedbackText:Hide() + f.feedback:Hide() f.combatfeedback = nil end @@ -1035,6 +1044,8 @@ end function pfUI.uf.OnShow() RegisterShownEvents(this) pfUI.uf:RefreshUnit(this, "all") + -- flags left from while the frame was off screen, and the portrait's model + pfUI.uf:QueueUpdate(this) end function pfUI.uf.OnHide() @@ -1051,7 +1062,6 @@ function pfUI.uf.OnEvent() if event == "PLAYER_LOGOUT" then this:UnregisterAllEvents() this:SetScript("OnEvent", nil) - this:SetScript("OnUpdate", nil) -- the visibility timer keeps ticking, so leaving this frame on its list -- would have UpdateVisibility re-register the unit events we just -- dropped -- straight back into the crash 132 this branch prevents @@ -1067,13 +1077,13 @@ function pfUI.uf.OnEvent() event == "RAID_ROSTER_UPDATE" or event == "PLAYER_UPDATE_RESTING" then - this.update_indicators = true + pfUI.uf:QueueUpdate(this, "indicators") end -- abort on broken unitframes (e.g focus) if not this.label then return end - -- a hidden frame runs no OnUpdate, so its unit coming into existence has to + -- a hidden frame does not refresh, so its unit coming into existence has to -- show it from here if VISIBILITY_EVENTS[event] then this:UpdateVisibility() @@ -1081,11 +1091,11 @@ function pfUI.uf.OnEvent() -- update regular frames if event == "PLAYER_ENTERING_WORLD" then - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") -- Clear GUID tracking on zone change for full rebuild if pfUI.uf.ClearGuidTracking then pfUI.uf.ClearGuidTracking() end elseif this.label == "target" and event == "PLAYER_TARGET_CHANGED" then - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") -- immediately update raid icon to avoid delay on target swap if this.raidIcon and this.config and this.config.raidicon == "1" then local raidIcon = UnitName("target") and GetRaidTargetIndex("target") @@ -1104,26 +1114,26 @@ function pfUI.uf.OnEvent() local oldGuid = pfUI.uf.guidTracker.frameToGuid[this] if newGuid ~= oldGuid then pfUI.uf.guidTracker.frameToGuid[this] = newGuid - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") end else - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") end elseif ( this.label == "raid" or this.label == "party" ) and event == "RAID_ROSTER_UPDATE" then - -- Note: Smart GUID-based updates are handled in raid.lua OnUpdate + -- Note: Smart GUID-based updates are handled in raid.lua UpdateRoster -- after frame IDs are reassigned. We don't set update_full here anymore -- for raid frames to avoid the freeze. if this.label == "party" then -- Party frames still need the old logic (no smart tracking yet) - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") end -- Raid frames: update_full is set by raid.lua GUID tracker elseif this.label == "pet" and event == "UNIT_PET" then - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") elseif this.label == "player" and (event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_EQUIPMENT_CHANGED") then - this.update_aura = true + pfUI.uf:QueueUpdate(this, "aura") elseif this.label == "pet" and event == "UNIT_HAPPINESS" then - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") elseif event == "UNIT_IN_RANGE_UPDATE" then -- registered for the frame's unit alone, and fired in the filter's lower -- case spelling, which a GUID's compare below would miss @@ -1135,211 +1145,194 @@ function pfUI.uf.OnEvent() -- GUID, so filtering on one of the two never wakes the frame twice. elseif arg1 and arg1 == this.eventunit then if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then - this.update_portrait = true + pfUI.uf:QueueUpdate(this, "portrait") elseif event == "UNIT_AURA" then - this.update_aura = true + pfUI.uf:QueueUpdate(this, "aura") elseif event == "UNIT_AURA_DELTA" then -- an aura that only refreshed or restacked leaves every aura in its -- slot, so the icons need their timers and stacks, not a rebuild if arg2.isFullUpdate or arg2.addedAuraInstanceIDs or arg2.removedAuraInstanceIDs then - this.update_aura = true + pfUI.uf:QueueUpdate(this, "aura") else - this.update_auratime = true + pfUI.uf:QueueUpdate(this, "auratime") end elseif event == "UNIT_POWER_UPDATE" or event == "UNIT_MAXPOWER" then -- every power of the unit reports, a cat druid's mana regen too; redraw -- for the one the bar shows, and for mana under a druid mana bar local _, shown = UnitPowerType(arg1) if arg2 == shown or (arg2 == "MANA" and this.druidmana) then - this.update_base = true + pfUI.uf:QueueUpdate(this, "base") end elseif event == "UNIT_FACTION" then -- the PvP flag, the reaction colour and the tapped grey - this.update_indicators = true - this.update_base = true + pfUI.uf:QueueUpdate(this, "indicators") + pfUI.uf:QueueUpdate(this, "base") elseif event == "UNIT_FLAGS" then - this.update_combat = true + pfUI.uf:QueueUpdate(this, "combat") elseif event == "UNIT_DISTANCE_CHECK_UPDATE" then -- the portrait trades the question mark for the model, the frame fades -- by sight, and an attacker that left with the member is let go - this.update_portrait = true - this.update_combat = true + pfUI.uf:QueueUpdate(this, "portrait") + pfUI.uf:QueueUpdate(this, "combat") elseif event == "UNIT_CONNECTION" then - this.update_full = true + pfUI.uf:QueueUpdate(this, "full") elseif event == "UNIT_COMBAT" then CombatFeedback_OnCombatEvent(arg2, arg3, arg4, arg5) + this.feedback:Show() elseif event == "INCOMING_RESURRECT_CHANGED" then - this.update_indicators = true + pfUI.uf:QueueUpdate(this, "indicators") else - this.update_base = true + pfUI.uf:QueueUpdate(this, "base") end end end --- Local reference for performance -local _GetTime = GetTime +-- Drain the update flags the events set, then hand a 3D portrait its unit. +-- A frame that is not on screen keeps its flags; OnShow flushes them. +local function Flush(frame) + frame.queued = nil + if not frame:IsVisible() then return end --- Global cached time for libpredict and other functions -pfUI.uf.now = 0 - --- ============================================================================ --- OnUpdate - draining the event-set update flags, heal prediction, and the --- two polls no event replaces (a UnitXP range threshold, the pet frames). --- ============================================================================ -function pfUI.uf.OnUpdate() - local now = _GetTime() - pfUI.uf.now = now - - -- update combat feedback (no throttle - needs immediate feedback) - if this.feedbackText then CombatFeedback_OnUpdate(arg1) end - - -- Throttle raid/party frames for performance - if this.label == "raid" or this.label == "party" then - if (this.throttleTick or 0) > now then - return - end - this.throttleTick = now + 0.1 -- Default: 10 FPS - end - - if this.label then - -- what no event reports: a UnitXP range threshold, and the pet frames - -- (created with a tick) - if this.rangepoll or this.tick then - -- Validate tick value - it should be an interval (e.g. 0.5), not a timestamp - local tickInterval = this.tick - if tickInterval and tickInterval > 10 then - -- tick is a timestamp, not an interval - ignore it - tickInterval = nil - end - -- Reset lastTick if it's invalid (much larger than now, e.g. from corrupted state) - if this.lastTick and this.lastTick > now + 10 then - this.lastTick = nil - end - if not this.lastTick then this.lastTick = now + (tickInterval or .5) end - if this.lastTick < now then - local unitstr = this.label .. this.id - this.lastTick = now + (tickInterval or .5) - - if this.rangepoll then pfUI.uf:RefreshUnitState(this) end - - -- A pet's full refresh rescans every aura and the portrait, so only - -- do it when the unit behind the frame changes or once a second; - -- other ticks refresh the bars only. - if this.tick then - local guid = UnitGUID(unitstr) - if guid ~= this.tickGuid or (this.tickFull or 0) < now then - this.tickGuid = guid - this.tickFull = now + 1 - pfUI.uf:RefreshUnit(this, "all") - else - pfUI.uf:RefreshUnit(this, "base") - end - end - end - end - - -- Heal Prediction (throttled to 0.1s for responsiveness) - if libpredict and this.incHeal then - if not this.lastHealTick then this.lastHealTick = now end - if this.lastHealTick < now then - this.lastHealTick = now + 0.1 - - local unit = this.label .. this.id - local heal = libpredict:UnitGetIncomingHeals(unit) - - local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) - - if heal - health - maxHealth ~= this.predictstate then - local overhealperc = tonumber(this.config.overhealperc) - this.predictstate = heal - health - maxHealth - - if heal > 0 and (health < maxHealth or overhealperc > 0 ) then - local width = this.config.width - local height = this.config.height - - if this.config.verticalbar == "0" then - local healthWidth = width * (health / maxHealth) - local incWidth = width * heal / maxHealth - if healthWidth + incWidth > width * (1+(overhealperc/100)) then - incWidth = width * (1+overhealperc/100) - healthWidth - end - this.incHeal:SetWidth(incWidth) - else - local healthHeight = height * (health / maxHealth) - local incHeight = height * heal / maxHealth - if healthHeight + incHeight > height * (1+(overhealperc/100)) then - incHeight = height * (1+overhealperc/100) - healthHeight - end - this.incHeal:SetHeight(incHeight) - end - - this.incHeal:Show() - else - this.incHeal:Hide() - end - end - end - end - end - - -- ============================================================================ - -- EVENT-BASED UPDATES (Health, Mana, Auras, etc.) - -- ============================================================================ - - - -- process all queued unit events - if this.update_full then + if frame.update_full then -- process full updates, indicators and combat state included - pfUI.uf:RefreshUnit(this, "all") + pfUI.uf:RefreshUnit(frame, "all") -- clear update caches - this.update_full = nil - this.update_base = nil - this.update_aura = nil - this.update_auratime = nil - this.update_portrait = nil - this.update_indicators = nil - this.update_combat = nil + frame.update_full = nil + frame.update_base = nil + frame.update_aura = nil + frame.update_auratime = nil + frame.update_portrait = nil + frame.update_indicators = nil + frame.update_combat = nil else - if this.update_indicators then - pfUI.uf:RefreshIndicators(this) - this.update_indicators = nil + if frame.update_indicators then + pfUI.uf:RefreshIndicators(frame) + frame.update_indicators = nil end - if this.update_combat then - pfUI.uf:RefreshCombat(this) - this.update_combat = nil + if frame.update_combat then + pfUI.uf:RefreshCombat(frame) + frame.update_combat = nil end -- process individual events; a rebuild re-times the icons as well - if this.update_aura then - pfUI.uf:RefreshUnit(this, "aura") - this.update_aura = nil - this.update_auratime = nil - this.update_base = true - elseif this.update_auratime then - pfUI.uf:RefreshUnit(this, "auratime") - this.update_auratime = nil + if frame.update_aura then + pfUI.uf:RefreshUnit(frame, "aura") + frame.update_aura = nil + frame.update_auratime = nil + frame.update_base = true + elseif frame.update_auratime then + pfUI.uf:RefreshUnit(frame, "auratime") + frame.update_auratime = nil end - if this.update_portrait then - pfUI.uf:RefreshUnit(this, "portrait") - this.update_portrait = nil - this.update_base = true + if frame.update_portrait then + pfUI.uf:RefreshUnit(frame, "portrait") + frame.update_portrait = nil + frame.update_base = true end - if this.update_base then - pfUI.uf:RefreshUnit(this, "base") - this.update_base = nil + if frame.update_base then + pfUI.uf:RefreshUnit(frame, "base") + frame.update_base = nil end end - -- update portrait on first visible frame - if this.portrait and this.portrait.model and this.portrait.model.update then - this.portrait.model.lastUnit = UnitName(this.portrait.model.update) - this.portrait.model:SetUnit(this.portrait.model.update) - this.portrait.model:SetCamera(0) - this.portrait.model.update = nil + -- a model takes its unit only once it is on screen, so it waits for this + local model = frame.portrait and frame.portrait.model + if model and model.update then + model.lastUnit = UnitName(model.update) + model:SetUnit(model.update) + model:SetCamera(0) + model.update = nil + end +end + +-- Flag `kind` ("full", "base", "aura", "auratime", "portrait", "indicators", +-- "combat", or nil for none) for the frame's next flush, and schedule that +-- flush: the next frame, or within 0.1s for the raid and party frames, which +-- batch their bursts. +function pfUI.uf:QueueUpdate(frame, kind) + if kind then frame["update_" .. kind] = true end + if frame.queued then return end + frame.queued = true + if frame.label == "raid" or frame.label == "party" then + C_Timer.After(.1, function() Flush(frame) end) + else + RunNextFrame(function() Flush(frame) end) + end +end + +-- Size the incoming-heal overlay from libpredict's heals and the unit's +-- health. Runs with the bars (RefreshUnit "base") and when libpredict reports +-- the heals on the unit changed. +function pfUI.uf:RefreshIncomingHeal(frame) + local unit = frame.label .. frame.id + local heal = libpredict:UnitGetIncomingHeals(unit) + local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) + + if heal - health - maxHealth == frame.predictstate then return end + frame.predictstate = heal - health - maxHealth + + local overhealperc = tonumber(frame.config.overhealperc) + if heal > 0 and (health < maxHealth or overhealperc > 0 ) then + local width = frame.config.width + local height = frame.config.height + + if frame.config.verticalbar == "0" then + local healthWidth = width * (health / maxHealth) + local incWidth = width * heal / maxHealth + if healthWidth + incWidth > width * (1+(overhealperc/100)) then + incWidth = width * (1+overhealperc/100) - healthWidth + end + frame.incHeal:SetWidth(incWidth) + else + local healthHeight = height * (health / maxHealth) + local incHeight = height * heal / maxHealth + if healthHeight + incHeight > height * (1+(overhealperc/100)) then + incHeight = height * (1+overhealperc/100) - healthHeight + end + frame.incHeal:SetHeight(incHeight) + end + + frame.incHeal:Show() + else + frame.incHeal:Hide() + end +end + +pfUI.events:RegisterCallback("libpredict:heals", function(_, target) + for frame in pairs(visibilityframes) do + if frame.namecache == target and frame:IsVisible() then + pfUI.uf:RefreshIncomingHeal(frame) + end + end +end, "unitframes") + +-- A UnitXP range threshold has no event, so the frames fading by it poll. +C_Timer.NewTicker(.5, function() + for frame in pairs(visibilityframes) do + if frame.rangepoll and frame:IsVisible() then pfUI.uf:RefreshUnitState(frame) end + end +end) + +-- Fade the combat feedback text in, hold it, and fade it out -- the timing of +-- CombatFeedback_OnUpdate. Runs on a child frame shown only while the text is. +local function FeedbackOnUpdate() + local frame = this:GetParent() + local text = frame.feedbackText + local elapsed = GetTime() - frame.feedbackStartTime + local fadein, hold = COMBATFEEDBACK_FADEINTIME, COMBATFEEDBACK_HOLDTIME + if elapsed < fadein then + text:SetAlpha(elapsed / fadein) + elseif elapsed < fadein + hold then + text:SetAlpha(1) + elseif elapsed < fadein + hold + COMBATFEEDBACK_FADEOUTTIME then + text:SetAlpha(1 - (elapsed - hold - fadein) / COMBATFEEDBACK_FADEOUTTIME) + else + text:Hide() + this:Hide() end end @@ -1528,7 +1521,6 @@ function pfUI.uf:EnableScripts() f:SetScript("OnShow", pfUI.uf.OnShow) f:SetScript("OnHide", pfUI.uf.OnHide) f:SetScript("OnEvent", pfUI.uf.OnEvent) - f:SetScript("OnUpdate", pfUI.uf.OnUpdate) visibilityframes[f] = true end @@ -1662,6 +1654,9 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick) f.portrait.model = CreateFrame("PlayerModel", "pfPortraitModel" .. f.label .. f.id, f.portrait) f.portrait.model.next = CreateFrame("PlayerModel", nil, nil) f.feedbackText = f:CreateFontString("pfHitIndicator" .. f.label .. f.id, "OVERLAY", "NumberFontNormalHuge") + f.feedback = CreateFrame("Frame", nil, f) + f.feedback:Hide() + f.feedback:SetScript("OnUpdate", FeedbackOnUpdate) if f.label == "raid" and mod(f.id, 5) == 1 then local group = math.ceil(f.id/5) @@ -2251,6 +2246,7 @@ function pfUI.uf:RefreshUnit(unit, component) unit.portrait.model.update = unitstr end end + if unit.portrait.model.update then pfUI.uf:QueueUpdate(unit) end end end @@ -2391,6 +2387,7 @@ function pfUI.uf:RefreshUnit(unit, component) if unit.druidmana then pfUI.uf:UpdateDruidMana(unit) end + pfUI.uf:RefreshIncomingHeal(unit) pfUI.uf:RefreshUnitState(unit) end end diff --git a/libs/libpredict.lua b/libs/libpredict.lua index 2307eeec..8b3827ae 100644 --- a/libs/libpredict.lua +++ b/libs/libpredict.lua @@ -36,6 +36,18 @@ local sentTargets = {} -- [castGUID] = target name of an own cast, from UNIT_ local resOffers = {} -- [guid] = expiry of a landed resurrection the target has yet to accept local RES_OFFER_TIMEOUT = 60 -- the target's resurrect popup declines itself after 60s +-- Tell the listeners of "libpredict:heals" that the heals on `target` (a +-- name) changed, and again at `expiry`, when a heal that is never stopped +-- drops out of UnitGetIncomingHeals. +local function HealsChanged(target, expiry) + pfUI.events:TriggerEvent("libpredict:heals", target) + if expiry then + C_Timer.After(expiry - GetTime(), function() + pfUI.events:TriggerEvent("libpredict:heals", target) + end) + end +end + -- Localized spell names resolved once from canonical rank-1 spellIDs. -- Every rank shares the same name, so per-rank comparisons elsewhere can -- be done against these constants without per-locale or per-rank tables. @@ -309,7 +321,7 @@ end local function RefreshResFrames(guid) for _, frame in pairs(pfUI.uf.frames) do if frame.unitstr and UnitGUID(frame.unitstr) == guid then - frame.update_indicators = true + pfUI.uf:QueueUpdate(frame, "indicators") end end end @@ -439,7 +451,7 @@ function libpredict:ParseChatMessage(sender, msg) end elseif msgtype == "Hot" then -- Duplicate check: ignore same sender+target+spell within DUPLICATE_WINDOW - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = sender .. target .. heal if recentHots[key] and (now - recentHots[key]) < DUPLICATE_WINDOW then if libpredict.debug then @@ -484,11 +496,11 @@ function libpredict:Heal(sender, target, amount, duration, senderGuid) return end - local now = pfUI.uf.now or GetTime() - local timeout = duration/1000 + now + local timeout = duration/1000 + GetTime() heals[target] = heals[target] or {} heals[target][sender] = { amount, timeout } if senderGuid then healGuidToName[senderGuid] = sender end + HealsChanged(target, timeout) end -- Debug flag @@ -512,7 +524,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank local existingRank = tonumber(existing.rank) or 0 local newRank = tonumber(rank) or 0 - local now = pfUI.uf.now or GetTime() + local now = GetTime() local existingTimeleft = (existing.start + existing.duration) - now -- If existing HoT is still active and has higher rank, don't overwrite @@ -525,7 +537,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank end end - local now = pfUI.uf.now or GetTime() + local now = GetTime() hots[target][spell].duration = duration hots[target][spell].start = startTime or now hots[target][spell].rank = rank -- Store rank for protection @@ -544,7 +556,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank if pfUI and pfUI.uf and pfUI.uf.frames then for _, frame in pairs(pfUI.uf.frames) do if frame.namecache == target then - frame.update_aura = true + pfUI.uf:QueueUpdate(frame, "aura") if libpredict.debug then DEFAULT_CHAT_FRAME:AddMessage(" |cff00ff00-> Frame update triggered for " .. (frame:GetName() or "?") .. "|r") end @@ -558,6 +570,7 @@ function libpredict:HealStop(sender) for tsender in pairs(heals[ttarget]) do if sender == tsender then heals[ttarget][tsender] = nil + HealsChanged(ttarget) end end end @@ -573,6 +586,7 @@ function libpredict:HealDelay(sender, delay) for tsender, amount in pairs(heals[target]) do if sender == tsender then amount[2] = amount[2] + delay + HealsChanged(target, amount[2]) end end end @@ -588,7 +602,7 @@ function libpredict:UnitGetIncomingHeals(unit) if not heals[name] then return sumheal else - local now = pfUI.uf.now or GetTime() + local now = GetTime() for sender, amount in pairs(heals[name]) do if amount[2] <= now then heals[name][sender] = nil @@ -720,7 +734,7 @@ hooksecurefunc("CastSpell", function(id, bookType) if effect == REJUVENATION then local target = spell_queue[3] - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Reju" .. target -- Cooldown-Check @@ -737,7 +751,7 @@ hooksecurefunc("CastSpell", function(id, bookType) libpredict.sender:SendHealCommMsg("Reju/"..target.."/"..rejuvDuration.."/"..rankStr.."/") elseif effect == RENEW then local target = spell_queue[3] - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Renew" .. target -- Cooldown-Check @@ -783,7 +797,7 @@ hooksecurefunc("CastSpellByName", function(effect, target) if effect == REJUVENATION then local hotTarget = target or default - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Reju" .. hotTarget -- Cooldown-Check @@ -800,7 +814,7 @@ hooksecurefunc("CastSpellByName", function(effect, target) libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/") elseif effect == RENEW then local hotTarget = target or default - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Renew" .. hotTarget -- Cooldown-Check @@ -843,7 +857,7 @@ hooksecurefunc("UseAction", function(slot, target, selfcast) if effect == REJUVENATION then local hotTarget = spell_queue[3] - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Reju" .. hotTarget -- Cooldown-Check @@ -860,7 +874,7 @@ hooksecurefunc("UseAction", function(slot, target, selfcast) libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/") elseif effect == RENEW then local hotTarget = spell_queue[3] - local now = pfUI.uf.now or GetTime() + local now = GetTime() local key = "Renew" .. hotTarget -- Cooldown-Check @@ -1083,7 +1097,7 @@ function libpredict:GetHotDuration(unit, spell) -- FALLBACK: the HealComm/cast-fed table, for HoTs C_UnitAuras has no timer for local start, duration, timeleft - local now = pfUI.uf.now or GetTime() + local now = GetTime() local unitName = UnitName(unit) local unitdata = hots[unitName] diff --git a/modules/player.lua b/modules/player.lua index ed96a144..77f84feb 100644 --- a/modules/player.lua +++ b/modules/player.lua @@ -112,18 +112,6 @@ pfUI:RegisterModule("player", function () UpdateInfoText() end - -- Add throttle to player frame OnUpdate - -- Throttle the unit frame's existing OnUpdate to ~20 FPS so the per-frame - -- work stays cheap. - if pfUI.uf.player:GetScript("OnUpdate") then - local originalOnUpdate = pfUI.uf.player:GetScript("OnUpdate") - pfUI.uf.player:SetScript("OnUpdate", function() - if (this.throttleTick or 0) > GetTime() then return end - this.throttleTick = GetTime() + 0.05 - originalOnUpdate() - end) - end - -- PLAYER_DAMAGE_DONE_MODS fires on the MOD_DAMAGE_DONE fields that -- GetSpellBonusDamage reads, so gear, buffs and talents all reach it. pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", UpdateInfoText) diff --git a/modules/raid.lua b/modules/raid.lua index 992205a5..917d7d8b 100644 --- a/modules/raid.lua +++ b/modules/raid.lua @@ -264,8 +264,7 @@ pfUI:RegisterModule("raid", function () if newGuid ~= oldGuid then -- GUID changed = different player = need full update tracker.frameToGuid[frame] = newGuid - frame.update_full = true - frame.update_aura = true -- Force aura refresh! + pfUI.uf:QueueUpdate(frame, "full") end end end