288 lines
11 KiB
Lua
288 lines
11 KiB
Lua
--------------------------------------------------------------------------------
|
|
-- Nanami-UI: MapReveal -- Reveal unexplored world map areas
|
|
-- Adapted from ShaguTweaks-extras worldmap-reveal approach
|
|
-- Uses LibMapOverlayData (from !Libs) supplemented with Turtle WoW zones
|
|
--------------------------------------------------------------------------------
|
|
|
|
SFrames.MapReveal = SFrames.MapReveal or {}
|
|
|
|
local MapReveal = SFrames.MapReveal
|
|
local origWorldMapFrame_Update = nil
|
|
local overlayDBPatched = false
|
|
|
|
local errata = {
|
|
["Interface\\WorldMap\\Tirisfal\\BRIGHTWATERLAKE"] = { offsetX = { 587, 584 } },
|
|
["Interface\\WorldMap\\Silverpine\\BERENSPERIL"] = { offsetY = { 417, 415 } },
|
|
}
|
|
|
|
-- Turtle WoW new/modified zones not present in LibMapOverlayData
|
|
local TurtleWoW_Zones = {
|
|
["StonetalonMountains"] = {
|
|
"SUNROCKRETREAT:512:256:256:256", "WINDSHEARCRAG:256:256:512:256",
|
|
"MIRKFALLONLAKE:512:512:256:0", "THECHARREDVALE:256:512:256:256",
|
|
"STONETALONPEAK:256:256:256:0", "WEBWINDERPATH:256:512:512:256",
|
|
"AMANIALOR:512:256:0:0", "GRIMTOTEMPOST:512:256:512:512",
|
|
"CAMPAPARAJE:512:256:512:512", "MALAKAJIN:512:256:512:512",
|
|
"BOULDERSLIDERAVINE:256:256:512:512", "SISHIRCANYON:256:512:512:256",
|
|
"VENTURECOMPANYCAMP:256:512:256:0", "BLACKSANDOILFIELDS:512:512:0:0",
|
|
"POWDERTOWN:256:256:256:256", "BRAMBLETHORNPASS:512:512:512:256",
|
|
"BAELHARDUL:512:256:512:256", "BROKENCLIFFMINE:256:512:256:0",
|
|
"THEEARTHENRING:512:256:256:256",
|
|
},
|
|
["UpperKarazhan2f"] = {
|
|
"OUTLAND:1024:768:0:0",
|
|
},
|
|
["GrimReaches"] = {
|
|
"DUNKITHAS:512:256:256:256", "THEGRIMHOLLOW:512:512:256:256",
|
|
"LAKEKITHAS:512:256:256:256", "SLATEBEARDSFORGE:512:256:256:256",
|
|
"THEHIGHPASS:256:256:256:256", "SALGAZMINES:256:256:512:256",
|
|
"EASTRIDGEOUTPOST:512:512:256:0", "BAGGOTHSRAMPART:256:512:256:0",
|
|
"RUINSOFSTOLGAZKEEP:256:256:256:0", "GROLDANSEXCAVATION:256:512:512:0",
|
|
"ZARMGETHSTRONGHOLD:512:256:256:0", "GETHKAR:512:256:256:0",
|
|
"ZARMGETHPOINT:512:256:256:0", "SHATTERBLADEPOST:256:256:512:0",
|
|
"BRANGARSFOLLY:256:256:512:0", "BARLEYCRESTFARMSTEAD:512:512:256:0",
|
|
},
|
|
["Balor"] = {
|
|
"GULLWINGWRECKAGE:512:256:0:0", "BILGERATCOMPOUND:256:256:256:0",
|
|
"SIOUTPOST:256:512:512:256", "RUINSOFBREEZEHAVEN:512:256:256:256",
|
|
"CROAKINGPLATEAU:512:512:256:0", "LANGSTONORCHARD:256:256:256:256",
|
|
"SORROWMORELAKE:256:256:256:256", "SCURRYINGTHICKET:256:512:256:0",
|
|
"STORMWROUGHTCASTLE:512:256:256:256", "STORMREAVERSPIRE:512:512:256:256",
|
|
"WINDROCKCLIFFS:256:512:256:256", "TREACHEROUSCRAGS:512:512:256:256",
|
|
"VANDERFARMSTEAD:256:256:256:256", "GRAHANESTATE:256:256:256:256",
|
|
"STORMBREAKERPOINT:512:512:512:0",
|
|
},
|
|
["Northwind"] = {
|
|
"MERCHANTSHIGHROAD:512:512:256:256", "AMBERSHIRE:512:256:256:256",
|
|
"AMBERWOODKEEP:512:256:0:256", "CRYSTALFALLS:512:512:512:256",
|
|
"CRAWFORDWINERY:256:256:512:256", "NORTHWINDLOGGINGCAMP:256:512:256:0",
|
|
"WITCHCOVEN:256:256:256:0", "RUINSOFBIRKHAVEN:512:512:512:0",
|
|
"SHERWOODQUARRY:512:512:512:0", "BLACKROCKBREACH:512:512:512:0",
|
|
"GRIMMENLAKE:256:512:512:256", "ABBEYGARDENS:256:256:512:0",
|
|
"STILLHEARTPORT:512:512:0:0", "TOWEROFMAGILOU:512:512:0:0",
|
|
"BRISTLEWHISKERCAVERN:256:512:512:0", "NORTHRIDGEPOINT:512:512:256:0",
|
|
"CINDERFALLPASS:512:512:512:256",
|
|
},
|
|
}
|
|
|
|
local function IsTurtleWoW()
|
|
return TargetHPText and TargetHPPercText
|
|
end
|
|
|
|
local function GetOverlayDB()
|
|
return MapOverlayData or LibMapOverlayData or zMapOverlayData or mapOverlayData
|
|
end
|
|
|
|
local function PatchOverlayDB()
|
|
if overlayDBPatched then return end
|
|
overlayDBPatched = true
|
|
|
|
if not IsTurtleWoW() then return end
|
|
|
|
local db = GetOverlayDB()
|
|
if not db then return end
|
|
|
|
for zone, data in pairs(TurtleWoW_Zones) do
|
|
db[zone] = data
|
|
end
|
|
end
|
|
|
|
local function GetConfig()
|
|
if not SFramesDB or type(SFramesDB.MapReveal) ~= "table" then
|
|
return { enabled = true, unexploredAlpha = 0.7 }
|
|
end
|
|
return SFramesDB.MapReveal
|
|
end
|
|
|
|
local function NextPowerOf2(n)
|
|
local p = 16
|
|
while p < n do
|
|
p = p * 2
|
|
end
|
|
return p
|
|
end
|
|
|
|
local function DoMapRevealUpdate()
|
|
local db = GetOverlayDB()
|
|
if not db then return end
|
|
|
|
local mapFileName = GetMapInfo and GetMapInfo()
|
|
if not mapFileName then mapFileName = "World" end
|
|
|
|
local zoneData = db[mapFileName]
|
|
if not zoneData then return end
|
|
|
|
local prefix = "Interface\\WorldMap\\" .. mapFileName .. "\\"
|
|
|
|
local numExploredOverlays = GetNumMapOverlays and GetNumMapOverlays() or 0
|
|
local explored = {}
|
|
for i = 1, numExploredOverlays do
|
|
local textureName = GetMapOverlayInfo(i)
|
|
if textureName and textureName ~= "" then
|
|
explored[textureName] = true
|
|
end
|
|
end
|
|
|
|
local cfg = GetConfig()
|
|
local dimR, dimG, dimB = 0.4, 0.4, 0.4
|
|
if cfg.unexploredAlpha then
|
|
dimR = cfg.unexploredAlpha
|
|
dimG = cfg.unexploredAlpha
|
|
dimB = cfg.unexploredAlpha
|
|
end
|
|
|
|
local textureCount = 0
|
|
|
|
for idx = 1, table.getn(zoneData) do
|
|
local entry = zoneData[idx]
|
|
local _, _, name, sW, sH, sX, sY = string.find(entry, "^(%u+):(%d+):(%d+):(%d+):(%d+)$")
|
|
if not name then
|
|
_, _, name, sW, sH, sX, sY = string.find(entry, "^([^:]+):(%d+):(%d+):(%d+):(%d+)$")
|
|
end
|
|
if name then
|
|
local textureWidth = tonumber(sW)
|
|
local textureHeight = tonumber(sH)
|
|
local offsetX = tonumber(sX)
|
|
local offsetY = tonumber(sY)
|
|
local textureName = prefix .. name
|
|
|
|
local isExplored = explored[textureName]
|
|
|
|
if cfg.enabled or isExplored then
|
|
if errata[textureName] then
|
|
local e = errata[textureName]
|
|
if e.offsetX and e.offsetX[1] == offsetX then
|
|
offsetX = e.offsetX[2]
|
|
end
|
|
if e.offsetY and e.offsetY[1] == offsetY then
|
|
offsetY = e.offsetY[2]
|
|
end
|
|
end
|
|
|
|
local numTexturesHorz = math.ceil(textureWidth / 256)
|
|
local numTexturesVert = math.ceil(textureHeight / 256)
|
|
local neededTextures = textureCount + (numTexturesHorz * numTexturesVert)
|
|
|
|
if neededTextures > NUM_WORLDMAP_OVERLAYS then
|
|
for j = NUM_WORLDMAP_OVERLAYS + 1, neededTextures do
|
|
WorldMapDetailFrame:CreateTexture("WorldMapOverlay" .. j, "ARTWORK")
|
|
end
|
|
NUM_WORLDMAP_OVERLAYS = neededTextures
|
|
end
|
|
|
|
for row = 1, numTexturesVert do
|
|
local texturePixelHeight, textureFileHeight
|
|
if row < numTexturesVert then
|
|
texturePixelHeight = 256
|
|
textureFileHeight = 256
|
|
else
|
|
texturePixelHeight = math.mod(textureHeight, 256)
|
|
if texturePixelHeight == 0 then texturePixelHeight = 256 end
|
|
textureFileHeight = NextPowerOf2(texturePixelHeight)
|
|
end
|
|
|
|
for col = 1, numTexturesHorz do
|
|
if textureCount > NUM_WORLDMAP_OVERLAYS then return end
|
|
|
|
local texture = _G["WorldMapOverlay" .. (textureCount + 1)]
|
|
|
|
local texturePixelWidth, textureFileWidth
|
|
if col < numTexturesHorz then
|
|
texturePixelWidth = 256
|
|
textureFileWidth = 256
|
|
else
|
|
texturePixelWidth = math.mod(textureWidth, 256)
|
|
if texturePixelWidth == 0 then texturePixelWidth = 256 end
|
|
textureFileWidth = NextPowerOf2(texturePixelWidth)
|
|
end
|
|
|
|
texture:SetWidth(texturePixelWidth)
|
|
texture:SetHeight(texturePixelHeight)
|
|
texture:SetTexCoord(0, texturePixelWidth / textureFileWidth,
|
|
0, texturePixelHeight / textureFileHeight)
|
|
texture:ClearAllPoints()
|
|
texture:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT",
|
|
offsetX + (256 * (col - 1)),
|
|
-(offsetY + (256 * (row - 1))))
|
|
|
|
local tileIndex = ((row - 1) * numTexturesHorz) + col
|
|
texture:SetTexture(textureName .. tileIndex)
|
|
|
|
if not isExplored then
|
|
texture:SetVertexColor(dimR, dimG, dimB, 1)
|
|
else
|
|
texture:SetVertexColor(1, 1, 1, 1)
|
|
end
|
|
|
|
texture:Show()
|
|
textureCount = textureCount + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function MapReveal:Initialize()
|
|
local db = GetOverlayDB()
|
|
if not db then
|
|
SFrames:Print("MapReveal: LibMapOverlayData 未找到,地图揭示功能不可用。")
|
|
return
|
|
end
|
|
|
|
PatchOverlayDB()
|
|
|
|
if not origWorldMapFrame_Update and WorldMapFrame_Update then
|
|
origWorldMapFrame_Update = WorldMapFrame_Update
|
|
WorldMapFrame_Update = function()
|
|
for i = 1, NUM_WORLDMAP_OVERLAYS do
|
|
local tex = _G["WorldMapOverlay" .. i]
|
|
if tex then tex:Hide() end
|
|
end
|
|
|
|
origWorldMapFrame_Update()
|
|
|
|
local cfg = GetConfig()
|
|
if cfg.enabled then
|
|
DoMapRevealUpdate()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function MapReveal:Toggle()
|
|
if not SFramesDB then SFramesDB = {} end
|
|
if type(SFramesDB.MapReveal) ~= "table" then
|
|
SFramesDB.MapReveal = { enabled = true, unexploredAlpha = 0.7 }
|
|
end
|
|
|
|
SFramesDB.MapReveal.enabled = not SFramesDB.MapReveal.enabled
|
|
|
|
if SFramesDB.MapReveal.enabled then
|
|
SFrames:Print("地图迷雾揭示: |cff00ff00已开启|r")
|
|
if not origWorldMapFrame_Update and WorldMapFrame_Update then
|
|
self:Initialize()
|
|
end
|
|
else
|
|
SFrames:Print("地图迷雾揭示: |cffff0000已关闭|r")
|
|
end
|
|
|
|
if WorldMapFrame and WorldMapFrame:IsShown() then
|
|
WorldMapFrame_Update()
|
|
end
|
|
end
|
|
|
|
function MapReveal:SetAlpha(alpha)
|
|
if not SFramesDB or type(SFramesDB.MapReveal) ~= "table" then return end
|
|
SFramesDB.MapReveal.unexploredAlpha = alpha
|
|
if SFramesDB.MapReveal.enabled and WorldMapFrame and WorldMapFrame:IsShown() then
|
|
WorldMapFrame_Update()
|
|
end
|
|
end
|
|
|
|
function MapReveal:Refresh()
|
|
if WorldMapFrame and WorldMapFrame:IsShown() then
|
|
WorldMapFrame_Update()
|
|
end
|
|
end
|