-- Addon settings local db -- Texture settings local textures ={ ['Star'] = "GroupLeader/Textures/star_", ['Plus'] = "GroupLeader/Textures/plus_", ['Circle'] = "GroupLeader/Textures/circle_", } local colors = { ['White'] = "w.dds", ['Black'] = "bl.dds", ['Red'] = "r.dds", ['Green'] = "g.dds", ['Blue'] = "b.dds", } local textureKeys = GetTableKeys(textures) local colorKeys = GetTableKeys(colors) local mapPinType = "GroupLeaderMap" local compassPinType = "GroupLeaderCompass" -- Defaults for settings local defaults = { compassEnabled = true, mapEnabled = true, leaderEnabled = true, leaderSymbol = 'Star', leaderColor = 'White', compassMaxDistance = 1.0, } -- Addon data storage local nameToUnitTagMap = {} local playerName = nil local trackers = { ['leader'] = {tag=nil, name=nil, symbol='Circle', color='Red', X=0, Y=0}, } -- Misc functions -- Map group member names to unit tags in a table local function MapNamesToUnitTags() nameToUnitTagMap = {} size = GetGroupSize() if size > 0 then for i=1, size, 1 do local unitTag = GetGroupUnitTagByIndex(i) if unitTag then local name = GetUnitName(unitTag) if name then local lowername = string.lower(name) nameToUnitTagMap[lowername]=unitTag end end end end end -- Tooltip creator local pinTooltipCreator = { creator = function(pin) --TODO InformationTooltip:AddLine("Tracker") end, tooltip = InformationTooltip, } -- Compass and map callbacks local function MapCallback(pinManager) if not db or not db.mapEnabled then return end for k, v in pairs(trackers) do if v.tag and v.name and v.symbol and v.color and not (v.X == 0 and v.Y == 0) then if k == 'leader' and db.leaderEnabled and v.name ~= playerName then pinManager:CreatePin(_G[mapPinType .. v.name], v.name, v.X, v.Y) else pinManager:CreatePin(_G[mapPinType .. v.name], v.name, v.X, v.Y) end end end end local function CompassPinCallback(pinManager) if COMPASS.container:IsHidden() then return end if not db or not db.compassEnabled then return end for k, v in pairs(trackers) do if v.tag and v.name and v.symbol and v.color and not (v.X == 0 and v.Y == 0) then if k == 'leader' and db.leaderEnabled and v.name ~= playerName then pinManager:CreatePin(compassPinType .. v.name, v.name, v.X, v.Y) else pinManager:CreatePin(compassPinType .. v.name, v.name, v.X, v.Y) end end end end -- Map specific functions local function RefreshMapPins(pinType) ZO_WorldMap_RefreshCustomPinsOfType(_G[pinType]) end local function AddMapPin(pinType, pinTypeAddCallback, pinTypeOnResizeCallback, pinLayoutData, pinTooltipCreator) ZO_WorldMap_AddCustomPin(pinType, pinTypeAddCallback, pinTypeOnResizeCallback, pinLayoutData, pinTooltipCreator) ZO_WorldMap_SetCustomPinEnabled(_G[pinType], true) RefreshMapPins(pinType) end -- Slash command handlers local function CommandHandler(text) -- Display help if text == nil or string.len(text) <= 0 or string.lower(text) == "help" then ChatMessage("GroupLeader Help:") ChatMessage("/gl : display help.") ChatMessage(" aliases: /groupleader, /gl help") ChatMessage("/gl leader : toggle leader tracking") ChatMessage("/gl map : toggle map tracking") ChatMessage("/gl compass : toggle compass tracking") ChatMessage("/gl add [name] -symbol -color : add a custom tracker") ChatMessage(" -symbol and -color are optional") ChatMessage(" e.g., /gl add adein -circle -red") ChatMessage("/gl del [name] : delete a custom tracker") ChatMessage("/gl clear : clear all custom trackers") elseif text ~= nil and string.len(text) > 0 then MapNamesToUnitTags() local input = string.lower(text) local params = SplitString(input) local paramCount = table.getn(params) if params[1] == "leader" then db.leaderEnabled = not db.leaderEnabled local status = nil if db.leaderEnabled then status = "enabled" else status = "disabled" end ChatMessage("Tracking group leader " .. status) elseif params[1] == "map" then db.mapEnabled = not db.mapEnabled local status = nil if db.mapEnabled then status = "enabled" else status = "disabled" end ChatMessage("Map tracking " .. status) elseif params[1] == "compass" then db.compassEnabled = not db.compassEnabled local status = nil if db.compassEnabled then status = "enabled" else status = "disabled" end ChatMessage("Compass tracking " .. status) elseif params[1] == "add" then local name = nil local symbol = 'Circle' local color = 'Red' for paramCounter = 2, paramCount, 1 do param = params[paramCounter] if string.sub(param, 1, string.len("-"))=="-" then local paramNoDash = string.sub(param, 2, -1) if not symbol then for tex in textureKeys do if paramNoDash == tex then symbol = tex break end end end if not color then for col in colorKeys do if paramNoDash == col then color = col break end end end else if not name then name = param else name = name .. " " .. param end end end local unitTag = nameToUnitTagMap[name] if unitTag then for k, v in pairs(trackers) do if v.tag == unitTag then ChatMessage("Already tracking that player!") return end end local mapPinLayout = { level = 200, texture = textures[symbol] .. colors[color], size = 40, } local compassPinLayout = { maxDistance = db.compassMaxDistance, texture = textures[symbol] .. colors[color], } AddMapPin(mapPinType .. name, MapCallback, nil, mapPinLayout, pinTooltipCreator) COMPASS_PINS:AddCustomPin(compassPinType .. name, CompassPinCallback, compassPinLayout) table.insert(trackers, {tag=unitTag, name=name, symbol=symbol, color=color, X=0, Y=0}) ChatMessage("Now tracking " .. name) else ChatMessage("Player not found in group!") end elseif params[1] == "del" then local name = nil for paramCounter = 2, paramCounter, 1 do param = params[paramCounter] if not name then name = param else name = name .. " " .. param end end deleted = false for k, v in pairs(trackers) do if v.name == name then table.remove(trackers, k) deleted = true end end -- TODO: delete the map/compass pins if possible (and other places where tracking removed) if deleted then ChatMessage("Deleted " .. name .. " from tracking list") else ChatMessage("Player not found in tracking list!") end elseif params[1] == "clear" then ChatMessage("Clearing custom trackers") local trackerCount = table.getn(trackers) - 1 for trackerCounter = 1, trackerCount, 1 do table.remove(trackerCounter) end else ChatMessage("Unknown GroupLeader command!") end end end -- Event handlers -- Called when the group is disbanded local function Disbanded() trackers = { ['leader'] = {tag=nil, name=nil, symbol=nil, color=nil, X=0, Y=0}, } end -- Called when the group leader changes local function LeaderUpdate() trackers['leader'].tag = GetGroupLeaderUnitTag() end -- Called when someone joins the group local function MemberJoined() LeaderUpdate() end -- Called when someone leaves the group local function MemberLeft() LeaderUpdate() MapNamesToUnitTags() for k, v in pairs(trackers) do local newUnitTag = nameToUnitTagMap[v.name] if newUnitTag then trackers[k].tag = newUnitTag else table.remove(trackers, k) end end end -- Called when someone in the group connects/disconnects local function ConnectedStatus() LeaderUpdate() end -- Refresh the compass and map with the chosen texture local function RefreshAllPins() for k, v in pairs(trackers) do if v.name then RefreshMapPins(mapPinType .. v.name) end end COMPASS_PINS:RefreshPins() end -- Called on game UI updates function OnGroupLeaderUpdate(time) for k, v in pairs(trackers) do if v.tag then v.X, v.Y = GetMapPlayerPosition(v.tag) v.name = GetUnitName(v.tag) else v.X = nil v.Y = nil v.name = nil end end RefreshAllPins() end -- Create the settings menu local function CreateSettings() local LAM = LibStub("LibAddonMenu-1.0") local panel = LAM:CreateControlPanel("GROUP_LEADER_SETTINGS", "Group Leader") LAM:AddHeader(panel, "GROUP_LEADER_SETTINGS_GENERAL", "General Settings") LAM:AddCheckbox(panel, "Group_Leader_Map_Enabled", "Enable Map Tracking", "If enabled, the location of the group leader (or custom targets) will be tracked on the map", function() return db.mapEnabled end, --getFunc function() --setFunc db.mapEnabled = not db.mapEnabled end) LAM:AddCheckbox(panel, "Group_Leader_Compass_Enabled", "Enable Compass Tracking", "If enabled, the location of the group leader (or custom targets) will be tracked on the compass", function() return db.compassEnabled end, --getFunc function() --setFunc db.compassEnabled = not db.compassEnabled end) LAM:AddSlider(panel, "Group_Leader_Compass_MaxDistance", "Max Distance", "The maximum distance (in normalized map units) to show the tracked players", 1, 100, 1, function() return db.compassMaxDistance * 100 end, function(maxDistance) db.compassMaxDistance = maxDistance / 100 COMPASS_PINS.pinLayouts[compassPinType].maxDistance = maxDistance / 100 COMPASS_PINS:RefreshPins() end) LAM:AddHeader(panel, "GROUP_LEADER_SETTINGS_LEADER", "Leader Settings") LAM:AddCheckbox(panel, "Group_Leader_Tracking_Enabled", "Enable Tracking", "If enabled, the location of the group leader will be tracked", function() return db.leaderEnabled end, --getFunc function() --setFunc db.leaderEnabled = not db.leaderEnabled end) LAM:AddDropdown(panel, "Group_Leader_Symbol", "Select Tracking Symbol", "Select the symbol to use for tracking the leader", textureKeys, function() return db.leaderSymbol end, --getFunc function(text) --setFunc db.leaderSymbol = text RefreshAllPins() end, --setFunc false, nil) LAM:AddDropdown(panel, "Group_Leader_Color", "Select Tracking Color", "Select the color to use for the symbol used for tracking the leader", colorKeys, function() return db.leaderColor end, --getFunc function(text) --setFunc db.leaderColor = text RefreshAllPins() end, --setFunc false, nil) end -- AddOn setup local function AddonSetup(eventCode, addOnName) if addOnName ~= "GroupLeader" then return end nameToUnitTagMap = {} playerName = nil trackers = { ['leader'] = {tag=nil, name=nil, symbol='Circle', color='Red', X=0, Y=0}, } -- Populate the settings DB Group_LeaderDB = Group_LeaderDB or {} for k,v in pairs(defaults) do if type(Group_LeaderDB[k]) == "nil" then Group_LeaderDB[k] = v end end db = Group_LeaderDB playerName = GetUnitName('player') LeaderUpdate() trackers['leader'].symbol = db.leaderSymbol trackers['leader'].color = db.leaderColor local mapPinLayout = { level = 200, texture = textures[db.leaderSymbol] .. colors[db.leaderColor], size = 40, } local compassPinLayout = { maxDistance = db.compassMaxDistance, texture = textures[db.leaderSymbol] .. colors[db.leaderColor], } AddMapPin(mapPinType .. 'leader', MapCallback, nil, mapPinLayout, pinTooltipCreator) COMPASS_PINS:AddCustomPin(compassPinType .. 'leader', CompassPinCallback, compassPinLayout) SLASH_COMMANDS["/groupleader"] = CommandHandler SLASH_COMMANDS["/gl"] = CommandHandler EVENT_MANAGER:RegisterForEvent("GroupLeaderDisbanded", EVENT_GROUP_DISBANDED, Disbanded) EVENT_MANAGER:RegisterForEvent("GroupLeaderLeaderUpdate", EVENT_LEADER_UPDATE, LeaderUpdate) EVENT_MANAGER:RegisterForEvent("GroupLeaderMemberJoined", EVENT_GROUP_MEMBER_JOINED, MemberJoined) EVENT_MANAGER:RegisterForEvent("GroupLeaderMemberLeft", EVENT_GROUP_MEMBER_LEFT, MemberLeft) EVENT_MANAGER:RegisterForEvent("GroupLeaderMemberConnected", EVENT_GROUP_MEMBER_CONNECTED_STATUS, ConnectedStatus) CreateSettings() end -- Register for addon loaded event EVENT_MANAGER:RegisterForEvent("GroupLeader", EVENT_ADD_ON_LOADED, AddonSetup)