1194 lines
38 KiB
Lua
1194 lines
38 KiB
Lua
local ADDON_NAME = "HailMaryGuildTools"
|
|
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
|
if not HMGT then return end
|
|
|
|
local MapOverlay = HMGT:NewModule("MapOverlay", "AceEvent-3.0")
|
|
HMGT.MapOverlay = MapOverlay
|
|
|
|
local MEDIA_PATH = "Interface\\AddOns\\HailMaryGuildTools\\Modules\\MapOverlay\\Media\\"
|
|
local DEFAULT_ICON = MEDIA_PATH .. "DefaultIcon.png"
|
|
local DEFAULT_CATEGORY = "default"
|
|
local OBJECT_ICONS_TEXTURE = "Interface\\Minimap\\ObjectIcons"
|
|
local OBJECT_ICONS_ATLAS_TEXTURE = "Interface\\Minimap\\ObjectIconsAtlas"
|
|
local BLIP_TEXTURE_WIDTH = 256
|
|
local BLIP_TEXTURE_HEIGHT = 256
|
|
local BLIP_CELL_SIZE = 32
|
|
local ATLAS_TEXTURE_DEFAULTS = {
|
|
[OBJECT_ICONS_TEXTURE] = { width = 256, height = 256 },
|
|
[OBJECT_ICONS_ATLAS_TEXTURE] = { width = 256, height = 256 },
|
|
}
|
|
local ICON_CONFIG = HMGT.MapOverlayIconConfig or {}
|
|
local RAW_CATEGORY_DEFS = type(ICON_CONFIG.icons) == "table" and ICON_CONFIG.icons or {
|
|
{ key = DEFAULT_CATEGORY, label = "Default", texture = DEFAULT_ICON },
|
|
}
|
|
|
|
DEFAULT_CATEGORY = tostring(ICON_CONFIG.defaultKey or DEFAULT_CATEGORY):lower()
|
|
|
|
local CATEGORY_DEFS = {}
|
|
local CATEGORY_BY_KEY = {}
|
|
for _, rawDef in ipairs(RAW_CATEGORY_DEFS) do
|
|
if type(rawDef) == "table" then
|
|
local key = tostring(rawDef.key or ""):lower()
|
|
if key ~= "" and not CATEGORY_BY_KEY[key] then
|
|
local def = {
|
|
key = key,
|
|
label = tostring(rawDef.label or key),
|
|
texture = tostring(rawDef.texture or DEFAULT_ICON),
|
|
atlasIndex = rawDef.atlasIndex,
|
|
atlasSize = rawDef.atlasSize,
|
|
atlasColumns = rawDef.atlasColumns,
|
|
textureWidth = rawDef.textureWidth,
|
|
textureHeight = rawDef.textureHeight,
|
|
cell = rawDef.cell,
|
|
iconCoords = rawDef.iconCoords,
|
|
}
|
|
CATEGORY_DEFS[#CATEGORY_DEFS + 1] = def
|
|
CATEGORY_BY_KEY[key] = def
|
|
if type(rawDef.aliases) == "table" then
|
|
for _, alias in ipairs(rawDef.aliases) do
|
|
local aliasKey = tostring(alias or ""):lower()
|
|
if aliasKey ~= "" and not CATEGORY_BY_KEY[aliasKey] then
|
|
CATEGORY_BY_KEY[aliasKey] = def
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not CATEGORY_BY_KEY[DEFAULT_CATEGORY] then
|
|
local fallbackDef = {
|
|
key = DEFAULT_CATEGORY,
|
|
label = "Default",
|
|
texture = DEFAULT_ICON,
|
|
}
|
|
table.insert(CATEGORY_DEFS, 1, fallbackDef)
|
|
CATEGORY_BY_KEY[DEFAULT_CATEGORY] = fallbackDef
|
|
end
|
|
local ROUND_ICON_MASK = "Interface\\CharacterFrame\\TempPortraitAlphaMask"
|
|
local PIN_RING_TEXTURE = "Interface\\Minimap\\POIIcons"
|
|
local PIN_RING_COLOR = { 0.96, 0.82, 0.22, 1.00 }
|
|
local PIN_SHADOW_COLOR = { 0.00, 0.00, 0.00, 0.22 }
|
|
|
|
local function EnsureRoundMask(owner, fieldName, texture)
|
|
if not owner or not fieldName or not texture then
|
|
return nil
|
|
end
|
|
if not owner.CreateMaskTexture or not texture.AddMaskTexture then
|
|
return nil
|
|
end
|
|
|
|
local mask = owner[fieldName]
|
|
if not mask then
|
|
mask = owner:CreateMaskTexture(nil, "ARTWORK")
|
|
mask:SetTexture(ROUND_ICON_MASK, "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE")
|
|
owner[fieldName] = mask
|
|
texture:AddMaskTexture(mask)
|
|
owner._textureMaskApplied = true
|
|
end
|
|
return mask
|
|
end
|
|
|
|
local function SetTextureMaskEnabled(owner, texture, enabled)
|
|
if not owner or not texture then
|
|
return
|
|
end
|
|
|
|
local mask = owner.textureMask
|
|
if not mask then
|
|
return
|
|
end
|
|
|
|
if enabled then
|
|
if texture.AddMaskTexture and not owner._textureMaskApplied then
|
|
texture:AddMaskTexture(mask)
|
|
owner._textureMaskApplied = true
|
|
end
|
|
mask:Show()
|
|
else
|
|
if texture.RemoveMaskTexture and owner._textureMaskApplied then
|
|
texture:RemoveMaskTexture(mask)
|
|
owner._textureMaskApplied = false
|
|
end
|
|
mask:Hide()
|
|
end
|
|
end
|
|
|
|
local function ApplyRingVisual(texture, r, g, b, a)
|
|
if not texture then
|
|
return
|
|
end
|
|
texture:SetTexture(PIN_RING_TEXTURE)
|
|
texture:SetTexCoord(0, 0.125, 0.625, 0.75)
|
|
texture:SetVertexColor(r or 1, g or 1, b or 1, a or 1)
|
|
end
|
|
|
|
local function GetIconInset(pinSize)
|
|
local size = tonumber(pinSize) or 16
|
|
local iconInset = math.max(2, math.floor((size * 0.20) + 0.5))
|
|
local maxIconInset = math.max(2, math.floor((size - 6) / 2))
|
|
if iconInset > maxIconInset then
|
|
iconInset = maxIconInset
|
|
end
|
|
return iconInset
|
|
end
|
|
|
|
local function clamp(v, minv, maxv, fallback)
|
|
v = tonumber(v)
|
|
if not v then return fallback end
|
|
if v < minv then return minv end
|
|
if v > maxv then return maxv end
|
|
return v
|
|
end
|
|
|
|
local function GetFallbackObjectIconTexCoord(atlasIndex)
|
|
local index = tonumber(atlasIndex)
|
|
if not index or index < 0 then
|
|
return nil
|
|
end
|
|
local col = math.fmod(index, 8)
|
|
local row = math.floor(index / 8)
|
|
local left = (col * BLIP_CELL_SIZE) / BLIP_TEXTURE_WIDTH
|
|
local right = ((col + 1) * BLIP_CELL_SIZE) / BLIP_TEXTURE_WIDTH
|
|
local top = (row * BLIP_CELL_SIZE) / BLIP_TEXTURE_HEIGHT
|
|
local bottom = ((row + 1) * BLIP_CELL_SIZE) / BLIP_TEXTURE_HEIGHT
|
|
return { left, right, top, bottom }
|
|
end
|
|
|
|
local function GetObjectIconTexCoord(iconIndex)
|
|
local index = tonumber(iconIndex)
|
|
if not index or index < 0 then
|
|
return nil
|
|
end
|
|
if type(GetObjectIconTextureCoords) == "function" then
|
|
local left, right, top, bottom = GetObjectIconTextureCoords(index)
|
|
if left and right and top and bottom then
|
|
return { left, right, top, bottom }
|
|
end
|
|
end
|
|
return GetFallbackObjectIconTexCoord(index)
|
|
end
|
|
|
|
local function ParseAtlasSize(atlasSize)
|
|
if type(atlasSize) == "string" then
|
|
local width, height = string.match(atlasSize, "^(%d+)%s*[xX]%s*(%d+)$")
|
|
return tonumber(width), tonumber(height)
|
|
end
|
|
if type(atlasSize) == "table" then
|
|
return tonumber(atlasSize[1]), tonumber(atlasSize[2])
|
|
end
|
|
return nil, nil
|
|
end
|
|
|
|
local function IsShimmedMinimapAtlas(def)
|
|
if type(def) ~= "table" then
|
|
return false
|
|
end
|
|
if tostring(def.texture or "") ~= OBJECT_ICONS_ATLAS_TEXTURE then
|
|
return false
|
|
end
|
|
local width, height = ParseAtlasSize(def.atlasSize)
|
|
local index = tonumber(def.atlasIndex)
|
|
return width == 32 and height == 32 and index and index >= 0 and index < 40 or false
|
|
end
|
|
|
|
local function GetDefinitionResolvedTexture(def)
|
|
if type(def) ~= "table" then
|
|
return DEFAULT_ICON
|
|
end
|
|
if IsShimmedMinimapAtlas(def) then
|
|
return OBJECT_ICONS_TEXTURE
|
|
end
|
|
return tostring(def.texture or DEFAULT_ICON)
|
|
end
|
|
|
|
local function GetDefinitionTextureDimensions(def)
|
|
if type(def) ~= "table" then
|
|
return BLIP_TEXTURE_WIDTH, BLIP_TEXTURE_HEIGHT
|
|
end
|
|
local texture = GetDefinitionResolvedTexture(def)
|
|
local defaults = ATLAS_TEXTURE_DEFAULTS[texture]
|
|
local width = tonumber(def.textureWidth) or (defaults and defaults.width) or BLIP_TEXTURE_WIDTH
|
|
local height = tonumber(def.textureHeight) or (defaults and defaults.height) or BLIP_TEXTURE_HEIGHT
|
|
return width, height
|
|
end
|
|
|
|
local function GetAtlasTexCoord(def)
|
|
if type(def) ~= "table" then
|
|
return nil
|
|
end
|
|
local index = tonumber(def.atlasIndex)
|
|
local cellWidth, cellHeight = ParseAtlasSize(def.atlasSize)
|
|
if not index or not cellWidth or not cellHeight or cellWidth <= 0 or cellHeight <= 0 then
|
|
return nil
|
|
end
|
|
|
|
local textureWidth, textureHeight = GetDefinitionTextureDimensions(def)
|
|
local columns = tonumber(def.atlasColumns)
|
|
if not columns or columns < 1 then
|
|
columns = math.max(1, math.floor(textureWidth / cellWidth))
|
|
end
|
|
|
|
local col = math.fmod(index, columns)
|
|
local row = math.floor(index / columns)
|
|
local left = (col * cellWidth) / textureWidth
|
|
local right = ((col + 1) * cellWidth) / textureWidth
|
|
local top = (row * cellHeight) / textureHeight
|
|
local bottom = ((row + 1) * cellHeight) / textureHeight
|
|
return { left, right, top, bottom }
|
|
end
|
|
|
|
local function GetObjectIconCellTexCoord(col, row)
|
|
col = tonumber(col)
|
|
row = tonumber(row)
|
|
if not col or not row or col < 0 or row < 0 then
|
|
return nil
|
|
end
|
|
local left = (col * BLIP_CELL_SIZE) / BLIP_TEXTURE_WIDTH
|
|
local right = ((col + 1) * BLIP_CELL_SIZE) / BLIP_TEXTURE_WIDTH
|
|
local top = (row * BLIP_CELL_SIZE) / BLIP_TEXTURE_HEIGHT
|
|
local bottom = ((row + 1) * BLIP_CELL_SIZE) / BLIP_TEXTURE_HEIGHT
|
|
return { left, right, top, bottom }
|
|
end
|
|
|
|
local function GetDefinitionIconCoords(def)
|
|
if type(def) ~= "table" then
|
|
return nil
|
|
end
|
|
if type(def.iconCoords) == "table" and #def.iconCoords == 4 then
|
|
return { def.iconCoords[1], def.iconCoords[2], def.iconCoords[3], def.iconCoords[4] }
|
|
end
|
|
if type(def.cell) == "table" then
|
|
return GetObjectIconCellTexCoord(def.cell[1], def.cell[2])
|
|
end
|
|
if IsShimmedMinimapAtlas(def) then
|
|
return GetObjectIconTexCoord(def.atlasIndex)
|
|
end
|
|
if def.atlasIndex ~= nil and def.atlasSize ~= nil then
|
|
return GetAtlasTexCoord(def)
|
|
end
|
|
if def.atlasIndex ~= nil then
|
|
if GetDefinitionResolvedTexture(def) == OBJECT_ICONS_TEXTURE then
|
|
return GetObjectIconTexCoord(def.atlasIndex)
|
|
end
|
|
return GetAtlasTexCoord(def)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function GetTextureEscape(def, iconCoords, size)
|
|
local iconTexture = type(def) == "table" and GetDefinitionResolvedTexture(def) or tostring(def or "")
|
|
local iconSize = tonumber(size) or 14
|
|
if iconTexture == "" then
|
|
return ""
|
|
end
|
|
|
|
if type(iconCoords) == "table" and #iconCoords == 4 then
|
|
local textureWidth, textureHeight = GetDefinitionTextureDimensions(type(def) == "table" and def or nil)
|
|
local left = math.floor((tonumber(iconCoords[1]) or 0) * textureWidth + 0.5)
|
|
local right = math.floor((tonumber(iconCoords[2]) or 0) * textureWidth + 0.5)
|
|
local top = math.floor((tonumber(iconCoords[3]) or 0) * textureHeight + 0.5)
|
|
local bottom = math.floor((tonumber(iconCoords[4]) or 0) * textureHeight + 0.5)
|
|
return string.format(
|
|
"|T%s:%d:%d:0:0:%d:%d:%d:%d:%d:%d|t",
|
|
iconTexture,
|
|
iconSize,
|
|
iconSize,
|
|
textureWidth,
|
|
textureHeight,
|
|
left,
|
|
right,
|
|
top,
|
|
bottom
|
|
)
|
|
end
|
|
|
|
return string.format("|T%s:%d:%d:0:0|t", iconTexture, iconSize, iconSize)
|
|
end
|
|
|
|
local function BuildCategoryDropdownLabel(def)
|
|
if not def then
|
|
return "Unknown"
|
|
end
|
|
local label = tostring(def.label or def.key or "Icon")
|
|
local iconTag = GetTextureEscape(def, GetDefinitionIconCoords(def), 14)
|
|
if iconTag ~= "" then
|
|
return string.format("%s %s", iconTag, label)
|
|
end
|
|
return label
|
|
end
|
|
|
|
function MapOverlay:GetCategoryDefinitions()
|
|
return CATEGORY_DEFS
|
|
end
|
|
|
|
function MapOverlay:GetCategoryDropdownValues()
|
|
local values = {}
|
|
for _, def in ipairs(CATEGORY_DEFS) do
|
|
values[def.key] = BuildCategoryDropdownLabel(def)
|
|
end
|
|
return values
|
|
end
|
|
|
|
function MapOverlay:GetCategoryIcon(category)
|
|
local key = tostring(category or DEFAULT_CATEGORY):lower()
|
|
local def = CATEGORY_BY_KEY[key]
|
|
if def then
|
|
local texture = GetDefinitionResolvedTexture(def)
|
|
if texture and texture ~= "" then
|
|
return texture
|
|
end
|
|
end
|
|
return DEFAULT_ICON
|
|
end
|
|
|
|
function MapOverlay:GetCategoryIconCoords(category)
|
|
local key = tostring(category or DEFAULT_CATEGORY):lower()
|
|
local def = CATEGORY_BY_KEY[key]
|
|
if def then
|
|
return GetDefinitionIconCoords(def)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function MapOverlay:GetCategoryLabel(category)
|
|
local key = tostring(category or DEFAULT_CATEGORY):lower()
|
|
local def = CATEGORY_BY_KEY[key]
|
|
if def and def.label and def.label ~= "" then
|
|
return def.label
|
|
end
|
|
return tostring(category or DEFAULT_CATEGORY)
|
|
end
|
|
|
|
function MapOverlay:GetNormalizedCategory(category)
|
|
local key = tostring(category or DEFAULT_CATEGORY):lower()
|
|
if CATEGORY_BY_KEY[key] then
|
|
return key
|
|
end
|
|
return DEFAULT_CATEGORY
|
|
end
|
|
|
|
function MapOverlay:GetCategoryVisual(category)
|
|
local normalizedCategory = self:GetNormalizedCategory(category)
|
|
return self:GetCategoryIcon(normalizedCategory), self:GetCategoryIconCoords(normalizedCategory), self:GetCategoryLabel(normalizedCategory), normalizedCategory
|
|
end
|
|
|
|
function MapOverlay:UsesAtlasIcon(category)
|
|
local normalizedCategory = self:GetNormalizedCategory(category)
|
|
local def = CATEGORY_BY_KEY[normalizedCategory]
|
|
return def and (def.atlasIndex ~= nil or type(def.cell) == "table" or type(def.iconCoords) == "table") or false
|
|
end
|
|
|
|
function MapOverlay:IsPOIUserWaypoint(poi)
|
|
if not poi or not C_Map or type(C_Map.GetUserWaypoint) ~= "function" then
|
|
return false
|
|
end
|
|
local wp = C_Map.GetUserWaypoint()
|
|
if not wp then return false end
|
|
if tonumber(wp.uiMapID) ~= tonumber(poi.mapID) then return false end
|
|
|
|
local px = (tonumber(poi.x) or 0) / 100
|
|
local py = (tonumber(poi.y) or 0) / 100
|
|
local wx = tonumber(wp.position and wp.position.x) or -1
|
|
local wy = tonumber(wp.position and wp.position.y) or -1
|
|
return math.abs(px - wx) <= 0.0005 and math.abs(py - wy) <= 0.0005
|
|
end
|
|
|
|
function MapOverlay:ToggleWaypointForPOI(poi)
|
|
if not poi or not C_Map or not UiMapPoint then return end
|
|
if type(C_Map.ClearUserWaypoint) ~= "function" or type(C_Map.SetUserWaypoint) ~= "function" then
|
|
return
|
|
end
|
|
|
|
if self:IsPOIUserWaypoint(poi) then
|
|
C_Map.ClearUserWaypoint()
|
|
if C_SuperTrack and type(C_SuperTrack.SetSuperTrackedUserWaypoint) == "function" then
|
|
C_SuperTrack.SetSuperTrackedUserWaypoint(false)
|
|
end
|
|
return
|
|
end
|
|
|
|
local mapID = tonumber(poi.mapID)
|
|
local x = (tonumber(poi.x) or 0) / 100
|
|
local y = (tonumber(poi.y) or 0) / 100
|
|
local mapPoint = UiMapPoint.CreateFromCoordinates(mapID, x, y)
|
|
if not mapPoint then return end
|
|
C_Map.SetUserWaypoint(mapPoint)
|
|
if C_SuperTrack and type(C_SuperTrack.SetSuperTrackedUserWaypoint) == "function" then
|
|
C_SuperTrack.SetSuperTrackedUserWaypoint(true)
|
|
end
|
|
end
|
|
|
|
function MapOverlay:GetSettings()
|
|
local p = HMGT.db and HMGT.db.profile
|
|
if not p then return nil end
|
|
p.mapOverlay = p.mapOverlay or {}
|
|
p.mapOverlay.pois = p.mapOverlay.pois or {}
|
|
if p.mapOverlay.enabled == nil then p.mapOverlay.enabled = true end
|
|
p.mapOverlay.iconSize = clamp(p.mapOverlay.iconSize, 8, 48, 16)
|
|
p.mapOverlay.alpha = clamp(p.mapOverlay.alpha, 0.1, 1, 1)
|
|
if p.mapOverlay.showLabels == nil then p.mapOverlay.showLabels = true end
|
|
for _, poi in ipairs(p.mapOverlay.pois) do
|
|
if type(poi) == "table" then
|
|
local icon, iconCoords, _, normalizedCategory = self:GetCategoryVisual(poi.category)
|
|
poi.category = normalizedCategory
|
|
poi.icon = icon
|
|
poi.iconCoords = iconCoords
|
|
end
|
|
end
|
|
return p.mapOverlay
|
|
end
|
|
|
|
function MapOverlay:GetActiveMapID()
|
|
if WorldMapFrame and WorldMapFrame.GetMapID then
|
|
local mapID = WorldMapFrame:GetMapID()
|
|
if mapID then return mapID end
|
|
end
|
|
if C_Map and C_Map.GetBestMapForUnit then
|
|
return C_Map.GetBestMapForUnit("player")
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function MapOverlay:GetCurrentPlayerPosition()
|
|
if not C_Map or type(C_Map.GetPlayerMapPosition) ~= "function" then
|
|
return nil, nil, nil, "api unavailable"
|
|
end
|
|
|
|
local mapID = tonumber(self:GetActiveMapID())
|
|
if not mapID and C_Map.GetBestMapForUnit then
|
|
mapID = tonumber(C_Map.GetBestMapForUnit("player"))
|
|
end
|
|
if not mapID then
|
|
return nil, nil, nil, "map unavailable"
|
|
end
|
|
|
|
local pos = C_Map.GetPlayerMapPosition(mapID, "player")
|
|
if (not pos or pos.x == nil or pos.y == nil) and C_Map.GetBestMapForUnit then
|
|
local bestMapID = tonumber(C_Map.GetBestMapForUnit("player"))
|
|
if bestMapID and bestMapID ~= mapID then
|
|
mapID = bestMapID
|
|
pos = C_Map.GetPlayerMapPosition(mapID, "player")
|
|
end
|
|
end
|
|
if not pos then
|
|
return mapID, nil, nil, "position unavailable"
|
|
end
|
|
|
|
local x, y
|
|
if type(pos.GetXY) == "function" then
|
|
x, y = pos:GetXY()
|
|
else
|
|
x, y = pos.x, pos.y
|
|
end
|
|
x = tonumber(x)
|
|
y = tonumber(y)
|
|
if not x or not y then
|
|
return mapID, nil, nil, "position unavailable"
|
|
end
|
|
|
|
return mapID, clamp(x * 100, 0, 100, 0), clamp(y * 100, 0, 100, 0)
|
|
end
|
|
|
|
function MapOverlay:AddPOI(mapID, x, y, label, icon, category)
|
|
local s = self:GetSettings()
|
|
if not s then return false, "no settings" end
|
|
|
|
mapID = tonumber(mapID)
|
|
x = tonumber(x)
|
|
y = tonumber(y)
|
|
if not mapID or not x or not y then return false, "invalid coordinates" end
|
|
|
|
x = clamp(x, 0, 100, 0)
|
|
y = clamp(y, 0, 100, 0)
|
|
label = tostring(label or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|
if label == "" then label = string.format("POI %.1f, %.1f", x, y) end
|
|
local iconCoords
|
|
icon, iconCoords, _, category = self:GetCategoryVisual(category)
|
|
|
|
s.pois[#s.pois + 1] = {
|
|
mapID = mapID,
|
|
x = x,
|
|
y = y,
|
|
label = label,
|
|
icon = icon,
|
|
iconCoords = iconCoords,
|
|
category = category,
|
|
}
|
|
self:Refresh()
|
|
self:UpdatePOIManagerFrame()
|
|
return true, #s.pois
|
|
end
|
|
|
|
function MapOverlay:UpdatePOI(index, mapID, x, y, label, icon, category)
|
|
local s = self:GetSettings()
|
|
if not s then return false, "no settings" end
|
|
index = tonumber(index)
|
|
if not index or index < 1 or index > #s.pois then return false, "invalid index" end
|
|
|
|
mapID = tonumber(mapID)
|
|
x = tonumber(x)
|
|
y = tonumber(y)
|
|
if not mapID or not x or not y then return false, "invalid coordinates" end
|
|
|
|
x = clamp(x, 0, 100, 0)
|
|
y = clamp(y, 0, 100, 0)
|
|
label = tostring(label or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|
if label == "" then label = string.format("POI %.1f, %.1f", x, y) end
|
|
local iconCoords
|
|
icon, iconCoords, _, category = self:GetCategoryVisual(category)
|
|
|
|
local poi = s.pois[index]
|
|
poi.mapID = mapID
|
|
poi.x = x
|
|
poi.y = y
|
|
poi.label = label
|
|
poi.icon = icon
|
|
poi.iconCoords = iconCoords
|
|
poi.category = category
|
|
self:Refresh()
|
|
self:UpdatePOIManagerFrame()
|
|
return true
|
|
end
|
|
|
|
function MapOverlay:RemovePOI(index)
|
|
local s = self:GetSettings()
|
|
if not s then return false end
|
|
index = tonumber(index)
|
|
if not index or index < 1 or index > #s.pois then return false end
|
|
table.remove(s.pois, index)
|
|
if self._poiManagerSelected and self._poiManagerSelected > #s.pois then
|
|
self._poiManagerSelected = #s.pois
|
|
end
|
|
if self._poiManagerSelected and self._poiManagerSelected < 1 then
|
|
self._poiManagerSelected = nil
|
|
end
|
|
self:Refresh()
|
|
self:UpdatePOIManagerFrame()
|
|
return true
|
|
end
|
|
|
|
function MapOverlay:BuildPOIListText(mapID)
|
|
local s = self:GetSettings()
|
|
if not s or type(s.pois) ~= "table" or #s.pois == 0 then
|
|
return "No POIs configured."
|
|
end
|
|
local filterMap = tonumber(mapID)
|
|
local out = {}
|
|
for i, poi in ipairs(s.pois) do
|
|
if (not filterMap) or poi.mapID == filterMap then
|
|
out[#out + 1] = string.format(
|
|
"%d) map=%d x=%.2f y=%.2f [%s] %s",
|
|
i,
|
|
tonumber(poi.mapID) or 0,
|
|
tonumber(poi.x) or 0,
|
|
tonumber(poi.y) or 0,
|
|
tostring(self:GetCategoryLabel(poi.category)),
|
|
tostring(poi.label or "POI")
|
|
)
|
|
end
|
|
end
|
|
if #out == 0 then
|
|
return "No POIs for this map."
|
|
end
|
|
return table.concat(out, "\n")
|
|
end
|
|
|
|
function MapOverlay:CreatePOIManagerFrame()
|
|
if self.poiManagerFrame then
|
|
return self.poiManagerFrame
|
|
end
|
|
|
|
local frame = CreateFrame("Frame", "HMGTMapPOIManagerFrame", UIParent, "BasicFrameTemplateWithInset")
|
|
frame:SetSize(470, 500)
|
|
frame:SetPoint("CENTER")
|
|
frame:SetFrameStrata("DIALOG")
|
|
frame:Hide()
|
|
frame:SetMovable(true)
|
|
frame:EnableMouse(true)
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:SetScript("OnDragStart", frame.StartMoving)
|
|
frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
|
|
|
|
frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
frame.title:SetPoint("LEFT", frame.TitleBg, "LEFT", 8, 0)
|
|
frame.title:SetText("HMGT - POIs")
|
|
|
|
frame.subtitle = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
frame.subtitle:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -34)
|
|
frame.subtitle:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -14, -34)
|
|
frame.subtitle:SetJustifyH("LEFT")
|
|
frame.subtitle:SetText("Klicke auf einen Eintrag, um Details unten anzuzeigen.")
|
|
|
|
local scroll = CreateFrame("ScrollFrame", nil, frame, "UIPanelScrollFrameTemplate")
|
|
scroll:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -54)
|
|
scroll:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -32, -54)
|
|
scroll:SetHeight(250)
|
|
|
|
local content = CreateFrame("Frame", nil, scroll)
|
|
content:SetSize(1, 1)
|
|
scroll:SetScrollChild(content)
|
|
|
|
frame.scroll = scroll
|
|
frame.content = content
|
|
frame.rows = {}
|
|
|
|
frame.emptyText = content:CreateFontString(nil, "OVERLAY", "GameFontDisable")
|
|
frame.emptyText:SetPoint("TOPLEFT", content, "TOPLEFT", 4, -4)
|
|
frame.emptyText:SetText("Keine POIs vorhanden.")
|
|
|
|
frame.detailHeader = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
|
|
frame.detailHeader:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -320)
|
|
frame.detailHeader:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -14, -320)
|
|
frame.detailHeader:SetJustifyH("LEFT")
|
|
frame.detailHeader:SetText("Details")
|
|
|
|
frame.detailText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
|
|
frame.detailText:SetPoint("TOPLEFT", frame.detailHeader, "BOTTOMLEFT", 0, -8)
|
|
frame.detailText:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -14, -336)
|
|
frame.detailText:SetJustifyH("LEFT")
|
|
frame.detailText:SetJustifyV("TOP")
|
|
frame.detailText:SetText("Waehle einen POI aus der Liste.")
|
|
|
|
frame.waypointButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
frame.waypointButton:SetSize(130, 24)
|
|
frame.waypointButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 14, 14)
|
|
frame.waypointButton:SetText("Waypoint")
|
|
frame.waypointButton:SetScript("OnClick", function()
|
|
local s = self:GetSettings()
|
|
local idx = tonumber(self._poiManagerSelected)
|
|
local poi = s and s.pois and idx and s.pois[idx]
|
|
if not poi then return end
|
|
self:ToggleWaypointForPOI(poi)
|
|
end)
|
|
|
|
frame.removeButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
frame.removeButton:SetSize(130, 24)
|
|
frame.removeButton:SetPoint("LEFT", frame.waypointButton, "RIGHT", 8, 0)
|
|
frame.removeButton:SetText("Entfernen")
|
|
frame.removeButton:SetScript("OnClick", function()
|
|
local idx = tonumber(self._poiManagerSelected)
|
|
if not idx then return end
|
|
self:RemovePOI(idx)
|
|
end)
|
|
|
|
frame.closeButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
frame.closeButton:SetSize(90, 24)
|
|
frame.closeButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -14, 14)
|
|
frame.closeButton:SetText(CLOSE or "Close")
|
|
frame.closeButton:SetScript("OnClick", function()
|
|
frame:Hide()
|
|
end)
|
|
|
|
self.poiManagerFrame = frame
|
|
return frame
|
|
end
|
|
|
|
function MapOverlay:AcquirePOIManagerRow(index)
|
|
local frame = self.poiManagerFrame
|
|
if not frame then return nil end
|
|
|
|
local row = frame.rows[index]
|
|
if row then
|
|
return row
|
|
end
|
|
|
|
row = CreateFrame("Button", nil, frame.content)
|
|
row:SetHeight(22)
|
|
|
|
row.bg = row:CreateTexture(nil, "BACKGROUND")
|
|
row.bg:SetAllPoints(row)
|
|
row.bg:SetColorTexture(1, 1, 1, 0.05)
|
|
|
|
row.highlight = row:CreateTexture(nil, "HIGHLIGHT")
|
|
row.highlight:SetAllPoints(row)
|
|
row.highlight:SetColorTexture(1, 1, 1, 0.12)
|
|
|
|
row.expandText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
row.expandText:SetPoint("LEFT", row, "LEFT", 6, 0)
|
|
row.expandText:SetText("+")
|
|
|
|
row.labelText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
row.labelText:SetPoint("LEFT", row.expandText, "RIGHT", 8, 0)
|
|
row.labelText:SetPoint("RIGHT", row, "RIGHT", -8, 0)
|
|
row.labelText:SetJustifyH("LEFT")
|
|
|
|
row:SetScript("OnClick", function(btn)
|
|
local idx = btn._index
|
|
if not idx then return end
|
|
if self._poiManagerSelected == idx then
|
|
self._poiManagerSelected = nil
|
|
else
|
|
self._poiManagerSelected = idx
|
|
end
|
|
self:UpdatePOIManagerFrame()
|
|
end)
|
|
|
|
frame.rows[index] = row
|
|
return row
|
|
end
|
|
|
|
function MapOverlay:UpdatePOIManagerFrame()
|
|
local frame = self.poiManagerFrame
|
|
if not frame or not frame:IsShown() then return end
|
|
|
|
local s = self:GetSettings()
|
|
local pois = (s and s.pois) or {}
|
|
local rowHeight = 22
|
|
local offsetY = -2
|
|
|
|
for i, poi in ipairs(pois) do
|
|
local row = self:AcquirePOIManagerRow(i)
|
|
row._index = i
|
|
row:ClearAllPoints()
|
|
row:SetPoint("TOPLEFT", frame.content, "TOPLEFT", 0, offsetY)
|
|
row:SetPoint("TOPRIGHT", frame.content, "TOPRIGHT", 0, offsetY)
|
|
|
|
local selected = (self._poiManagerSelected == i)
|
|
row.expandText:SetText(selected and "-" or "+")
|
|
row.labelText:SetText(string.format("(%d) %s", i, tostring(poi.label or ("POI " .. i))))
|
|
if selected then
|
|
row.bg:SetColorTexture(0.20, 0.45, 0.80, 0.22)
|
|
else
|
|
local alpha = (i % 2 == 0) and 0.03 or 0.07
|
|
row.bg:SetColorTexture(1, 1, 1, alpha)
|
|
end
|
|
|
|
row:Show()
|
|
offsetY = offsetY - rowHeight
|
|
end
|
|
|
|
for i = #pois + 1, #frame.rows do
|
|
frame.rows[i]:Hide()
|
|
frame.rows[i]._index = nil
|
|
end
|
|
|
|
frame.content:SetHeight(math.max(1, #pois * rowHeight + 6))
|
|
frame.emptyText:SetShown(#pois == 0)
|
|
|
|
local selected = tonumber(self._poiManagerSelected)
|
|
local poi = selected and pois[selected] or nil
|
|
|
|
if poi then
|
|
frame.detailHeader:SetText(string.format("%s (%d)", tostring(poi.label or "POI"), selected))
|
|
frame.detailText:SetText(string.format(
|
|
"Map ID: %d\nX: %.2f\nY: %.2f\nIcon: %s",
|
|
tonumber(poi.mapID) or 0,
|
|
tonumber(poi.x) or 0,
|
|
tonumber(poi.y) or 0,
|
|
self:GetCategoryLabel(poi.category)
|
|
))
|
|
frame.waypointButton:Enable()
|
|
frame.removeButton:Enable()
|
|
else
|
|
frame.detailHeader:SetText("Details")
|
|
frame.detailText:SetText("Waehle einen POI aus der Liste.")
|
|
frame.waypointButton:Disable()
|
|
frame.removeButton:Disable()
|
|
end
|
|
end
|
|
|
|
function MapOverlay:ShowPOIManager()
|
|
local frame = self:CreatePOIManagerFrame()
|
|
frame:Show()
|
|
frame:Raise()
|
|
self:UpdatePOIManagerFrame()
|
|
end
|
|
|
|
function MapOverlay:HidePOIManager()
|
|
if self.poiManagerFrame then
|
|
self.poiManagerFrame:Hide()
|
|
end
|
|
end
|
|
|
|
function MapOverlay:TogglePOIManager()
|
|
local frame = self:CreatePOIManagerFrame()
|
|
if frame:IsShown() then
|
|
frame:Hide()
|
|
return
|
|
end
|
|
frame:Show()
|
|
frame:Raise()
|
|
self:UpdatePOIManagerFrame()
|
|
end
|
|
local WORLD_MAP_PIN_TEMPLATE = "HMGTMapOverlayPinTemplate"
|
|
local WorldMapPinMixin = CreateFromMixins(MapCanvasPinMixin)
|
|
local WorldMapDataProviderMixin = CreateFromMixins(MapCanvasDataProviderMixin)
|
|
|
|
_G.HMGTMapOverlayPinMixin = WorldMapPinMixin
|
|
|
|
function WorldMapPinMixin:EnsureVisuals()
|
|
if not self.shadow then
|
|
self.shadow = self:CreateTexture(nil, "BACKGROUND")
|
|
self.shadow:SetPoint("TOPLEFT", self, "TOPLEFT", 1, -1)
|
|
self.shadow:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 1, -1)
|
|
end
|
|
ApplyRingVisual(self.shadow, unpack(PIN_SHADOW_COLOR))
|
|
|
|
if not self.ring then
|
|
self.ring = self:CreateTexture(nil, "ARTWORK", nil, -2)
|
|
self.ring:SetAllPoints(self)
|
|
end
|
|
ApplyRingVisual(self.ring, unpack(PIN_RING_COLOR))
|
|
|
|
if self.innerStroke then
|
|
self.innerStroke:Hide()
|
|
end
|
|
if self.fill then
|
|
self.fill:Hide()
|
|
end
|
|
|
|
if not self.texture then
|
|
self.texture = self:CreateTexture(nil, "OVERLAY")
|
|
self.texture:SetTexCoord(0.07, 0.93, 0.07, 0.93)
|
|
end
|
|
if not self.textureMask then
|
|
EnsureRoundMask(self, "textureMask", self.texture)
|
|
end
|
|
|
|
if not self.label then
|
|
self.label = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
self.label:SetPoint("LEFT", self, "RIGHT", 3, 0)
|
|
self.label:SetJustifyH("LEFT")
|
|
self.label:SetText("")
|
|
end
|
|
|
|
if self.RegisterForClicks then
|
|
self:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
end
|
|
end
|
|
|
|
function WorldMapPinMixin:UpdateVisualLayout(pinSize, fullSizeTexture)
|
|
self:EnsureVisuals()
|
|
|
|
self.texture:ClearAllPoints()
|
|
if fullSizeTexture then
|
|
self.texture:SetAllPoints(self)
|
|
else
|
|
local iconInset = GetIconInset(pinSize)
|
|
self.texture:SetPoint("TOPLEFT", self, "TOPLEFT", iconInset, -iconInset)
|
|
self.texture:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -iconInset, iconInset)
|
|
end
|
|
if self.textureMask then
|
|
self.textureMask:ClearAllPoints()
|
|
self.textureMask:SetAllPoints(self.texture)
|
|
end
|
|
end
|
|
|
|
function WorldMapPinMixin:OnLoad()
|
|
self:EnsureVisuals()
|
|
self:UseFrameLevelType("PIN_FRAME_LEVEL_AREA_POI")
|
|
if self.SetScalingLimits then
|
|
self:SetScalingLimits(1, 1.0, 1.2)
|
|
end
|
|
if self.SetPassThroughButtons then
|
|
self:SetPassThroughButtons("")
|
|
end
|
|
end
|
|
|
|
function WorldMapPinMixin:OnAcquired(poi, settings, owner)
|
|
self:EnsureVisuals()
|
|
self._poi = poi
|
|
self._owner = owner
|
|
self._settings = settings
|
|
local pinSize = tonumber(settings and settings.iconSize) or 16
|
|
local usesAtlasIcon = owner and owner.UsesAtlasIcon and owner:UsesAtlasIcon(poi.category) or false
|
|
|
|
self:SetPosition((tonumber(poi.x) or 0) / 100, (tonumber(poi.y) or 0) / 100)
|
|
self:SetSize(pinSize, pinSize)
|
|
self:SetAlpha(tonumber(settings and settings.alpha) or 1)
|
|
self:UpdateVisualLayout(pinSize, usesAtlasIcon)
|
|
if usesAtlasIcon then
|
|
SetTextureMaskEnabled(self, self.texture, false)
|
|
self.shadow:Hide()
|
|
self.ring:Hide()
|
|
else
|
|
SetTextureMaskEnabled(self, self.texture, true)
|
|
self.shadow:Show()
|
|
self.ring:Show()
|
|
end
|
|
local texture, iconCoords = nil, nil
|
|
if owner and owner.GetCategoryVisual then
|
|
texture, iconCoords = owner:GetCategoryVisual(poi.category)
|
|
end
|
|
self.texture:SetTexture(texture or poi.icon or DEFAULT_ICON)
|
|
if type(iconCoords) == "table" then
|
|
self.texture:SetTexCoord(unpack(iconCoords))
|
|
elseif type(poi.iconCoords) == "table" then
|
|
self.texture:SetTexCoord(unpack(poi.iconCoords))
|
|
else
|
|
self.texture:SetTexCoord(0.07, 0.93, 0.07, 0.93)
|
|
end
|
|
self.texture:SetVertexColor(1, 1, 1, 1)
|
|
self.texture:Show()
|
|
|
|
if settings and settings.showLabels then
|
|
self.label:SetText(tostring(poi.label or "POI"))
|
|
self.label:Show()
|
|
else
|
|
self.label:SetText("")
|
|
self.label:Hide()
|
|
end
|
|
end
|
|
|
|
function WorldMapPinMixin:OnReleased()
|
|
self._poi = nil
|
|
self._owner = nil
|
|
self._settings = nil
|
|
if self.texture then
|
|
self.texture:SetTexture(nil)
|
|
end
|
|
if self.label then
|
|
self.label:SetText("")
|
|
self.label:Hide()
|
|
end
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
function WorldMapPinMixin:OnMouseEnter()
|
|
local poi = self._poi
|
|
local owner = self._owner
|
|
if not poi then return end
|
|
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
|
GameTooltip:AddLine(tostring(poi.label or "POI"), 1, 1, 1)
|
|
GameTooltip:AddLine(string.format("Map: %d", tonumber(poi.mapID) or 0), 0.8, 0.8, 0.8)
|
|
GameTooltip:AddLine(string.format("X: %.2f Y: %.2f", tonumber(poi.x) or 0, tonumber(poi.y) or 0), 0.8, 0.8, 0.8)
|
|
if poi.category then
|
|
local label = owner and owner.GetCategoryLabel and owner:GetCategoryLabel(poi.category) or tostring(poi.category)
|
|
GameTooltip:AddLine("Icon: " .. tostring(label), 0.8, 0.8, 0.8)
|
|
end
|
|
GameTooltip:AddLine("Left click: toggle waypoint", 0.8, 0.8, 0.8)
|
|
HMGT:SafeShowTooltip(GameTooltip)
|
|
end
|
|
|
|
function WorldMapPinMixin:OnMouseLeave()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
function WorldMapPinMixin:OnClick(mouseButton)
|
|
if mouseButton ~= "LeftButton" then return end
|
|
local owner = self._owner
|
|
local poi = self._poi
|
|
if not owner or not poi then return end
|
|
owner:ToggleWaypointForPOI(poi)
|
|
end
|
|
|
|
function WorldMapPinMixin:SetPassThroughButtons() end
|
|
|
|
function WorldMapDataProviderMixin:RemoveAllData()
|
|
local map = self:GetMap()
|
|
if map then
|
|
map:RemoveAllPinsByTemplate(WORLD_MAP_PIN_TEMPLATE)
|
|
end
|
|
end
|
|
|
|
function WorldMapDataProviderMixin:RefreshAllData()
|
|
self:RemoveAllData()
|
|
|
|
local map = self:GetMap()
|
|
local owner = self.owner
|
|
if not map or not owner then return end
|
|
|
|
local settings = owner:GetSettings()
|
|
if not settings or settings.enabled ~= true then
|
|
return
|
|
end
|
|
|
|
local mapID = map:GetMapID()
|
|
if not mapID then
|
|
return
|
|
end
|
|
|
|
for _, poi in ipairs(settings.pois or {}) do
|
|
if tonumber(poi.mapID) == tonumber(mapID) then
|
|
map:AcquirePin(WORLD_MAP_PIN_TEMPLATE, poi, settings, owner)
|
|
end
|
|
end
|
|
end
|
|
|
|
function MapOverlay:EnsureWorldMapPinPool()
|
|
if not WorldMapFrame then
|
|
return false
|
|
end
|
|
|
|
WorldMapFrame.pinPools = WorldMapFrame.pinPools or {}
|
|
if WorldMapFrame.pinPools[WORLD_MAP_PIN_TEMPLATE] then
|
|
self._worldMapPinPool = WorldMapFrame.pinPools[WORLD_MAP_PIN_TEMPLATE]
|
|
return true
|
|
end
|
|
|
|
local canvas = WorldMapFrame.GetCanvas and WorldMapFrame:GetCanvas()
|
|
if not canvas then
|
|
canvas = WorldMapFrame.ScrollContainer and WorldMapFrame.ScrollContainer.Child
|
|
end
|
|
if not canvas then
|
|
return false
|
|
end
|
|
|
|
local pool
|
|
if type(CreateUnsecuredRegionPoolInstance) == "function" then
|
|
pool = CreateUnsecuredRegionPoolInstance(WORLD_MAP_PIN_TEMPLATE)
|
|
elseif type(CreateFramePool) == "function" then
|
|
pool = CreateFramePool("BUTTON")
|
|
end
|
|
if not pool then
|
|
return false
|
|
end
|
|
|
|
pool.parent = canvas
|
|
pool.createFunc = function()
|
|
local frame = CreateFrame("Button", nil, canvas)
|
|
frame:SetSize(1, 1)
|
|
if type(Mixin) == "function" then
|
|
Mixin(frame, WorldMapPinMixin)
|
|
end
|
|
if frame.OnLoad then
|
|
frame:OnLoad()
|
|
end
|
|
return frame
|
|
end
|
|
pool.resetFunc = function(_, pin)
|
|
pin:Hide()
|
|
pin:ClearAllPoints()
|
|
if pin.OnReleased then
|
|
pin:OnReleased()
|
|
end
|
|
pin.pinTemplate = nil
|
|
pin.owningMap = nil
|
|
end
|
|
|
|
-- Compatibility with older pool field names.
|
|
pool.creationFunc = pool.createFunc
|
|
pool.resetterFunc = pool.resetFunc
|
|
|
|
WorldMapFrame.pinPools[WORLD_MAP_PIN_TEMPLATE] = pool
|
|
self._worldMapPinPool = pool
|
|
return true
|
|
end
|
|
|
|
function MapOverlay:EnsureWorldMapProvider()
|
|
if not WorldMapFrame or type(WorldMapFrame.AddDataProvider) ~= "function" then
|
|
return false
|
|
end
|
|
if not self:EnsureWorldMapPinPool() then
|
|
return false
|
|
end
|
|
|
|
if not self._worldMapProvider then
|
|
self._worldMapProvider = CreateFromMixins(WorldMapDataProviderMixin)
|
|
self._worldMapProvider.owner = self
|
|
end
|
|
|
|
if not self._worldMapProviderRegistered then
|
|
WorldMapFrame:AddDataProvider(self._worldMapProvider)
|
|
self._worldMapProviderRegistered = true
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function MapOverlay:Refresh()
|
|
if not self:EnsureWorldMapProvider() then
|
|
return
|
|
end
|
|
self._worldMapProvider:RefreshAllData()
|
|
end
|
|
|
|
function MapOverlay:HookWorldMap()
|
|
if self._mapHooked then return end
|
|
if not WorldMapFrame then return end
|
|
self._mapHooked = true
|
|
|
|
self:EnsureWorldMapProvider()
|
|
WorldMapFrame:HookScript("OnShow", function() self:Refresh() end)
|
|
WorldMapFrame:HookScript("OnHide", function()
|
|
if self._worldMapProvider then
|
|
self._worldMapProvider:RemoveAllData()
|
|
end
|
|
end)
|
|
hooksecurefunc(WorldMapFrame, "SetMapID", function()
|
|
self:Refresh()
|
|
end)
|
|
end
|
|
|
|
function MapOverlay:OnEnable()
|
|
self:GetSettings()
|
|
self:RegisterEvent("ADDON_LOADED", "OnAddonLoaded")
|
|
self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "Refresh")
|
|
self:RegisterEvent("ZONE_CHANGED", "Refresh")
|
|
self:RegisterEvent("ZONE_CHANGED_INDOORS", "Refresh")
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD", "Refresh")
|
|
self:HookWorldMap()
|
|
self:Refresh()
|
|
end
|
|
|
|
function MapOverlay:OnAddonLoaded(_, addonName)
|
|
if addonName == "Blizzard_WorldMap" then
|
|
self:HookWorldMap()
|
|
self:Refresh()
|
|
end
|
|
end
|
|
|
|
function MapOverlay:OnDisable()
|
|
self:UnregisterAllEvents()
|
|
if self._worldMapProvider then
|
|
self._worldMapProvider:RemoveAllData()
|
|
end
|
|
self:HidePOIManager()
|
|
end
|
|
|
|
local function GetMapModule(self)
|
|
if self and self.MapOverlay then return self.MapOverlay end
|
|
if self and self.GetModule then
|
|
return self:GetModule("MapOverlay", true)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function HMGT:AddMapPOI(mapID, x, y, label, icon, category)
|
|
local mod = GetMapModule(self)
|
|
if not mod then return false, "module missing" end
|
|
return mod:AddPOI(mapID, x, y, label, icon, category)
|
|
end
|
|
|
|
function HMGT:RemoveMapPOI(index)
|
|
local mod = GetMapModule(self)
|
|
if not mod then return false end
|
|
return mod:RemovePOI(index)
|
|
end
|
|
|
|
function HMGT:UpdateMapPOI(index, mapID, x, y, label, icon, category)
|
|
local mod = GetMapModule(self)
|
|
if not mod then return false, "module missing" end
|
|
return mod:UpdatePOI(index, mapID, x, y, label, icon, category)
|
|
end
|
|
|
|
function HMGT:BuildMapPOIListText(mapID)
|
|
local mod = GetMapModule(self)
|
|
if not mod then return "Map module missing." end
|
|
return mod:BuildPOIListText(mapID)
|
|
end
|
|
|
|
function HMGT:GetMapPOICategoryValues()
|
|
local mod = GetMapModule(self)
|
|
if not mod then
|
|
return { [DEFAULT_CATEGORY] = "Default" }
|
|
end
|
|
return mod:GetCategoryDropdownValues()
|
|
end
|
|
|
|
function HMGT:GetCurrentMapPOIData()
|
|
local mod = GetMapModule(self)
|
|
if not mod then
|
|
return nil, nil, nil, "module missing"
|
|
end
|
|
return mod:GetCurrentPlayerPosition()
|
|
end
|
|
|
|
function HMGT:ToggleMapPOIManager()
|
|
local mod = GetMapModule(self)
|
|
if not mod then return false end
|
|
mod:TogglePOIManager()
|
|
return true
|
|
end
|