Update mapreveal overlay data for Turtle WoW

env/tables.lua — Updated pfMapOverlayData to current Turtle WoW WorldMapOverlay.dbc (53 zones, 707 overlays — added 12 new zones, ~40 new exploration areas)

modules/mapreveal.lua — Use separate texture pool to prevent conflicts with Blizzard overlay rendering; removed legacy errata and unused hash logic
This commit is contained in:
Meow
2026-03-20 12:37:25 +01:00
parent 0917caa80e
commit 3a1b24ddd5
2 changed files with 135 additions and 149 deletions
+81 -108
View File
@@ -1,5 +1,4 @@
pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
-- do not load if other map addon is loaded
if Cartographer then return end
if METAMAP_TITLE then return end
@@ -31,22 +30,6 @@ pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
pfUI.mapreveal:UpdateConfig()
end)
local errata = {
["Interface\\WorldMap\\Tirisfal\\BRIGHTWATERLAKE"] = {offsetX={587,584}},
["Interface\\WorldMap\\Silverpine\\BERENSPERIL"] = {offsetY={417,415}},
}
local function create_hash(prefix, textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY)
local hash = string.format(":%s:%s:%s:%s",textureWidth,textureHeight,offsetX,offsetY)
if (mapPointX ~= 0 or mapPointY ~= 0) then
hash = string.format("%s:%s:%s",hash,tostring(mapPointX),tostring(mapPointY))
end
if string.sub(textureName, 0, string.len(prefix)) == prefix then
return string.format("%s%s",string.sub(textureName, string.len(prefix) + 1),hash)
end
return string.format("|%s",hash)
end
local function unpack_hash(prefix, hash)
local _, stored_prefix, textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY, name
_, _, stored_prefix, textureName, textureWidth, textureHeight, offsetX, offsetY = string.find(hash, "^([|]?)([^:]+):([^:]+):([^:]+):([^:]+):([^:]+)")
@@ -63,14 +46,23 @@ pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
name = textureName
textureName = string.format("%s%s",prefix,textureName)
end
-- coerce to number by addition; cheaper than tonumber()
return textureName, textureWidth + 0, textureHeight + 0, offsetX + 0, offsetY + 0, mapPointX + 0, mapPointY + 0, name
end
local explores = {}
local explorecaches = {}
local alreadyknown = {}
local BASE_WORLDMAP_OVERLAYS = nil
-- Own texture pool - separate from Blizzard's WorldMapOverlay textures
local pfOverlays = {}
local pfOverlayMax = 0
local function pfGetOverlay(idx)
if not pfOverlays[idx] then
pfOverlays[idx] = WorldMapDetailFrame:CreateTexture("pfReveal"..idx, "ARTWORK")
end
return pfOverlays[idx]
end
local exploreEnter = function()
WorldMapTooltip:ClearLines()
@@ -81,7 +73,6 @@ pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
if not explorecaches[this.name] then return end
if C.appearance.worldmap.mapreveal == "0" then return end
local r,g,b,a = GetStringColor(C.appearance.worldmap.mapreveal_color)
for texture in pairs(explorecaches[this.name]) do
texture:SetVertexColor(1,1,1,1)
end
@@ -97,51 +88,52 @@ pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
end
end
local function pfWorldMapFrame_Update()
-- clear stale texture references to prevent memory leak / Error 132
for k in pairs(explorecaches) do
explorecaches[k] = nil
end
-- overlay data with lazy init
local overlayData = setmetatable(pfMapOverlayData, {__index = function(t,k)
local v = {}
rawset(t,k,v)
return v
end})
-- create metatable if not yet created
this.overlayData = this.overlayData or setmetatable(pfMapOverlayData, {__index = function(t,k)
local v = {}
rawset(t,k,v)
return v
end})
local function pfWorldMapFrame_Update()
-- clear stale caches
for k in pairs(explorecaches) do explorecaches[k] = nil end
-- hide all our textures from last frame
for i = 1, pfOverlayMax do
pfOverlays[i]:Hide()
end
local r,g,b,a = GetStringColor(C.appearance.worldmap.mapreveal_color)
local mapFileName, textureHeight, textureWidth = GetMapInfo()
local mapFileName = GetMapInfo()
if not mapFileName then mapFileName = "World" end
if (not mapFileName) then mapFileName = "World" end
local prefix = string.format("Interface\\WorldMap\\%s\\",mapFileName)
local prefix = string.format("Interface\\WorldMap\\%s\\", mapFileName)
local numOverlays = GetNumMapOverlays()
-- reuse upvalue table to avoid GC pressure
-- collect explored overlays
for k in pairs(alreadyknown) do alreadyknown[k] = nil end
for i=1, numOverlays do
local textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY = GetMapOverlayInfo(i)
local overlayHash = create_hash(textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY)
alreadyknown[textureName] = overlayHash
for i = 1, numOverlays do
local texName = GetMapOverlayInfo(i)
if texName then alreadyknown[texName] = true end
end
-- hide all exploration points
for k, frame in pairs(explores) do
frame:Hide()
end
-- hide explore icons
for _, frame in pairs(explores) do frame:Hide() end
local zoneData = this.overlayData[mapFileName]
local zoneData = overlayData[mapFileName]
local textureCount = 0
local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight
for i, hash in ipairs(zoneData) do
local textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY, name = unpack_hash(prefix, hash)
if not textureName then break end
-- explore magnifying glass icon
explores[i] = explores[i] or CreateFrame("Frame", nil, WorldMapDetailFrame)
local explore = explores[i]
explore:SetWidth(16)
explore:SetHeight(16)
explore:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", offsetX+textureWidth/2, -offsetY-textureHeight/2)
explore:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", offsetX + textureWidth/2, -offsetY - textureHeight/2)
explore:SetScript("OnEnter", exploreEnter)
explore:SetScript("OnLeave", exploreLeave)
explore:EnableMouse(true)
@@ -159,84 +151,65 @@ pfUI:RegisterModule("mapreveal", "vanilla:tbc", function ()
explore:Hide()
end
-- render overlay texture tiles
if C.appearance.worldmap.mapreveal == "1" or alreadyknown[textureName] then
if errata[textureName] and errata[textureName].offsetX and errata[textureName].offsetX[1] == offsetX then
offsetX = errata[textureName].offsetX[2]
end
if errata[textureName] and errata[textureName].offsetY and errata[textureName].offsetY[1] == offsetY then
offsetY = errata[textureName].offsetY[2]
end
local numTexturesHorz = math.ceil(textureWidth / 256)
local numTexturesVert = math.ceil(textureHeight / 256)
local neededTextures = textureCount + (numTexturesHorz * numTexturesVert)
local texture, texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight
if (neededTextures > NUM_WORLDMAP_OVERLAYS) then
for j = NUM_WORLDMAP_OVERLAYS + 1, neededTextures do
_G.WorldMapDetailFrame:CreateTexture(string.format("%s%s","WorldMapOverlay",j), "ARTWORK")
end
NUM_WORLDMAP_OVERLAYS = neededTextures
end
for j = 1, numTexturesVert do
if (j < numTexturesVert) then
texturePixelHeight,textureFileHeight = 256,256
local numH = math.ceil(textureWidth / 256)
local numV = math.ceil(textureHeight / 256)
local texPixW, texFileW, texPixH, texFileH
for j = 1, numV do
if j < numV then
texPixH = 256
texFileH = 256
else
texturePixelHeight = mod(textureHeight, 256)
if (texturePixelHeight == 0) then texturePixelHeight = 256 end
textureFileHeight = 16
while (textureFileHeight < texturePixelHeight) do
textureFileHeight = textureFileHeight * 2
end
texPixH = mod(textureHeight, 256)
if texPixH == 0 then texPixH = 256 end
texFileH = 16
while texFileH < texPixH do texFileH = texFileH * 2 end
end
for k = 1, numTexturesHorz do
if (textureCount > NUM_WORLDMAP_OVERLAYS) then
return
end
texture = _G[string.format("%s%s","WorldMapOverlay",(textureCount + 1))]
if (k < numTexturesHorz) then
texturePixelWidth, textureFileWidth = 256,256
for k = 1, numH do
textureCount = textureCount + 1
local tex = pfGetOverlay(textureCount)
if k < numH then
texPixW = 256
texFileW = 256
else
texturePixelWidth = mod(textureWidth, 256)
if (texturePixelWidth == 0) then texturePixelWidth = 256 end
textureFileWidth = 16
while (textureFileWidth < texturePixelWidth) do
textureFileWidth = textureFileWidth * 2
end
texPixW = mod(textureWidth, 256)
if texPixW == 0 then texPixW = 256 end
texFileW = 16
while texFileW < texPixW do texFileW = texFileW * 2 end
end
texture:SetWidth(texturePixelWidth)
texture:SetHeight(texturePixelHeight)
texture:SetTexCoord(0, texturePixelWidth / textureFileWidth, 0, texturePixelHeight / textureFileHeight)
texture:ClearAllPoints()
texture:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", offsetX + (256 *(k - 1)), -(offsetY +(256 *(j - 1))))
texture:SetTexture(string.format("%s%s",textureName,(((j - 1) * numTexturesHorz) + k)))
tex:SetWidth(texPixW)
tex:SetHeight(texPixH)
tex:SetTexCoord(0, texPixW/texFileW, 0, texPixH/texFileH)
tex:ClearAllPoints()
tex:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", offsetX + 256*(k-1), -(offsetY + 256*(j-1)))
tex:SetTexture(string.format("%s%s", textureName, ((j-1)*numH + k)))
explorecaches[name] = explorecaches[name] or {}
explorecaches[name][texture] = true
explorecaches[name][tex] = true
if not alreadyknown[textureName] then
texture:SetVertexColor(r,g,b,a)
tex:SetVertexColor(r,g,b,a)
else
texture:SetVertexColor(1,1,1,1)
tex:SetVertexColor(1,1,1,1)
end
texture:Show()
textureCount = textureCount + 1
tex:Show()
end
end
end
end
pfOverlayMax = math.max(pfOverlayMax, textureCount)
end
-- hook map reveal functions before and after the actual call
local pfHookWorldMapFrame_Update = _G.WorldMapFrame_Update
_G.WorldMapFrame_Update = function(self)
-- hide all previously set textures
for i = 1, NUM_WORLDMAP_OVERLAYS do
_G[string.format("%s%s","WorldMapOverlay",i)]:Hide()
end
-- let the game put its explored tiles on the map
pfHookWorldMapFrame_Update(self)
-- let the addon extend it with its own data
-- hook WorldMapFrame_Update
local origUpdate = _G.WorldMapFrame_Update
_G.WorldMapFrame_Update = function(...)
origUpdate(unpack(arg))
pfWorldMapFrame_Update()
end
end)