From bd2186c87b75c8f6fdc15b15ac4a99c6532cb0dd Mon Sep 17 00:00:00 2001 From: Dusk-92 Date: Sun, 30 Aug 2026 10:30:50 +0200 Subject: [PATCH] Make raid first-frame state deterministic --- mods/raid-aggro-indicator.lua | 1 + mods/raid-combat-feedback.lua | 4 ++- mods/raid-compact-layout.lua | 7 +++- mods/raid-dispel-indicators.lua | 4 ++- mods/raid-group-header.lua | 55 ++++++++++++++++++++----------- mods/raid-healing-predictions.lua | 28 ++++++++-------- mods/raid-party.lua | 13 +++++--- mods/raid.lua | 21 ++++++++++-- 8 files changed, 91 insertions(+), 42 deletions(-) diff --git a/mods/raid-aggro-indicator.lua b/mods/raid-aggro-indicator.lua index 2f4c1e1..5c60a67 100644 --- a/mods/raid-aggro-indicator.lua +++ b/mods/raid-aggro-indicator.lua @@ -79,6 +79,7 @@ module.enable = function(self) frame.aggro.tex:SetVertexColor(1, 0, 0, 1) frame.aggro.tex:SetPoint("TOPLEFT", frame.aggro, "TOPLEFT", 2, -2) frame.aggro.tex:SetPoint("BOTTOMRIGHT", frame.aggro, "BOTTOMRIGHT", -2, 2) + frame.aggro:Hide() end, update = function(frame, event) diff --git a/mods/raid-combat-feedback.lua b/mods/raid-combat-feedback.lua index 89b1fac..2d5cc44 100644 --- a/mods/raid-combat-feedback.lua +++ b/mods/raid-combat-feedback.lua @@ -31,7 +31,9 @@ module.enable = function(self) end, update = function(frame, event) - if event and event == 'UNIT_COMBAT' then + if event then + if event ~= 'UNIT_COMBAT' then return end + -- update with latest values if arg1 ~= frame.unitstr then return end CombatFeedback_OnCombatEvent(arg2, arg3, arg4, arg5) diff --git a/mods/raid-compact-layout.lua b/mods/raid-compact-layout.lua index 60e2eb3..fe9ae25 100644 --- a/mods/raid-compact-layout.lua +++ b/mods/raid-compact-layout.lua @@ -59,8 +59,10 @@ module.enable = function(self) this.elapsed = 0 if ShaguTweaksRaidHeaders then + local foundHeader = false for i = 1, 8 do if ShaguTweaksRaidHeaders[i] then + foundHeader = true local _, anchor = ShaguTweaksRaidHeaders[i]:GetPoint() if anchor then ShaguTweaksRaidHeaders[i]:ClearAllPoints() @@ -72,7 +74,10 @@ module.enable = function(self) end end end - this:Hide() + + if foundHeader then + this:Hide() + end elseif this.total >= 10 then -- Fail closed instead of polling forever if headers never materialize. this:Hide() diff --git a/mods/raid-dispel-indicators.lua b/mods/raid-dispel-indicators.lua index f8b75e2..c86da85 100644 --- a/mods/raid-dispel-indicators.lua +++ b/mods/raid-dispel-indicators.lua @@ -56,13 +56,15 @@ module.enable = function(self) frame.dispel[dtype].tex:SetVertexColor(unpack(color)) frame.dispel[dtype].tex:SetPoint("TOPLEFT", frame.dispel[dtype], "TOPLEFT", 2, -2) frame.dispel[dtype].tex:SetPoint("BOTTOMRIGHT", frame.dispel[dtype], "BOTTOMRIGHT", -2, 2) + frame.dispel[dtype]:Hide() end end, update = function(frame, event) -- ignore empty or unrelated events if not event then return end - if arg1 and frame.unitstr ~= arg1 then return end + if (event == "UNIT_AURA" or event == "UNIT_AURASTATE") + and arg1 ~= frame.unitstr then return end -- affected debuffs frame.affected = frame.affected or {} diff --git a/mods/raid-group-header.lua b/mods/raid-group-header.lua index 7666413..3dbc3ea 100644 --- a/mods/raid-group-header.lua +++ b/mods/raid-group-header.lua @@ -23,38 +23,33 @@ module.enable = function(self) events = { }, create = function(frame) - -- skip if already initialized - if init then return else init = true end + if init then return end + init = true - -- create shortcut to raid.cluster local cluster = frame:GetParent() - - -- initialize header frame on cluster local header = CreateFrame("Frame", "ShaguTweaksRaidHeaders", cluster) header:SetFrameLevel(128) header:SetScale(.9) header:SetAllPoints(cluster) - header:RegisterEvent("PLAYER_ENTERING_WORLD") - header:RegisterEvent("RAID_ROSTER_UPDATE") - header:SetScript("OnEvent", function() - for i = 1, 40 do - if math.mod(i, 5) == 1 then - local group = math.ceil(i/5) - -- create header base frame + local function UpdateHeaders() + if not cluster.frames then return end + + for group = 1, 8 do + local index = (group - 1) * 5 + 1 + local anchorFrame = cluster.frames[index] + + if anchorFrame then if not header[group] then - header[group] = header[group] or CreateFrame("Frame", "ShaguTweaksRaidGroupHeader" .. group, header) - header[group]:SetPoint("TOP", cluster.frames[i], "TOP", 0, 6) + header[group] = CreateFrame("Frame", "ShaguTweaksRaidGroupHeader" .. group, header) + header[group]:SetPoint("TOP", anchorFrame, "TOP", 0, 6) header[group]:SetWidth(42) header[group]:SetHeight(16) header[group]:SetBackdrop(backdrop) header[group]:SetBackdropBorderColor(.8, .8, .8, 1) header[group]:SetBackdropColor(.4, .4, .4, 1) ShaguTweaks.DarkenFrame(header[group]) - end - -- create header text - if not header[group].text then header[group].text = header[group]:CreateFontString(nil, "HIGH", "GameFontWhite") header[group].text:SetFont(STANDARD_TEXT_FONT, 7, "THINOUTLINE") header[group].text:SetAllPoints(header[group]) @@ -63,14 +58,36 @@ module.enable = function(self) header[group].text:SetText("Group " .. group) end - -- toggle visibility if needed - if RAID_SUBGROUP_LISTS and RAID_SUBGROUP_LISTS[group] and table.getn(RAID_SUBGROUP_LISTS[group]) > 0 then + local inRaid = RAID_SUBGROUP_LISTS + and RAID_SUBGROUP_LISTS[group] + and table.getn(RAID_SUBGROUP_LISTS[group]) > 0 + local inParty = group == 1 + and not UnitInRaid("player") + and GetNumPartyMembers() > 0 + + if inRaid or inParty then header[group]:Show() else header[group]:Hide() end end end + end + + header.Update = UpdateHeaders + header:RegisterEvent("PLAYER_ENTERING_WORLD") + header:RegisterEvent("RAID_ROSTER_UPDATE") + header:RegisterEvent("PARTY_MEMBERS_CHANGED") + header:SetScript("OnEvent", UpdateHeaders) + + -- The header container is created while the first raid unit frame is + -- still being built. Wait until all 40 anchors exist, then initialize + -- once even if the PLAYER_ENTERING_WORLD event that created us was missed. + header:SetScript("OnUpdate", function() + if cluster.frames and cluster.frames[40] then + UpdateHeaders() + this:SetScript("OnUpdate", nil) + end end) end, diff --git a/mods/raid-healing-predictions.lua b/mods/raid-healing-predictions.lua index 3525240..dbc8b3d 100644 --- a/mods/raid-healing-predictions.lua +++ b/mods/raid-healing-predictions.lua @@ -23,6 +23,7 @@ module.enable = function(self) frame.predict:SetVertexColor(0, 1, 0, 1) frame.predict:SetPoint("TOPLEFT", frame.bar, "TOPLEFT", 0, 0) frame.predict:SetPoint("BOTTOMLEFT", frame.bar, "BOTTOMLEFT", 0, 0) + frame.predict:Hide() end, update = function(frame, event) @@ -30,22 +31,21 @@ module.enable = function(self) local heal = ShaguTweaks.libpredict:UnitGetIncomingHeals(frame.unitstr) local res = ShaguTweaks.libpredict:UnitHasIncomingResurrection(frame.unitstr) - -- update bar size if required - if heal ~= frame.predict_lastval then - if heal and heal > 0 then - local health, maxHealth = UnitHealth(frame.unitstr), UnitHealthMax(frame.unitstr) - local barWidth = frame.bar:GetWidth() - local healthWidth = maxHealth > 0 and barWidth * health / maxHealth or 0 - local incWidth = maxHealth > 0 and barWidth * heal / maxHealth or 0 - frame.predict:SetWidth(math.min(barWidth, healthWidth + incWidth)) - frame.predict:Show() - else - frame.predict:Hide() - end - - frame.predict_lastval = heal + -- Health can change while the incoming-heal amount stays constant, so + -- recalculate the projected width on every 250ms prediction tick. + if heal and heal > 0 then + local health, maxHealth = UnitHealth(frame.unitstr), UnitHealthMax(frame.unitstr) + local barWidth = frame.bar:GetWidth() + local healthWidth = maxHealth > 0 and barWidth * health / maxHealth or 0 + local incWidth = maxHealth > 0 and barWidth * heal / maxHealth or 0 + frame.predict:SetWidth(math.min(barWidth, healthWidth + incWidth)) + frame.predict:Show() + else + frame.predict:Hide() end + frame.predict_lastval = heal + -- update healing state if heal and heal > 0 then frame.info = "|cff22ff22+" .. heal .. "|r" diff --git a/mods/raid-party.lua b/mods/raid-party.lua index 06775a9..bb81870 100644 --- a/mods/raid-party.lua +++ b/mods/raid-party.lua @@ -40,13 +40,18 @@ module.enable = function(self) local unitstr = index == 1 and "player" or "party" .. index-1 -- assign party to first raid group of frames - this.cluster.frames[index].unitstr = unitstr - this.cluster.frames[index].groupid = 1 - this.cluster.frames[index]:Show() + local frame = this.cluster.frames[index] + frame.unitstr = unitstr + frame.groupid = 1 - -- save required raid frame size if UnitExists(unitstr) then + frame:Show() + if ShaguTweaks.UnitFrame_Refresh then + ShaguTweaks.UnitFrame_Refresh(frame) + end y = math.max(y, index) + else + frame:Hide() end end end diff --git a/mods/raid.lua b/mods/raid.lua index e5964ab..0314f7e 100644 --- a/mods/raid.lua +++ b/mods/raid.lua @@ -93,6 +93,14 @@ local UnitFrame_NewComponent = function(name, object) table.insert(components, object) end +local UnitFrame_Refresh = function(frame) + if not frame or not frame.unitstr or not UnitName(frame.unitstr) then return end + + for _, component in ipairs(components) do + component.update(frame, "FRAME_REFRESH") + end +end + local UnitFrame_OnEnter = function() if not this.unitstr then return end @@ -251,7 +259,8 @@ UnitFrame_NewComponent('health', { update = function(frame, event) -- ignore empty or unrelated events if not event then return end - if arg1 and frame.unitstr ~= arg1 then return end + if (event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH") + and arg1 ~= frame.unitstr then return end -- update statusbar values frame.bar:SetMinMaxValues(0, UnitHealthMax(frame.unitstr)) @@ -295,7 +304,11 @@ UnitFrame_NewComponent('mana', { update = function(frame, event) -- ignore empty or unrelated events if not event then return end - if arg1 and frame.unitstr ~= arg1 then return end + if (event == "UNIT_MANA" or event == "UNIT_MAXMANA" + or event == "UNIT_ENERGY" or event == "UNIT_MAXENERGY" + or event == "UNIT_RAGE" or event == "UNIT_MAXRAGE" + or event == "UNIT_DISPLAYPOWER") + and arg1 ~= frame.unitstr then return end -- update mana bar values frame.mana:SetMinMaxValues(0, UnitManaMax(frame.unitstr)) @@ -376,6 +389,7 @@ UnitFrame_NewComponent('highlight', { highlight:SetBackdrop(backdrop.border) highlight:SetPoint("TOPLEFT", frame, "TOPLEFT", -1.5,1.5) highlight:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 1.5,-1.5) + highlight:Hide() frame.highlight = highlight end, @@ -420,6 +434,7 @@ UnitFrame_NewComponent('target', { right:SetHeight(8) right:SetBlendMode('ADD') + target:Hide() frame.target = target end, @@ -486,6 +501,7 @@ UnitFrame_NewComponent('range', { }) ShaguTweaks.UnitFrame_NewComponent = UnitFrame_NewComponent +ShaguTweaks.UnitFrame_Refresh = UnitFrame_Refresh -- Bring everything to life module.enable = function(self) @@ -517,6 +533,7 @@ module.enable = function(self) frame.unitstr = 'raid' .. unit frame.groupid = group frame:Show() + UnitFrame_Refresh(frame) -- save required raid frame size x = math.max(x, frame.left)