From 345b74a02ff89b39c8732cd7b165737fb1ec649e Mon Sep 17 00:00:00 2001 From: Krathe Date: Fri, 12 Jun 2026 22:19:37 +0100 Subject: [PATCH] Arena: stop early GetContentType calls from destroying the reload hint The ARENA RELOAD FIX fallback (trust the saved lastContentType hint while IsInInstance() recovers after a reload) was being defeated by its own neighbours: on a reload, FinalizeHeaderInit -> UpdateHeaderVisibility calls GetContentType at ADDON_LOADED -- before PLAYER_ENTERING_WORLD arms useContentTypeFallback. If WoW's APIs weren't ready yet, that early call either nil'd DandersFramesCharDB.lastContentType (not-in-raid branch) or overwrote it with "openWorld" (in-raid + instanceType "none"), destroying the hint in exactly the scenario it exists for. Out of combat the ArenaDetectionRetry/ARENA_PREP backups recover; on a combat reload mid-round the arena frames could stay hidden until the round ended. - Snapshot the hint once at load (ADDON_LOADED, plus a self-capture in GetContentType for safety) and read the fallback from the snapshot, so later live-field writes can't destroy it. - Arm the fallback at ADDON_LOADED on a /reload (player already exists at ADDON_LOADED only on a reload -- same detection the header init uses), so the combat-safe FinalizeHeaderInit window already benefits. Fresh logins still never arm it: a stale "arena" hint from a previous session would misclassify the login zone. - Extend the fallback to the IsInRaid()==true + instanceType "none" case: IsInRaid() can recover before IsInInstance() after an arena reload (arena groups ARE raid groups), which previously classified the arena as "openWorld" and showed raid frames over the arena header. --- Core.lua | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/Core.lua b/Core.lua index dcc1618..2a49226 100644 --- a/Core.lua +++ b/Core.lua @@ -2900,7 +2900,18 @@ function DF:GetContentType() DF.cachedContentType = "arena" return "arena" end - + + -- ARENA RELOAD FIX: snapshot the saved content-type hint ONCE, before any + -- detection branch below can overwrite it. Early calls (e.g. + -- FinalizeHeaderInit → UpdateHeaderVisibility at ADDON_LOADED on a reload) + -- run while IsInInstance()/IsInRaid() may still be unreliable; without the + -- snapshot, those calls wiped DandersFramesCharDB.lastContentType (or + -- overwrote it with "openWorld") before the reload fallback could use it. + if not DF._contentTypeHintCaptured and DandersFramesCharDB then + DF._contentTypeHintCaptured = true + DF._contentTypeHintAtLoad = DandersFramesCharDB.lastContentType + end + local inInstance, instanceType = IsInInstance() -- Cache instance type for other uses @@ -2929,7 +2940,7 @@ function DF:GetContentType() -- before the reload. Only trust "arena" — other types recover fine on their own. if DF.useContentTypeFallback and not inInstance and (instanceType == "none" or instanceType == nil) - and DandersFramesCharDB and DandersFramesCharDB.lastContentType == "arena" then + and DF._contentTypeHintAtLoad == "arena" then DF.cachedContentType = "arena" return "arena" end @@ -2957,6 +2968,18 @@ function DF:GetContentType() -- In a raid group but not in an instance = open world (world boss, etc.) if IsInRaid() then + -- ARENA RELOAD FIX (part 2): IsInRaid() can recover before + -- IsInInstance() after a reload in arena (arena groups ARE raid + -- groups). Without this, the not-yet-recovered instanceType made us + -- conclude "openWorld" — showing raid frames over the arena header + -- and overwriting the saved arena hint. + if DF.useContentTypeFallback and not inInstance + and (instanceType == "none" or instanceType == nil) + and DF._contentTypeHintAtLoad == "arena" then + DF.cachedContentType = "arena" + return "arena" + end + DF.cachedContentType = "openWorld" DF.useContentTypeFallback = nil if DandersFramesCharDB then DandersFramesCharDB.lastContentType = "openWorld" end @@ -3335,6 +3358,26 @@ DF._MainEventDispatcher = function(self, event, arg1) -- Ensure structure exists in per-character DB if DandersFramesCharDB.specProfiles == nil then DandersFramesCharDB.specProfiles = {} end + -- ARENA RELOAD FIX: snapshot the saved content-type hint before any + -- GetContentType call can overwrite it (GetContentType also + -- self-captures; this pins the earliest possible point), and arm the + -- fallback NOW on a /reload — the player only already exists at + -- ADDON_LOADED on a reload (same detection Headers.lua uses for the + -- combat-safe finalize). PLAYER_ENTERING_WORLD also arms it + -- (isReloadingUi), but that's too late for the FinalizeHeaderInit → + -- UpdateHeaderVisibility call that runs inside the ADDON_LOADED + -- combat-safe window on a combat reload in arena. + -- Fresh logins must NOT arm it: a stale "arena" hint from a previous + -- session would misclassify the login zone (the fallback only clears + -- once real detection returns a definite answer). + if not DF._contentTypeHintCaptured then + DF._contentTypeHintCaptured = true + DF._contentTypeHintAtLoad = DandersFramesCharDB.lastContentType + end + if UnitExists("player") then + DF.useContentTypeFallback = true + end + -- Language override lives per-character because the locale files -- need to read it at file-load time, before any profile resolution -- happens. SavedVariablesPerCharacter is available at that stage.