local ADDON_NAME = "HailMaryGuildTools" local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME) if not HMGT then return end local MapOverlay = HMGT.MapOverlay if not MapOverlay then return end if not HMGT_Config or not HMGT_Config.RegisterOptionsProvider then return end local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME, true) or {} local AceConfigRegistry = LibStub("AceConfigRegistry-3.0", true) local MAX_POI_EDITOR_ROWS = 40 local function NotifyOptionsChanged() if AceConfigRegistry and type(AceConfigRegistry.NotifyChange) == "function" then AceConfigRegistry:NotifyChange(ADDON_NAME) end end local function MapCategoryValues() if HMGT.GetMapPOICategoryValues then return HMGT:GetMapPOICategoryValues() end return { default = "Default" } end local function GetMapPOIs() local profile = HMGT.db and HMGT.db.profile if not profile then return {} end profile.mapOverlay = profile.mapOverlay or {} profile.mapOverlay.pois = profile.mapOverlay.pois or {} return profile.mapOverlay.pois end local function HasPOIAt(index) return GetMapPOIs()[index] ~= nil end local function HasAnyPOIs() return GetMapPOIs()[1] ~= nil end local function GetPoiCount() local count = 0 for _ in ipairs(GetMapPOIs()) do count = count + 1 end return count end local function EnsurePoiDraft(index) local poi = GetMapPOIs()[index] if not poi then return nil end HMGT._mapPoiDrafts = HMGT._mapPoiDrafts or {} local draft = HMGT._mapPoiDrafts[index] if not draft then draft = { mapID = tostring(tonumber(poi.mapID) or ""), x = string.format("%.2f", tonumber(poi.x) or 0), y = string.format("%.2f", tonumber(poi.y) or 0), label = tostring(poi.label or ""), category = tostring(poi.category or "default"), } HMGT._mapPoiDrafts[index] = draft end return draft end local function BuildPoiEditorGroupArgs() local function GetPoiTitle(index) local poi = GetMapPOIs()[index] if not poi then return string.format("POI #%d", index) end return tostring(poi.label or ("POI " .. index)) end local args = { } for index = 1, MAX_POI_EDITOR_ROWS do local row = index args["poi_" .. index] = { type = "group", name = function() return GetPoiTitle(row) end, icon = function() local poi = GetMapPOIs()[row] if not poi or not MapOverlay.GetCategoryVisual then return poi and poi.icon or nil end local texture = MapOverlay:GetCategoryVisual(poi.category) return texture or poi.icon or nil end, iconCoords = function() local poi = GetMapPOIs()[row] if not poi or not MapOverlay.GetCategoryVisual then return poi and poi.iconCoords or nil end local _, iconCoords = MapOverlay:GetCategoryVisual(poi.category) return iconCoords or poi.iconCoords or nil end, order = 20 + index, hidden = function() return not HasPOIAt(row) end, args = { details = { type = "description", order = 0.5, width = "full", name = function() local poi = GetMapPOIs()[row] if not poi then return "POI not found." end local categoryValues = MapCategoryValues() local category = tostring(poi.category or "default") local categoryLabel = categoryValues[category] or category return 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, tostring(categoryLabel) ) end, }, mapID = { type = "input", order = 1, width = 0.7, name = L["OPT_MAP_POI_MAPID"] or "Map ID", get = function() local draft = EnsurePoiDraft(row) return (draft and draft.mapID) or "" end, set = function(_, value) local draft = EnsurePoiDraft(row) if draft then draft.mapID = value end end, }, x = { type = "input", order = 2, width = 0.7, name = L["OPT_MAP_POI_X"] or "X (0-100)", get = function() local draft = EnsurePoiDraft(row) return (draft and draft.x) or "" end, set = function(_, value) local draft = EnsurePoiDraft(row) if draft then draft.x = value end end, }, y = { type = "input", order = 3, width = 0.7, name = L["OPT_MAP_POI_Y"] or "Y (0-100)", get = function() local draft = EnsurePoiDraft(row) return (draft and draft.y) or "" end, set = function(_, value) local draft = EnsurePoiDraft(row) if draft then draft.y = value end end, }, label = { type = "input", order = 4, width = "full", name = L["OPT_MAP_POI_LABEL"] or "Label", get = function() local draft = EnsurePoiDraft(row) return (draft and draft.label) or "" end, set = function(_, value) local draft = EnsurePoiDraft(row) if draft then draft.label = value end end, }, category = { type = "select", order = 5, width = "full", name = L["OPT_MAP_POI_CATEGORY"] or "Category", values = function() return MapCategoryValues() end, get = function() local draft = EnsurePoiDraft(row) return (draft and draft.category) or "default" end, set = function(_, value) local draft = EnsurePoiDraft(row) if draft then draft.category = value end end, }, waypoint = { type = "execute", order = 6, width = "half", name = "Waypoint", func = function() local poi = GetMapPOIs()[row] if poi and MapOverlay.ToggleWaypointForPOI then MapOverlay:ToggleWaypointForPOI(poi) end end, }, update = { type = "execute", order = 7, width = "half", name = L["OPT_MAP_POI_UPDATE"] or "Update POI", func = function() local draft = EnsurePoiDraft(row) if not draft then return end local ok = HMGT.UpdateMapPOI and HMGT:UpdateMapPOI(row, draft.mapID, draft.x, draft.y, draft.label, nil, draft.category) if ok then if HMGT._mapPoiDrafts then HMGT._mapPoiDrafts[row] = nil end HMGT:Print(L["OPT_MAP_POI_UPDATED"] or "HMGT: POI updated") else HMGT:Print(L["OPT_MAP_POI_UPDATE_FAILED"] or "HMGT: could not update POI") end NotifyOptionsChanged() end, }, delete = { type = "execute", order = 8, width = "half", name = L["OPT_MAP_POI_REMOVE"] or "Remove POI", func = function() local ok = HMGT.RemoveMapPOI and HMGT:RemoveMapPOI(row) if ok then HMGT._mapPoiDrafts = nil HMGT:Print(L["OPT_MAP_POI_REMOVED"] or "HMGT: POI removed") else HMGT:Print(L["OPT_MAP_POI_REMOVE_FAILED"] or "HMGT: could not remove POI") end NotifyOptionsChanged() end, }, }, } end return args end function MapOverlay:GetOptionsGroup() local group = { type = "group", name = L["OPT_MODULE_MAP_OVERLAY"] or "Map Overlay", order = 30, childGroups = "tree", args = { general = { type = "group", order = 1, name = GENERAL or "General", args = { enabled = { type = "toggle", order = 1, width = "full", name = L["OPT_MAP_ENABLED"] or "Enable map overlay", get = function() local profile = HMGT.db and HMGT.db.profile if not profile then return true end profile.mapOverlay = profile.mapOverlay or {} return profile.mapOverlay.enabled ~= false end, set = function(_, value) local profile = HMGT.db and HMGT.db.profile if not profile then return end profile.mapOverlay = profile.mapOverlay or {} profile.mapOverlay.enabled = value if MapOverlay.Refresh then MapOverlay:Refresh() end end, }, iconSize = { type = "range", order = 2, min = 8, max = 48, step = 1, name = L["OPT_MAP_ICON_SIZE"] or "Icon size", get = function() local profile = HMGT.db and HMGT.db.profile if not profile then return 16 end profile.mapOverlay = profile.mapOverlay or {} return profile.mapOverlay.iconSize or 16 end, set = function(_, value) local profile = HMGT.db and HMGT.db.profile if not profile then return end profile.mapOverlay = profile.mapOverlay or {} profile.mapOverlay.iconSize = value if MapOverlay.Refresh then MapOverlay:Refresh() end end, }, alpha = { type = "range", order = 3, min = 0.1, max = 1, step = 0.05, name = L["OPT_MAP_ALPHA"] or "Icon alpha", get = function() local profile = HMGT.db and HMGT.db.profile if not profile then return 1 end profile.mapOverlay = profile.mapOverlay or {} return profile.mapOverlay.alpha or 1 end, set = function(_, value) local profile = HMGT.db and HMGT.db.profile if not profile then return end profile.mapOverlay = profile.mapOverlay or {} profile.mapOverlay.alpha = value if MapOverlay.Refresh then MapOverlay:Refresh() end end, }, showLabels = { type = "toggle", order = 4, width = "full", name = L["OPT_MAP_SHOW_LABELS"] or "Show labels", get = function() local profile = HMGT.db and HMGT.db.profile if not profile then return true end profile.mapOverlay = profile.mapOverlay or {} return profile.mapOverlay.showLabels ~= false end, set = function(_, value) local profile = HMGT.db and HMGT.db.profile if not profile then return end profile.mapOverlay = profile.mapOverlay or {} profile.mapOverlay.showLabels = value if MapOverlay.Refresh then MapOverlay:Refresh() end end, }, poiSection = { type = "header", order = 10, name = L["OPT_MAP_POI_SECTION"] or "Custom POIs", }, poiSummary = { type = "description", order = 10.1, width = "full", name = function() local count = GetPoiCount() if count <= 0 then return L["OPT_MAP_POI_EMPTY"] or "No POIs configured." end return string.format( "%s: %d\n%s", L["OPT_MAP_POI_LIST"] or "Current POIs", count, L["OPT_MAP_POI_SELECT_HINT"] or "Select a POI in the tree on the left to edit it." ) end, }, draftMapID = { type = "input", order = 11, width = 0.8, name = L["OPT_MAP_POI_MAPID"] or "Map ID", get = function() HMGT._mapDraft = HMGT._mapDraft or {} if not HMGT._mapDraft.mapID and MapOverlay.GetActiveMapID then local activeMap = MapOverlay:GetActiveMapID() if activeMap then HMGT._mapDraft.mapID = tostring(activeMap) end end return HMGT._mapDraft.mapID or "" end, set = function(_, value) HMGT._mapDraft = HMGT._mapDraft or {} HMGT._mapDraft.mapID = value end, }, useCurrentPosition = { type = "execute", order = 11.1, width = "half", name = L["OPT_MAP_POI_USE_CURRENT"] or "Use current position", desc = L["OPT_MAP_POI_USE_CURRENT_DESC"] or "Fill map ID, X and Y from your current player position", func = function() HMGT._mapDraft = HMGT._mapDraft or {} local mapID, x, y = nil, nil, nil if HMGT.GetCurrentMapPOIData then mapID, x, y = HMGT:GetCurrentMapPOIData() end if mapID and x and y then HMGT._mapDraft.mapID = tostring(mapID) HMGT._mapDraft.x = string.format("%.2f", x) HMGT._mapDraft.y = string.format("%.2f", y) HMGT:Print(L["OPT_MAP_POI_CURRENT_SET"] or "HMGT: current position copied") else HMGT:Print(L["OPT_MAP_POI_CURRENT_FAILED"] or "HMGT: could not determine current position") end NotifyOptionsChanged() end, }, draftX = { type = "input", order = 12, width = 0.8, name = L["OPT_MAP_POI_X"] or "X (0-100)", get = function() HMGT._mapDraft = HMGT._mapDraft or {} return HMGT._mapDraft.x or "" end, set = function(_, value) HMGT._mapDraft = HMGT._mapDraft or {} HMGT._mapDraft.x = value end, }, draftY = { type = "input", order = 13, width = 0.8, name = L["OPT_MAP_POI_Y"] or "Y (0-100)", get = function() HMGT._mapDraft = HMGT._mapDraft or {} return HMGT._mapDraft.y or "" end, set = function(_, value) HMGT._mapDraft = HMGT._mapDraft or {} HMGT._mapDraft.y = value end, }, draftLabel = { type = "input", order = 14, width = "full", name = L["OPT_MAP_POI_LABEL"] or "Label", get = function() HMGT._mapDraft = HMGT._mapDraft or {} return HMGT._mapDraft.label or "" end, set = function(_, value) HMGT._mapDraft = HMGT._mapDraft or {} HMGT._mapDraft.label = value end, }, draftCategory = { type = "select", order = 14.1, width = "full", name = L["OPT_MAP_POI_CATEGORY"] or "Category", values = function() return MapCategoryValues() end, get = function() HMGT._mapDraft = HMGT._mapDraft or {} return HMGT._mapDraft.category or "default" end, set = function(_, value) HMGT._mapDraft = HMGT._mapDraft or {} HMGT._mapDraft.category = value end, }, addPoi = { type = "execute", order = 15, width = "half", name = L["OPT_MAP_POI_ADD"] or "Add POI", func = function() HMGT._mapDraft = HMGT._mapDraft or {} local draft = HMGT._mapDraft local ok = HMGT.AddMapPOI and HMGT:AddMapPOI(draft.mapID, draft.x, draft.y, draft.label, nil, draft.category or "default") if ok then HMGT._mapPoiDrafts = nil HMGT:Print(L["OPT_MAP_POI_ADDED"] or "HMGT: POI added") else HMGT:Print(L["OPT_MAP_POI_ADD_FAILED"] or "HMGT: could not add POI") end NotifyOptionsChanged() end, }, }, }, }, } for key, value in pairs(BuildPoiEditorGroupArgs()) do group.args[key] = value end return group end HMGT_Config:RegisterOptionsProvider("map.overlay", function() return { path = "map.overlay", order = 30, group = MapOverlay:GetOptionsGroup(), } end)