local _G = ShaguTweaks.GetGlobalEnv() local T = ShaguTweaks.T local module = ShaguTweaks:register({ title = T["WorldMap Class Colors"], description = T["Show class colored circles on world and battlefield map."], expansions = { ["vanilla"] = true }, category = T["Minimap & World Map"], enabled = true, }) local addonpath local tocs = { "", "-master", "-tbc", "-wotlk" } for _, name in pairs(tocs) do local current = string.format("ShaguTweaks%s", name) local _, title = GetAddOnInfo(current) if title then addonpath = "Interface\\AddOns\\" .. current break end end local partyUnits = { "party1", "party2", "party3", "party4" } local UPDATE_INTERVAL = .1 local function SetAllPointsOffset(frame, parent, offset) frame:SetPoint("TOPLEFT", parent, "TOPLEFT", offset, -offset) frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -offset, offset) end -- Icon names for one map ("WorldMap" or "BattlefieldMinimap"), each with the -- unit the icon shows when the map does not say otherwise. local function BuildButtons(prefix) local buttons = {} for i = 1, 4 do table.insert(buttons, { prefix .. "Party" .. i, "party" .. i }) end for i = 1, 40 do table.insert(buttons, { prefix .. "Raid" .. i, "raid" .. i }) end return buttons end -- In a raid the map packs its raid icons: WorldMapRaid1 is the first raid -- member who is on this map (yourself excluded), not raid1. The map stores -- the real unit on the icon as .unit, and battleground team members outside -- the raid only as .name. Using raidN for WorldMapRaidN showed other players' -- class colors. local function ResolveIcon(frame, fallback) if frame.name then return nil, frame.name elseif frame.unit and UnitExists(frame.unit) then return frame.unit, UnitName(frame.unit) elseif not frame.unit and UnitExists(fallback) then return fallback, UnitName(fallback) end end local function UpdateIcon(frame, fallback) local unit, name = ResolveIcon(frame, fallback) if not unit and not name then return end local icon = _G[frame:GetName() .. "Icon"] if icon then icon:SetTexture() end -- create icon if not yet existing if not frame.texture then frame.texture = frame:CreateTexture(nil, "OVERLAY") SetAllPointsOffset(frame.texture, frame, 12) end -- check if unit is in same party group local ingroup for i = 1, 4 do if UnitName(partyUnits[i]) == name then ingroup = true break end end -- update texture according to raid/group state if ingroup and frame.texture.ingroup ~= "PARTY" then frame.texture:SetTexture(addonpath .. "\\img\\circleparty") frame.texture.ingroup = "PARTY" elseif not ingroup and frame.texture.ingroup ~= "RAID" then frame.texture:SetTexture(addonpath .. "\\img\\circleraid") frame.texture.ingroup = "RAID" end -- detect unit class and set color local class if unit then local _, token = UnitClass(unit) class = token elseif name and ShaguTweaks.GetUnitData then class = ShaguTweaks.GetUnitData(name) end local color = class and RAID_CLASS_COLORS[class] if color then frame.texture:SetVertexColor(color.r, color.g, color.b) else frame.texture:SetVertexColor(.5,1,.5) end end local function UpdateMapColors() this.elapsed = (this.elapsed or UPDATE_INTERVAL) + arg1 if this.elapsed < UPDATE_INTERVAL then return end this.elapsed = 0 local buttons = this.buttons for i = 1, table.getn(buttons) do local frame = _G[buttons[i][1]] if frame and frame:IsVisible() then UpdateIcon(frame, buttons[i][2]) end end end -- The updater is a child of its map, so its OnUpdate only runs while that -- map is shown. This module used to run a frame-wide updater all the time. local updaters = {} local function AttachUpdater(map, prefix) if not map or updaters[prefix] then return end local updater = CreateFrame("Frame", nil, map) updater.buttons = BuildButtons(prefix) updater:SetScript("OnUpdate", UpdateMapColors) updaters[prefix] = updater end module.enable = function(self) AttachUpdater(_G.WorldMapFrame, "WorldMap") -- The battlefield minimap is a load-on-demand Blizzard addon. if _G.BattlefieldMinimap then AttachUpdater(_G.BattlefieldMinimap, "BattlefieldMinimap") else local loader = CreateFrame("Frame") loader:RegisterEvent("ADDON_LOADED") loader:SetScript("OnEvent", function() if _G.BattlefieldMinimap then AttachUpdater(_G.BattlefieldMinimap, "BattlefieldMinimap") this:UnregisterEvent("ADDON_LOADED") end end) end end