diff --git a/CMap.lua b/CMap.lua deleted file mode 100644 index 77ce078..0000000 --- a/CMap.lua +++ /dev/null @@ -1,557 +0,0 @@ -local useUiScale = tonumber(GetCVar("useUiScale")) -local uiScale = GetCVar("uiScale") -if useUiScale ~= 1 then uiScale = 1 end -frameWidth = UIParent:GetWidth() / uiScale -xMiddle = frameWidth / 2 -frameHeight = UIParent:GetHeight() / uiScale -yMiddle = frameHeight / 2 -frameScale = 0.75999999046326 -local _G = getfenv(0) -local timeElapsed = 0 -local updateTime = 1/60 -CTextures = {} -CRotateTextures = {} - --- Default minimap dimensions (before any scaling) -local defaultMinimapWidth = 140 -local defaultMinimapHeight = 140 - --- Track hidden minimap buttons so we can restore them -local hiddenMinimapButtons = {} - - --- Minimap cluster Show hook state (for minimap hide/show toggle) -local minimapClusterHooked = false -local minimapClusterOrigShow = nil -local minimapOrigShow = nil - --- Minimap button Show hook state -local minimapBtnHooked = false - --- Saved original Show functions for minimap buttons -local hiddenBtnOrigShows = {} - --- Saved original anchor points for minimap buttons (so positions are preserved across hide/show) --- Format: hiddenBtnOrigPoints[frame] = { {point, relativeTo, relativePoint, xOfs, yOfs}, ... } -local hiddenBtnOrigPoints = {} - --- Addon version for SavedVariables migration -local ADDON_VERSION = 7 - -local function print(msg) - if msg and msg ~= "" then - DEFAULT_CHAT_FRAME:AddMessage(msg, 1, 1, 0) - end -end - -function deepCopyHash(t) - if t == nil then return nil end - local nt = {} - for k, v in pairs(t) do - if type(v) == "table" then - nt[k] = deepCopyHash(v) - else - nt[k] = v - end - end - return nt -end - -function destroyTable(t) - setmetatable(t, nil) - for k,v in pairs(t) do - t[k] = nil - end -end - --- ============================================ --- SavedVariables Migration --- ============================================ --- Detects and fixes stale/invalid data from older addon versions. --- Called during PLAYER_ENTERING_WORLD before any settings are applied. -local function MigrateSavedVariables() - if not SexyMap2DB then - SexyMap2DB = {} - end - - -- Version-based migration: if the saved version is older than current, - -- apply fixes. This runs ONCE per version bump. - local savedVersion = SexyMap2DB.version or 0 - - -- Always check for invalid data regardless of version, - -- since the user might have stale data from before version tracking existed. - - -- Fix empty borders array (from v1.4 when some presets had empty borders) - if SexyMap2DB.borders == nil or (type(SexyMap2DB.borders) == "table" and table.getn(SexyMap2DB.borders) == 0 and next(SexyMap2DB.borders) == nil) then - SexyMap2DB.borders = deepCopyHash(borderPresets["Diablo by Zork"].borders) - print("[SexyMap] Migrated: empty borders reset to default preset.") - end - - -- Fix backdrop with invalid/missing data - if SexyMap2DB.backdrop == nil then - SexyMap2DB.backdrop = deepCopyHash(borderPresets["Diablo by Zork"].backdrop) - print("[SexyMap] Migrated: missing backdrop reset to default preset.") - else - -- Fix empty borderColor/textureColor that cause green rendering - if SexyMap2DB.backdrop.borderColor == nil or (type(SexyMap2DB.backdrop.borderColor) == "table" and next(SexyMap2DB.backdrop.borderColor) == nil) then - SexyMap2DB.backdrop.borderColor = { r = 1, g = 1, b = 1, a = 1 } - end - if SexyMap2DB.backdrop.textureColor == nil or (type(SexyMap2DB.backdrop.textureColor) == "table" and next(SexyMap2DB.backdrop.textureColor) == nil) then - SexyMap2DB.backdrop.textureColor = { r = 0, g = 0, b = 0, a = 1 } - end - -- Fix settings with .blp in edgeFile/bgFile (WoW 1.12 auto-appends .blp) - if SexyMap2DB.backdrop.settings then - local s = SexyMap2DB.backdrop.settings - if s.edgeFile and string.find(s.edgeFile, "%.blp$") then - s.edgeFile = string.gsub(s.edgeFile, "%.blp$", "") - print("[SexyMap] Migrated: removed .blp from backdrop edgeFile.") - end - if s.bgFile and string.find(s.bgFile, "%.blp$") then - s.bgFile = string.gsub(s.bgFile, "%.blp$", "") - print("[SexyMap] Migrated: removed .blp from backdrop bgFile.") - end - end - end - - -- Fix missing/empty shape - if SexyMap2DB.shape == nil or SexyMap2DB.shape == "" then - SexyMap2DB.shape = "Round" - end - - -- Ensure all expected fields exist - if SexyMap2DB.showZoneText == nil then - SexyMap2DB.showZoneText = true - end - if SexyMap2DB.showMinimapButtons == nil then - SexyMap2DB.showMinimapButtons = true - end - if SexyMap2DB.mapScale == nil then - SexyMap2DB.mapScale = 1.0 - end - if SexyMap2DB.showMinimap == nil then - SexyMap2DB.showMinimap = true - end - if not SexyMap2DB.userPresets then - SexyMap2DB.userPresets = {} - end - - -- Mark the current version so migration doesn't re-run needlessly - -- (but the checks above still protect against manually-edited bad data) - SexyMap2DB.version = ADDON_VERSION -end - -function CMap_OnLoad() - print("[SexyMap] v1.7 loaded for OctoWoW. Type '/sm' or '/sexymap' to open the menu.") - this:SetScript("OnEvent", CMap_OnEvent) - this:SetScript("OnUpdate", CMap_OnUpdate) - this:RegisterEvent("PLAYER_ENTERING_WORLD") -end - -function CMap_OnEvent() - if event == "PLAYER_ENTERING_WORLD" then - this:UnregisterEvent("PLAYER_ENTERING_WORLD") - - -- Run migration FIRST, before any settings are applied - MigrateSavedVariables() - - -- Capture the default minimap dimensions before we modify anything - defaultMinimapWidth = Minimap:GetWidth() - defaultMinimapHeight = Minimap:GetHeight() - - CreateFrame("Frame", "CMinimapBackdrop", Minimap) - CMinimapBackdrop:SetFrameStrata("BACKGROUND") - CMinimapBackdrop:SetFrameLevel(CMinimapBackdrop:GetFrameLevel() - 1) - CMinimapBackdrop:SetPoint("CENTER", Minimap, "CENTER") - CMinimapBackdrop:SetWidth(Minimap:GetWidth()) - CMinimapBackdrop:SetHeight(Minimap:GetHeight()) - -- Set an explicit default backdrop so the frame never renders as green - -- (a frame with no backdrop set can render as solid green in WoW 1.12) - CMinimapBackdrop:SetBackdrop({ - bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", - edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = false, - edgeSize = 16, - insets = { left = 4, right = 4, top = 4, bottom = 4 } - }) - CMinimapBackdrop:SetBackdropColor(0, 0, 0, 1) - CMinimapBackdrop:SetBackdropBorderColor(1, 1, 1, 1) - - CHideAnnoyingStuff() - CUpdateZoneText() - CUpdateMinimapButtonsVisibility() - CUpdateMinimapVisibility() - CApplyMapScale() - CLoadArtwork() - SlashCmdList["CMAP"] = CMap_SlashCmdHandler - SLASH_CMAP1 = "/cm" - SLASH_CMAP2 = "/sm" - SLASH_CMAP3 = "/sexymap" - end -end - - -function CMap_OnUpdate() - timeElapsed = timeElapsed + arg1 - if timeElapsed >= updateTime then - for k,v in pairs(CRotateTextures) do - CRotateTexture(_G[k], v * timeElapsed) - end - timeElapsed = 0 - end -end - - -function CMap_SlashCmdHandler(msg) - if not CMinimapOptionFrame.menuState then - CInitiateMenu() - else - CHideMenu() - end -end - - -function CHideAnnoyingStuff() - -- Hide the default minimap border art (we draw our own borders) - MinimapBorder:Hide() - MinimapBorderTop:Hide() - -- Hide the X button (minimap toggle) — we now control this from the GUI - MinimapToggleButton:Hide() - -- Hide zoom buttons ( SexyMap handles its own zoom or user doesn't need them ) - MinimapZoomIn:Hide() - MinimapZoomOut:Hide() - -- Style the zone text font - MinimapZoneText:SetFont("Fonts\\FRIZQT__.TTF", 11, "OUTLINE") -end - --- ============================================ --- Minimap visibility (replaces the X button) --- ============================================ --- In vanilla WoW 1.12, MinimapToggleButton calls ToggleMinimap() which --- hides/shows just the Minimap frame. We replace this with a full --- MinimapCluster hide/show controlled from the GUI, and hook Show/Hide --- to prevent anything from re-showing the minimap when it should be hidden. - -local function MinimapClusterHookedShow(self) - if not SexyMap2DB.showMinimap then - return -- Block the Show, minimap stays hidden - end - if minimapClusterOrigShow then - minimapClusterOrigShow(self) - end -end - -local function MinimapHookedShow(self) - if not SexyMap2DB.showMinimap then - return -- Block the Show, minimap stays hidden - end - if minimapOrigShow then - minimapOrigShow(self) - end -end - -function CUpdateMinimapVisibility() - if SexyMap2DB.showMinimap then - -- Show the minimap cluster - unhook first - if minimapClusterHooked then - if MinimapCluster then - MinimapCluster.Show = minimapClusterOrigShow - end - if Minimap then - Minimap.Show = minimapOrigShow - end - minimapClusterHooked = false - minimapClusterOrigShow = nil - minimapOrigShow = nil - end - -- Show everything - if MinimapCluster then MinimapCluster:Show() end - if Minimap then Minimap:Show() end - -- Re-apply our hidden stuff (borders, zoom buttons, X button stay hidden) - CHideAnnoyingStuff() - -- Re-apply button visibility settings - CUpdateMinimapButtonsVisibility() - else - -- Hide the entire minimap cluster and hook Show to prevent re-appearance - if MinimapCluster then - if not minimapClusterHooked then - minimapClusterOrigShow = MinimapCluster.Show - MinimapCluster.Show = MinimapClusterHookedShow - minimapOrigShow = Minimap.Show - Minimap.Show = MinimapHookedShow - minimapClusterHooked = true - end - MinimapCluster:Hide() - end - end -end - --- ============================================ --- Minimap buttons visibility --- ============================================ - -local function MinimapBtnHookedShow(self) - if not SexyMap2DB.showMinimapButtons then - return -- Block Show while buttons should be hidden - end - -- When buttons are allowed, call the original Show - local orig = hiddenBtnOrigShows[self] - if orig then - orig(self) - end -end - --- Save a frame's current anchor points so we can restore them later -local function SaveButtonPoints(frame) - local points = {} - local numPoints = frame:GetNumPoints() - if numPoints and numPoints > 0 then - for i = 1, numPoints do - local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint(i) - if point then - table.insert(points, { - point = point, - relativeTo = relativeTo, - relativePoint = relativePoint, - xOfs = xOfs, - yOfs = yOfs, - }) - end - end - end - -- Only store if we actually got points; don't overwrite existing saved points with empty - if table.getn(points) > 0 then - hiddenBtnOrigPoints[frame] = points - end -end - --- Restore a frame's saved anchor points -local function RestoreButtonPoints(frame) - local points = hiddenBtnOrigPoints[frame] - if points and table.getn(points) > 0 then - frame:ClearAllPoints() - for _, pt in ipairs(points) do - frame:SetPoint(pt.point, pt.relativeTo, pt.relativePoint, pt.xOfs, pt.yOfs) - end - end - -- Clean up saved points for this frame - hiddenBtnOrigPoints[frame] = nil -end - -function CUpdateMinimapButtonsVisibility() - if SexyMap2DB.showMinimapButtons then - -- Show only the buttons we previously hid (preserves original visibility) - for _, btn in ipairs(hiddenMinimapButtons) do - if btn then - -- Restore original Show - local orig = hiddenBtnOrigShows[btn] - if orig then - btn.Show = orig - hiddenBtnOrigShows[btn] = nil - end - -- Restore saved anchor points (preserves button positions across hide/show) - RestoreButtonPoints(btn) - btn:Show() - end - end - hiddenMinimapButtons = {} - else - -- Find and hide only VISIBLE minimap buttons, hook their Show - hiddenMinimapButtons = {} - local children = { Minimap:GetChildren() } - for idx, frame in ipairs(children) do - local objType = frame:GetObjectType() - if objType == "Button" or objType == "CheckButton" then - local name = frame:GetName() or "" - -- Skip our own frames and WoW native controls we already hide - if name ~= "MinimapZoomIn" and name ~= "MinimapZoomOut" - and name ~= "MinimapToggleButton" and name ~= "GameTimeFrame" - and name ~= "CMinimapBackdrop" then - -- Only hide buttons that are currently visible - -- (buttons already hidden by other addons should stay hidden) - if frame:IsVisible() then - -- Save anchor points before hiding so we can restore them later - SaveButtonPoints(frame) - -- Hook Show to prevent re-appearance - if not hiddenBtnOrigShows[frame] then - hiddenBtnOrigShows[frame] = frame.Show - frame.Show = MinimapBtnHookedShow - end - frame:Hide() - table.insert(hiddenMinimapButtons, frame) - end - end - end - end - -- Also hide known WoW minimap frames by name (only if visible) - local knownFrames = { - "MiniMapTracking", - "MiniMapTrackingButton", - "MiniMapTrackingFrame", - "MiniMapMailFrame", - "MiniMapMailBorder", - "MiniMapBattlefieldFrame", - "MiniMapMeetingStoneFrame", - "MiniMapWorldMapButton", - "MinimapVoiceChatFrame", - "MiniMapLFGFrame", - } - for _, frameName in ipairs(knownFrames) do - local frame = _G[frameName] - if frame and frame:IsVisible() then - -- Save anchor points before hiding so we can restore them later - SaveButtonPoints(frame) - if not hiddenBtnOrigShows[frame] then - hiddenBtnOrigShows[frame] = frame.Show - frame.Show = MinimapBtnHookedShow - end - frame:Hide() - table.insert(hiddenMinimapButtons, frame) - end - end - end -end - - -function CApplyMapScale() - local scale = SexyMap2DB.mapScale or 1.0 - if scale < 0.3 then scale = 0.3 end - if scale > 1.0 then scale = 1.0 end - SexyMap2DB.mapScale = scale - - -- Apply scale to the MinimapCluster which contains everything - MinimapCluster:SetScale(scale) - - -- Re-anchor to TOPRIGHT - the anchor point is TOPRIGHT so when scaled down, - -- the right side and top stay put, while the left and bottom move inward - MinimapCluster:ClearAllPoints() - MinimapCluster:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -14, 10) - - -- Update backdrop to match current minimap size - CMinimapBackdrop:SetWidth(Minimap:GetWidth()) - CMinimapBackdrop:SetHeight(Minimap:GetHeight()) - - -- Update border textures to match new minimap size - CUpdateBackdrop() -end - -function CUpdateZoneText() - MinimapCluster:ClearAllPoints() - -- Map position: always anchored TOPRIGHT so scale keeps right/top fixed - MinimapCluster:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -14, 10) - MinimapZoneText:ClearAllPoints() - if SexyMap2DB.showZoneText then - MinimapZoneText:Show() - -- Zone name positioned below the minimap - MinimapZoneText:SetPoint("TOP", Minimap, "BOTTOM", 0, -20) - else - -- Only hide the zone text; map and border do NOT move - MinimapZoneText:Hide() - end -end - --- ============================================ --- Set Defaults - resets all settings to factory --- ============================================ -function CSetDefaults() - -- Reset all SavedVariables to defaults - SexyMap2DB.borders = deepCopyHash(borderPresets["Diablo by Zork"].borders) - SexyMap2DB.backdrop = deepCopyHash(borderPresets["Diablo by Zork"].backdrop) - SexyMap2DB.shape = "Round" - SexyMap2DB.userPresets = {} - SexyMap2DB.showZoneText = true - SexyMap2DB.showMinimapButtons = true - SexyMap2DB.mapScale = 1.0 - SexyMap2DB.showMinimap = true - SexyMap2DB.version = ADDON_VERSION - - -- Reapply everything - CHideAnnoyingStuff() - CUpdateZoneText() - CUpdateMinimapButtonsVisibility() - CUpdateMinimapVisibility() - CApplyMapScale() - CClearArtwork() - CLoadArtwork() - - -- Refresh the GUI if it's open - if CMinimapOptionFrame and CMinimapOptionFrame.menuState then - CUpdatePresetList() - CUpdateShapeList() - CTexture_Update() - CZoneTextToggle_Update() - CMinimapButtonsToggle_Update() - CMinimapToggle_Update() - CMapScaleSlider_Update() - CVariable_Update() - end - - print("[SexyMap] All settings reset to defaults.") -end - -function CClearArtwork() - for k,v in pairs(CTextures) do - _G[k]:SetTexCoord(0,1,0,1) - _G[k]:Hide() - end - destroyTable(CTextures) - CTextures = {} - destroyTable(CRotateTextures) - CRotateTextures = {} -end - - -function CLoadArtwork() - if SexyMap2DB.shape then - CApplyShape(SexyMap2DB.shape) - end - for k,v in ipairs(SexyMap2DB.borders) do - CCreateBorder(v) - end - CUpdateBackdrop() -end - - -function CUpdateBackdrop() - if not SexyMap2DB.backdrop or not SexyMap2DB.backdrop.show then - CMinimapBackdrop:Hide() - else - local backdrop = CMinimapBackdrop - backdrop:Show() - backdrop:SetWidth(Minimap:GetWidth() * (SexyMap2DB.backdrop.scale or 1)) - backdrop:SetHeight(Minimap:GetHeight() * (SexyMap2DB.backdrop.scale or 1)) - - -- Validate the backdrop settings before applying. - -- If edgeFile or bgFile references are invalid, WoW 1.12 renders the frame - -- as solid green (missing texture fallback). We check that the paths exist - -- in the settings table before calling SetBackdrop. - local settings = SexyMap2DB.backdrop.settings - if settings then - -- Ensure edgeFile doesn't have .blp extension (WoW 1.12 auto-appends it) - if settings.edgeFile and string.find(settings.edgeFile, "%.blp$") then - settings.edgeFile = string.gsub(settings.edgeFile, "%.blp$", "") - end - if settings.bgFile and string.find(settings.bgFile, "%.blp$") then - settings.bgFile = string.gsub(settings.bgFile, "%.blp$", "") - end - backdrop:SetBackdrop(settings) - end - - -- Set backdrop color with safe defaults for empty/missing color tables - local c = SexyMap2DB.backdrop.textureColor - if c and (c.r or c.g or c.b or c.a) then - backdrop:SetBackdropColor(c.r or 0, c.g or 0, c.b or 0, c.a or 1) - else - -- Default: black background, full opacity - backdrop:SetBackdropColor(0, 0, 0, 1) - end - - -- Set border color with safe defaults for empty/missing color tables - c = SexyMap2DB.backdrop.borderColor - if c and (c.r or c.g or c.b or c.a) then - backdrop:SetBackdropBorderColor(c.r or 1, c.g or 1, c.b or 1, c.a or 1) - else - -- Default: white border, full opacity - backdrop:SetBackdropBorderColor(1, 1, 1, 1) - end - end -end