-------------------------------------------------------------------------------- -- Nanami-UI: Minimap Skin (Minimap.lua) -- Custom cat-paw pixel art frame for the minimap -------------------------------------------------------------------------------- SFrames.Minimap = SFrames.Minimap or {} local MM = SFrames.Minimap local _A = SFrames.ActiveTheme local MAP_STYLES = { { key = "map", tex = "Interface\\AddOns\\Nanami-UI\\img\\map", label = "猫爪", plateY = -10, textColor = {0.45, 0.32, 0.20} }, { key = "zs", tex = "Interface\\AddOns\\Nanami-UI\\img\\zs", label = "战士", plateY = -6, textColor = {1, 1, 1} }, { key = "qs", tex = "Interface\\AddOns\\Nanami-UI\\img\\qs", label = "圣骑士", plateY = -6, textColor = {0.22, 0.13, 0.07} }, { key = "lr", tex = "Interface\\AddOns\\Nanami-UI\\img\\lr", label = "猎人", plateY = -6, textColor = {1, 1, 1} }, { key = "qxz", tex = "Interface\\AddOns\\Nanami-UI\\img\\qxz", label = "潜行者", plateY = -6, textColor = {1, 1, 1} }, { key = "ms", tex = "Interface\\AddOns\\Nanami-UI\\img\\ms", label = "牧师", plateY = -6, textColor = {0.22, 0.13, 0.07} }, { key = "sm", tex = "Interface\\AddOns\\Nanami-UI\\img\\sm", label = "萨满", plateY = -6, textColor = {1, 1, 1} }, { key = "fs", tex = "Interface\\AddOns\\Nanami-UI\\img\\fs", label = "法师", plateY = -6, textColor = {1, 1, 1} }, { key = "ss", tex = "Interface\\AddOns\\Nanami-UI\\img\\ss", label = "术士", plateY = -6, textColor = {1, 1, 1} }, { key = "dly", tex = "Interface\\AddOns\\Nanami-UI\\img\\dly", label = "德鲁伊", plateY = -6, textColor = {0.22, 0.13, 0.07} }, } local SQUARE_STYLES = { { key = "square1", label = "方形·金", tex = "Interface\\AddOns\\Nanami-UI\\img\\map_f_1", texSize = 512, mapX = 9, mapY = 9, mapW = 486, mapH = 486, zoneOverlay = true, textColor = {0.85, 0.75, 0.55}, }, { key = "square2", label = "方形·暗", tex = "Interface\\AddOns\\Nanami-UI\\img\\map_f_2", texSize = 512, mapX = 52, mapY = 61, mapW = 418, mapH = 418, zonePlateX = 104, zonePlateY = 18, zonePlateW = 302, zonePlateH = 45, textColor = {0.8, 0.8, 0.8}, }, } local SQUARE_MASK = "Interface\\BUTTONS\\WHITE8X8" local TEX_SIZE = 512 local CIRCLE_CX = 256 local CIRCLE_CY = 256 local CIRCLE_R = 210 local PLATE_X = 103 local PLATE_Y = 29 local PLATE_W = 200 local PLATE_H = 66 local BASE_SIZE = 180 local CLASS_STYLE_MAP = { ["Warrior"] = "zs", ["WARRIOR"] = "zs", ["战士"] = "zs", ["Paladin"] = "qs", ["PALADIN"] = "qs", ["圣骑士"] = "qs", ["Hunter"] = "lr", ["HUNTER"] = "lr", ["猎人"] = "lr", ["Rogue"] = "qxz", ["ROGUE"] = "qxz", ["潜行者"] = "qxz", ["Priest"] = "ms", ["PRIEST"] = "ms", ["牧师"] = "ms", ["Shaman"] = "sm", ["SHAMAN"] = "sm", ["萨满祭司"] = "sm", ["Mage"] = "fs", ["MAGE"] = "fs", ["法师"] = "fs", ["Warlock"] = "ss", ["WARLOCK"] = "ss", ["术士"] = "ss", ["Druid"] = "dly", ["DRUID"] = "dly", ["德鲁伊"] = "dly", } local DEFAULTS = { enabled = true, scale = 1.0, showClock = true, showCoords = true, mapStyle = "auto", mapShape = "square1", posX = -5, posY = -5, mailIconX = nil, mailIconY = nil, } local container, overlayFrame, overlayTex local zoneFs, clockFs, clockBg, coordFs, zoneBg local built = false -------------------------------------------------------------------------------- -- Helpers -------------------------------------------------------------------------------- local function GetDB() if not SFramesDB then SFramesDB = {} end if type(SFramesDB.Minimap) ~= "table" then SFramesDB.Minimap = {} end local db = SFramesDB.Minimap for k, v in pairs(DEFAULTS) do if db[k] == nil then db[k] = v end end return db end local function IsMapStateProtected() if WorldMapFrame and WorldMapFrame:IsVisible() then return true end if BattlefieldMinimap and BattlefieldMinimap:IsVisible() then return true end if BattlefieldMinimapFrame and BattlefieldMinimapFrame:IsVisible() then return true end return false end local function ResolveStyleKey() local key = GetDB().mapStyle or "auto" if key == "auto" then local localName, engName = UnitClass("player") key = CLASS_STYLE_MAP[engName] or CLASS_STYLE_MAP[localName] or "map" end return key end local function GetCurrentStyle() local key = ResolveStyleKey() for _, s in ipairs(MAP_STYLES) do if s.key == key then return s end end return MAP_STYLES[1] end local function GetMapTexture() return GetCurrentStyle().tex end local function IsSquareShape() local shape = GetDB().mapShape or "square1" return shape == "square1" or shape == "square2" end local function GetSquareStyle() local shape = GetDB().mapShape or "square1" for _, s in ipairs(SQUARE_STYLES) do if s.key == shape then return s end end return SQUARE_STYLES[1] end local function S(texPx, frameSize) return texPx / TEX_SIZE * frameSize end local function FrameSize() return math.floor(BASE_SIZE * ((GetDB().scale) or 1)) end local function ApplyPosition() if not container then return end local pos = SFramesDB and SFramesDB.Positions and SFramesDB.Positions["Minimap"] if pos and pos.point and pos.relativePoint then container:ClearAllPoints() container:SetPoint(pos.point, UIParent, pos.relativePoint, pos.xOfs or 0, pos.yOfs or 0) else local db = GetDB() local x = tonumber(db.posX) or -5 local y = tonumber(db.posY) or -5 container:ClearAllPoints() container:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", x, y) end end local function HideTooltipIfOwned(frame) if not frame or not GameTooltip or not GameTooltip:IsVisible() then return end if GameTooltip.IsOwned and GameTooltip:IsOwned(frame) then GameTooltip:Hide() return end if GameTooltip.GetOwner and GameTooltip:GetOwner() == frame then GameTooltip:Hide() end end local function ForceHideMinimapFrame(frame) if not frame then return end HideTooltipIfOwned(frame) if frame.EnableMouse then frame:EnableMouse(false) end if frame.Hide then frame:Hide() end if frame.SetAlpha then frame:SetAlpha(0) end frame.Show = function() end end -------------------------------------------------------------------------------- -- Hide default Blizzard minimap chrome -- MUST be called AFTER BuildFrame (Minimap is already reparented) -------------------------------------------------------------------------------- local function HideDefaultElements() local kill = { MinimapBorder, MinimapBorderTop, MinimapZoomIn, MinimapZoomOut, MinimapToggleButton, MiniMapWorldMapButton, GameTimeFrame, TimeManagerClockButton, MinimapZoneTextButton, MiniMapTracking, MinimapBackdrop, } for _, f in ipairs(kill) do ForceHideMinimapFrame(f) end -- Hide all tracking-related frames (Turtle WoW dual tracking, etc.) local trackNames = { "MiniMapTrackingButton", "MiniMapTrackingFrame", "MiniMapTrackingIcon", "MiniMapTracking1", "MiniMapTracking2", } for _, name in ipairs(trackNames) do local f = _G[name] ForceHideMinimapFrame(f) end -- Also hide any tracking textures that are children of Minimap if Minimap.GetChildren then local children = { Minimap:GetChildren() } for _, child in ipairs(children) do local n = child.GetName and child:GetName() if n and string.find(n, "Track") then ForceHideMinimapFrame(child) end end end -- Move MinimapCluster off-screen instead of Hide() -- Hide() would cascade-hide children that were still parented at load time if MinimapCluster then MinimapCluster:ClearAllPoints() MinimapCluster:SetPoint("TOP", UIParent, "BOTTOM", 0, -500) MinimapCluster:SetWidth(1) MinimapCluster:SetHeight(1) MinimapCluster:EnableMouse(false) end end -------------------------------------------------------------------------------- -- Build -------------------------------------------------------------------------------- local function BuildFrame() if built then return end built = true local fs = FrameSize() local isSquare = IsSquareShape() -- Main container container = CreateFrame("Frame", "SFramesMinimapContainer", UIParent) container:SetWidth(fs) container:SetHeight(fs) container:SetFrameStrata("LOW") container:SetFrameLevel(1) container:EnableMouse(false) container:SetClampedToScreen(true) -- Reparent the actual minimap into our container Minimap:SetParent(container) Minimap:ClearAllPoints() if isSquare then local sq = GetSquareStyle() local mapW = sq.mapW / sq.texSize * fs local mapH = sq.mapH / sq.texSize * fs local cx = (sq.mapX + sq.mapW / 2) / sq.texSize * fs local cy = (sq.mapY + sq.mapH / 2) / sq.texSize * fs Minimap:SetPoint("CENTER", container, "TOPLEFT", cx, -cy) Minimap:SetWidth(mapW) Minimap:SetHeight(mapH) else local mapDiam = math.floor(S((CIRCLE_R + 8) * 2, fs)) Minimap:SetPoint("CENTER", container, "TOPLEFT", S(CIRCLE_CX, fs), -S(CIRCLE_CY, fs)) Minimap:SetWidth(mapDiam) Minimap:SetHeight(mapDiam) end Minimap:SetFrameStrata("LOW") Minimap:SetFrameLevel(2) Minimap:Show() if Minimap.SetMaskTexture then if isSquare then Minimap:SetMaskTexture(SQUARE_MASK) else Minimap:SetMaskTexture("Textures\\MinimapMask") end end -- Decorative overlay (frame texture) overlayFrame = CreateFrame("Frame", nil, container) overlayFrame:SetAllPoints(container) overlayFrame:SetFrameStrata("LOW") overlayFrame:SetFrameLevel(Minimap:GetFrameLevel() + 3) overlayFrame:EnableMouse(false) overlayTex = overlayFrame:CreateTexture(nil, "ARTWORK") if isSquare then overlayTex:SetTexture(GetSquareStyle().tex) else overlayTex:SetTexture(GetMapTexture()) end overlayTex:SetAllPoints(overlayFrame) -- Zone name background (semi-transparent strip for square styles) zoneBg = CreateFrame("Frame", nil, overlayFrame) zoneBg:SetFrameLevel(overlayFrame:GetFrameLevel() - 1) zoneBg:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", }) zoneBg:SetBackdropColor(0, 0, 0, 0.5) zoneBg:Hide() -- Zone name zoneFs = overlayFrame:CreateFontString(nil, "OVERLAY") zoneFs:SetJustifyH("CENTER") zoneFs:SetJustifyV("MIDDLE") if isSquare then local sq = GetSquareStyle() zoneFs:SetFont(SFrames:GetFont(), 11, "OUTLINE") if sq.zonePlateX then local px = (sq.zonePlateX + sq.zonePlateW / 2) / sq.texSize * fs local py = (sq.zonePlateY + sq.zonePlateH / 2) / sq.texSize * fs zoneFs:SetPoint("CENTER", container, "TOPLEFT", px, -py) zoneFs:SetWidth(sq.zonePlateW / sq.texSize * fs) zoneFs:SetHeight(sq.zonePlateH / sq.texSize * fs) else zoneFs:SetPoint("TOP", Minimap, "TOP", 0, -3) zoneFs:SetWidth(Minimap:GetWidth() * 0.7) zoneFs:SetHeight(18) zoneBg:ClearAllPoints() zoneBg:SetPoint("TOP", Minimap, "TOP", 0, 0) zoneBg:SetWidth(Minimap:GetWidth()) zoneBg:SetHeight(20) zoneBg:Show() end local tc = sq.textColor or {1, 1, 1} zoneFs:SetTextColor(tc[1], tc[2], tc[3]) else local style = GetCurrentStyle() zoneFs:SetFont(SFrames:GetFont(), 11, "") local pcy = S(PLATE_Y + PLATE_H / 2 + (style.plateY or -6), fs) zoneFs:SetPoint("CENTER", container, "TOP", 0, -pcy) zoneFs:SetWidth(S(PLATE_W + 60, fs)) zoneFs:SetHeight(S(PLATE_H, fs)) local tc = style.textColor or {0.22, 0.13, 0.07} zoneFs:SetTextColor(tc[1], tc[2], tc[3]) end -- Clock background (semi-transparent rounded) clockBg = CreateFrame("Frame", nil, overlayFrame) clockBg:SetFrameLevel(overlayFrame:GetFrameLevel() + 1) clockBg:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = { left = 2, right = 2, top = 2, bottom = 2 }, }) local _clkBg = _A.clockBg or { 0, 0, 0, 0.55 } local _clkBd = _A.clockBorder or { 0, 0, 0, 0.3 } clockBg:SetBackdropColor(_clkBg[1], _clkBg[2], _clkBg[3], _clkBg[4]) clockBg:SetBackdropBorderColor(_clkBd[1], _clkBd[2], _clkBd[3], _clkBd[4]) clockBg:SetWidth(46) clockBg:SetHeight(18) if isSquare then clockBg:SetPoint("TOP", Minimap, "BOTTOM", 0, -2) else clockBg:SetPoint("CENTER", container, "BOTTOM", 0, S((TEX_SIZE - CIRCLE_CY - CIRCLE_R) / 2, fs)) end -- Clock text clockFs = clockBg:CreateFontString(nil, "OVERLAY") clockFs:SetFont(SFrames:GetFont(), 10, "OUTLINE") clockFs:SetPoint("CENTER", clockBg, "CENTER", 0, 0) clockFs:SetJustifyH("CENTER") local _clkTxt = _A.clockText or { 0.92, 0.84, 0.72 } clockFs:SetTextColor(_clkTxt[1], _clkTxt[2], _clkTxt[3]) -- Coordinates (inside map area, near bottom) coordFs = overlayFrame:CreateFontString(nil, "OVERLAY") coordFs:SetFont(SFrames:GetFont(), 9, "OUTLINE") coordFs:SetPoint("BOTTOM", Minimap, "BOTTOM", 0, 8) coordFs:SetJustifyH("CENTER") local _coordTxt = _A.coordText or { 0.80, 0.80, 0.80 } coordFs:SetTextColor(_coordTxt[1], _coordTxt[2], _coordTxt[3]) MM.container = container MM.overlayFrame = overlayFrame end -------------------------------------------------------------------------------- -- Interactions -------------------------------------------------------------------------------- local function SetupScrollZoom() Minimap:EnableMouseWheel(true) Minimap:SetScript("OnMouseWheel", function() if arg1 > 0 then Minimap_ZoomIn() else Minimap_ZoomOut() end end) end local function SetupMouseHandler() Minimap:SetScript("OnMouseUp", function() if arg1 == "RightButton" then if MiniMapTrackingDropDown then ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, "cursor") end else if Minimap_OnClick then Minimap_OnClick(this) end end end) end MM.ApplyPosition = ApplyPosition -------------------------------------------------------------------------------- -- Reposition child icons -------------------------------------------------------------------------------- local function SetupMailDragging() if not MiniMapMailFrame then return end MiniMapMailFrame:SetMovable(true) MiniMapMailFrame:EnableMouse(true) MiniMapMailFrame:RegisterForDrag("LeftButton") MiniMapMailFrame:SetScript("OnDragStart", function() MiniMapMailFrame:StartMoving() end) MiniMapMailFrame:SetScript("OnDragStop", function() MiniMapMailFrame:StopMovingOrSizing() local db = GetDB() local cx, cy = MiniMapMailFrame:GetCenter() local ux, uy = UIParent:GetCenter() if cx and cy and ux and uy then db.mailIconX = cx - ux db.mailIconY = cy - uy end end) end local function RepositionIcons() if MiniMapMailFrame then local db = GetDB() MiniMapMailFrame:ClearAllPoints() if db.mailIconX and db.mailIconY then MiniMapMailFrame:SetPoint("CENTER", UIParent, "CENTER", db.mailIconX, db.mailIconY) else local mapDiam = Minimap:GetWidth() MiniMapMailFrame:SetPoint("RIGHT", Minimap, "RIGHT", 8, mapDiam * 0.12) end MiniMapMailFrame:SetFrameStrata("LOW") MiniMapMailFrame:SetFrameLevel((overlayFrame and overlayFrame:GetFrameLevel() or 5) + 2) SetupMailDragging() end if MiniMapBattlefieldFrame then MiniMapBattlefieldFrame:ClearAllPoints() MiniMapBattlefieldFrame:SetPoint("BOTTOMLEFT", Minimap, "BOTTOM", 15, -8) MiniMapBattlefieldFrame:SetFrameStrata("LOW") MiniMapBattlefieldFrame:SetFrameLevel((overlayFrame and overlayFrame:GetFrameLevel() or 5) + 2) end end -------------------------------------------------------------------------------- -- Update helpers -------------------------------------------------------------------------------- local function UpdateZoneText() if not zoneFs then return end local text = GetMinimapZoneText and GetMinimapZoneText() or "" lastZoneText = text zoneFs:SetText(text) end local function SetZoneMap() if IsMapStateProtected() then return end if SetMapToCurrentZone then if SFrames and SFrames.CallWithPreservedBattlefieldMinimap then SFrames:CallWithPreservedBattlefieldMinimap(SetMapToCurrentZone) else pcall(SetMapToCurrentZone) end end end local clockTimer = 0 local coordTimer = 0 local zoneTimer = 0 local lastZoneText = "" local function OnUpdate() local dt = arg1 or 0 local db = GetDB() -- Clock (every 1 s) clockTimer = clockTimer + dt if clockTimer >= 1 then clockTimer = 0 if db.showClock and clockFs then local timeStr if date then timeStr = date("%H:%M") else local h, m = GetGameTime() timeStr = string.format("%02d:%02d", h, m) end clockFs:SetText(timeStr) clockFs:Show() if clockBg then clockBg:Show() end elseif clockFs then clockFs:Hide() if clockBg then clockBg:Hide() end end end -- Zone text (every 1 s) – catches late API updates missed by events zoneTimer = zoneTimer + dt if zoneTimer >= 1 then zoneTimer = 0 if zoneFs and GetMinimapZoneText then local cur = GetMinimapZoneText() or "" if cur ~= lastZoneText then lastZoneText = cur zoneFs:SetText(cur) end end end -- Coordinates (every 0.25 s) coordTimer = coordTimer + dt if coordTimer >= 0.25 then coordTimer = 0 if db.showCoords and coordFs and GetPlayerMapPosition then local ok, x, y = pcall(GetPlayerMapPosition, "player") if ok and x and y and (x > 0 or y > 0) then coordFs:SetText(string.format("%.1f, %.1f", x * 100, y * 100)) coordFs:Show() else coordFs:Hide() end elseif coordFs then coordFs:Hide() end end end -------------------------------------------------------------------------------- -- Public API -------------------------------------------------------------------------------- function MM:Refresh() if not container then return end local fs = FrameSize() local isSquare = IsSquareShape() container:SetWidth(fs) container:SetHeight(fs) -- Apply mask if Minimap.SetMaskTexture then if isSquare then Minimap:SetMaskTexture(SQUARE_MASK) else Minimap:SetMaskTexture("Textures\\MinimapMask") end end -- Position and size minimap Minimap:ClearAllPoints() if isSquare then local sq = GetSquareStyle() local mapW = sq.mapW / sq.texSize * fs local mapH = sq.mapH / sq.texSize * fs local cx = (sq.mapX + sq.mapW / 2) / sq.texSize * fs local cy = (sq.mapY + sq.mapH / 2) / sq.texSize * fs Minimap:SetPoint("CENTER", container, "TOPLEFT", cx, -cy) Minimap:SetWidth(mapW) Minimap:SetHeight(mapH) else local mapDiam = math.floor(S((CIRCLE_R + 8) * 2, fs)) Minimap:SetPoint("CENTER", container, "TOPLEFT", S(CIRCLE_CX, fs), -S(CIRCLE_CY, fs)) Minimap:SetWidth(mapDiam) Minimap:SetHeight(mapDiam) end -- Update overlay texture if overlayTex then if isSquare then overlayTex:SetTexture(GetSquareStyle().tex) else overlayTex:SetTexture(GetMapTexture()) end end -- Update zone text if zoneFs then zoneFs:ClearAllPoints() if isSquare then local sq = GetSquareStyle() zoneFs:SetFont(SFrames:GetFont(), 11, "OUTLINE") if sq.zonePlateX then local px = (sq.zonePlateX + sq.zonePlateW / 2) / sq.texSize * fs local py = (sq.zonePlateY + sq.zonePlateH / 2) / sq.texSize * fs zoneFs:SetPoint("CENTER", container, "TOPLEFT", px, -py) zoneFs:SetWidth(sq.zonePlateW / sq.texSize * fs) zoneFs:SetHeight(sq.zonePlateH / sq.texSize * fs) else zoneFs:SetPoint("TOP", Minimap, "TOP", 0, -3) zoneFs:SetWidth(Minimap:GetWidth() * 0.7) zoneFs:SetHeight(18) end local tc = sq.textColor or {1, 1, 1} zoneFs:SetTextColor(tc[1], tc[2], tc[3]) else zoneFs:SetFont(SFrames:GetFont(), 11, "") local style = GetCurrentStyle() local pcy = S(PLATE_Y + PLATE_H / 2 + (style.plateY or -6), fs) zoneFs:SetPoint("CENTER", container, "TOP", 0, -pcy) zoneFs:SetWidth(S(PLATE_W + 60, fs)) local tc = style.textColor or {0.22, 0.13, 0.07} zoneFs:SetTextColor(tc[1], tc[2], tc[3]) end end -- Zone background (semi-transparent strip, only for square styles with zoneOverlay) if zoneBg then if isSquare and GetSquareStyle().zoneOverlay then zoneBg:ClearAllPoints() zoneBg:SetPoint("TOP", Minimap, "TOP", 0, 0) zoneBg:SetWidth(Minimap:GetWidth()) zoneBg:SetHeight(20) zoneBg:Show() else zoneBg:Hide() end end -- Clock if clockBg then clockBg:ClearAllPoints() if isSquare then clockBg:SetPoint("TOP", Minimap, "BOTTOM", 0, -2) else clockBg:SetPoint("CENTER", container, "BOTTOM", 0, S((TEX_SIZE - CIRCLE_CY - CIRCLE_R) / 2, fs)) end end -- Coords if coordFs then coordFs:ClearAllPoints() coordFs:SetPoint("BOTTOM", Minimap, "BOTTOM", 0, 8) end UpdateZoneText() RepositionIcons() end MM.MAP_STYLES = MAP_STYLES MM.SQUARE_STYLES = SQUARE_STYLES -------------------------------------------------------------------------------- -- Shield: re-apply our skin after other addons (ShaguTweaks etc.) touch Minimap -------------------------------------------------------------------------------- local shielded = false local function ShieldMinimap() if shielded then return end shielded = true if Minimap:GetParent() ~= container then Minimap:SetParent(container) end local fs = FrameSize() local isSquare = IsSquareShape() Minimap:ClearAllPoints() if isSquare then local sq = GetSquareStyle() local mapW = sq.mapW / sq.texSize * fs local mapH = sq.mapH / sq.texSize * fs local cx = (sq.mapX + sq.mapW / 2) / sq.texSize * fs local cy = (sq.mapY + sq.mapH / 2) / sq.texSize * fs Minimap:SetPoint("CENTER", container, "TOPLEFT", cx, -cy) Minimap:SetWidth(mapW) Minimap:SetHeight(mapH) else local mapDiam = math.floor(S((CIRCLE_R + 8) * 2, fs)) Minimap:SetPoint("CENTER", container, "TOPLEFT", S(CIRCLE_CX, fs), -S(CIRCLE_CY, fs)) Minimap:SetWidth(mapDiam) Minimap:SetHeight(mapDiam) end Minimap:SetFrameStrata("LOW") Minimap:SetFrameLevel(2) Minimap:Show() if Minimap.SetMaskTexture then if isSquare then Minimap:SetMaskTexture(SQUARE_MASK) else Minimap:SetMaskTexture("Textures\\MinimapMask") end end HideDefaultElements() -- Kill any border/backdrop that ShaguTweaks may have injected local regions = { Minimap:GetRegions() } for _, r in ipairs(regions) do if r and r:IsObjectType("Texture") then local tex = r.GetTexture and r:GetTexture() if tex and type(tex) == "string" then local low = string.lower(tex) if string.find(low, "border") or string.find(low, "backdrop") or string.find(low, "overlay") or string.find(low, "background") then r:Hide() end end end end shielded = false end function MM:Initialize() if not Minimap then return end local db = GetDB() if db.enabled == false then return end local ok, err = pcall(function() -- Build first (reparents Minimap), THEN hide old chrome BuildFrame() HideDefaultElements() -- Ensure Minimap is visible after reparent Minimap:Show() SetupScrollZoom() SetupMouseHandler() -- Apply position from settings ApplyPosition() RepositionIcons() -- Zone text events SFrames:RegisterEvent("ZONE_CHANGED", function() SetZoneMap() UpdateZoneText() end) SFrames:RegisterEvent("ZONE_CHANGED_NEW_AREA", function() SetZoneMap() UpdateZoneText() end) SFrames:RegisterEvent("ZONE_CHANGED_INDOORS", function() SetZoneMap() UpdateZoneText() end) -- Re-apply after other addons finish loading (ShaguTweaks etc.) SFrames:RegisterEvent("PLAYER_ENTERING_WORLD", function() pcall(ShieldMinimap) pcall(UpdateZoneText) end) -- Delayed zone text: GetMinimapZoneText() may be empty at PLAYER_LOGIN local zoneDelay = CreateFrame("Frame") local elapsed = 0 zoneDelay:SetScript("OnUpdate", function() elapsed = elapsed + (arg1 or 0) if elapsed >= 1 then zoneDelay:SetScript("OnUpdate", nil) pcall(SetZoneMap) pcall(UpdateZoneText) end end) -- Tick container:SetScript("OnUpdate", OnUpdate) -- First refresh SetZoneMap() UpdateZoneText() MM:Refresh() end) if not ok then DEFAULT_CHAT_FRAME:AddMessage("|cffff4444Nanami-UI Minimap error: " .. tostring(err) .. "|r") end if SFrames.Movers and SFrames.Movers.RegisterMover and container then SFrames.Movers:RegisterMover("Minimap", container, "小地图", "TOPRIGHT", "UIParent", "TOPRIGHT", db.posX or -5, db.posY or -5, function() pcall(RepositionIcons) end) end end