local addonname, shared = ... ---@cast shared HeimdallShared ---@cast addonname string local ModuleName = "MinimapTagger" ---@diagnostic disable-next-line: missing-fields shared.MinimapTagger = {} function shared.MinimapTagger.Init() ---@param x number ---@param y number ---@param frame Frame ---@param scale number? ---@param ttl number? local function PlantFrame(x, y, frame, scale, ttl) scale = scale or 1 local w, h = BattlefieldMinimap:GetSize() w, h = w * BattlefieldMinimap:GetEffectiveScale(), h * BattlefieldMinimap:GetEffectiveScale() local maxSize = w > h and w or h if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Minimap size: %d", ModuleName, maxSize)) end local iconSize = maxSize * 0.05 iconSize = iconSize * scale x, y = x / 100, y / 100 -- Could do with how... I have no idea, but this seems more accurate than without --x, y = x - 0.01, y - 0.01 local offsetx, offsety = w * x, h * y if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Alert position: %d, %d", ModuleName, x, y)) print(string.format("[%s] Alert offset: %d, %d", ModuleName, offsetx, offsety)) end frame:Hide() frame:SetSize(iconSize, iconSize) frame:SetFrameStrata("HIGH") frame:SetFrameLevel(100) frame:SetPoint("CENTER", BattlefieldMinimap, "TOPLEFT", offsetx, -offsety) if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Alert frame created, OnUpdate hooked", ModuleName)) end frame:SetScript("OnShow", function(self) self:SetAlpha(1) self.custom.busy = true self.custom.progress = 0 self:SetScript("OnUpdate", function(self, elapsed) self.custom.progress = self.custom.progress + elapsed local progress = self.custom.progress / ttl if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Alert progress%%: %f", ModuleName, progress)) print(string.format("[%s] Alert progress: %f", ModuleName, self.custom.progress)) print(string.format("[%s] Alert ttl: %f", ModuleName, Heimdall_Data.config.minimapTagger.ttl)) end self:SetAlpha(1 - progress) if progress >= 1 then self:Hide() self.custom.busy = false self:SetScript("OnUpdate", nil) end end) end) frame:Show() end ---@type Frame[] local alertFramePool = {} local alertFramePoolMaxSize = 20 for i = 1, alertFramePoolMaxSize do local frame = CreateFrame("Frame") frame.custom = { busy = false } local texture = frame:CreateTexture(nil, "ARTWORK") texture:SetAllPoints(frame) texture:SetTexture("Interface\\AddOns\\WeakAuras\\PowerAurasMedia\\Auras\\Aura27") --texture:SetTexture("Interface\\AddOns\\Heimdall\\Texture\\Alert") table.insert(alertFramePool, frame) end ---@param x number ---@param y number ---@param scale number? local function PlantAlert(x, y, scale) local frame = nil for _, alertFrame in ipairs(alertFramePool) do if not alertFrame.custom.busy then frame = alertFrame break end end if not frame then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Alert frame pool is full and could not get frame", ModuleName)) end return end if Heimdall_Data.config.minimapTagger.alertSound then PlaySoundFile("Interface\\AddOns\\Heimdall\\Sound\\Alert.mp3") end PlantFrame(x, y, frame, scale, Heimdall_Data.config.minimapTagger.alertTTL) end ---@type Frame[] local tagFramePool = {} local tagFramePoolMaxSize = 20 for i = 1, tagFramePoolMaxSize do local frame = CreateFrame("Frame") frame.custom = { busy = false } local texture = frame:CreateTexture(nil, "ARTWORK") texture:SetAllPoints(frame) texture:SetTexture("Interface\\AddOns\\WeakAuras\\PowerAurasMedia\\Auras\\Aura11") --texture:SetTexture("Interface\\AddOns\\Heimdall\\Texture\\Tag") table.insert(tagFramePool, frame) end ---@param x number ---@param y number ---@param scale number? local function PlantTag(x, y, scale) local frame = nil for _, tagFrame in ipairs(tagFramePool) do if not tagFrame.custom.busy then frame = tagFrame break end end if not frame then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Tag frame pool is full and could not get frame", ModuleName)) end return end if Heimdall_Data.config.minimapTagger.tagSound then PlaySoundFile("Interface\\AddOns\\Heimdall\\Sound\\Tag.mp3") end PlantFrame(x, y, frame, scale, Heimdall_Data.config.minimapTagger.tagTTL) end ---@type Frame[] local battleFramePool = {} local battleFramePoolMaxSize = 20 for i = 1, battleFramePoolMaxSize do local frame = CreateFrame("Frame") frame.custom = { busy = false } local texture = frame:CreateTexture(nil, "ARTWORK") texture:SetAllPoints(frame) texture:SetTexture("Interface\\AddOns\\WeakAuras\\PowerAurasMedia\\Auras\\Aura19") --texture:SetTexture("Interface\\AddOns\\Heimdall\\Texture\\Fight") table.insert(battleFramePool, frame) end ---@param x number ---@param y number ---@param scale number? local function PlantBattle(x, y, scale) local frame = nil for _, battleFrame in ipairs(battleFramePool) do if not battleFrame.custom.busy then frame = battleFrame break end end if not frame then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Battle frame pool is full and could not get frame", ModuleName)) end return end if Heimdall_Data.config.minimapTagger.combatSound then PlaySoundFile("Interface\\AddOns\\Heimdall\\Sound\\Fight.mp3") end PlantFrame(x, y, frame, scale, Heimdall_Data.config.minimapTagger.combatTTL) end local pauseUntil = 0 local frame = CreateFrame("Frame") frame:RegisterEvent("WORLD_MAP_UPDATE") frame:SetScript("OnEvent", function(self, event, addon) if pauseUntil > GetTime() then return end pauseUntil = GetTime() + 1 if not BattlefieldMinimap then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] BattlefieldMinimap not found", ModuleName)) end return end if not Heimdall_Data.config.minimapTagger.enabled then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] MinimapTagger is disabled", ModuleName)) end return end --local scale = Heimdall_Data.config.minimapTagger.scale local scale = 4 BattlefieldMinimap:SetScale(scale) BattlefieldMinimap:SetMovable(true) BattlefieldMinimap:EnableMouse(true) BattlefieldMinimap:RegisterForDrag("LeftButton") BattlefieldMinimap:SetScript("OnDragStart", function(self) self:StartMoving() end) BattlefieldMinimap:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end) BattlefieldMinimapBackground:Hide() BattlefieldMinimapCloseButton:Hide() BattlefieldMinimapCorner:Hide() BattlefieldMinimap:HookScript("OnHide", function(self) for _, alertFrame in ipairs(alertFramePool) do alertFrame:Hide() alertFrame.custom.busy = false end for _, tagFrame in ipairs(tagFramePool) do tagFrame:Hide() tagFrame.custom.busy = false end for _, battleFrame in ipairs(battleFramePool) do battleFrame:Hide() battleFrame.custom.busy = false end end) end) local chatFrame = CreateFrame("Frame") chatFrame:RegisterEvent("CHAT_MSG_CHANNEL") chatFrame:SetScript("OnEvent", function(self, event, msg, sender, ...) -- if Heimdall_Data.config.echoer.debug then -- print(string.format("[%s] Channel message received from: %s", ModuleName, sender)) -- end if not Heimdall_Data.config.minimapTagger.enabled then -- if Heimdall_Data.config.echoer.debug then -- print(string.format("[%s] Module disabled, ignoring message", ModuleName)) -- end return end local channelId = select(6, ...) local _, channelname = GetChannelName(channelId) -- if Heimdall_Data.config.echoer.debug then -- print(string.format("[%s] Processing message from channel: %s", ModuleName, channelname)) -- end if channelname ~= Heimdall_Data.config.minimapTagger.masterChannel then -- if Heimdall_Data.config.echoer.debug then -- print(string.format("[%s] Ignoring message from non-master channel", ModuleName)) -- end return end if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Processing message from master channel: %s", ModuleName, sender)) shared.dumpTable(Heimdall_Data.config.minimapTagger) end if string.find(msg, "^I see") then if Heimdall_Data.config.minimapTagger.tagTTL == 0 then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Tag TTL is 0, ignoring message: %s", ModuleName, msg)) end return end local x, y = string.match(msg, "%((%d+%.%d+)%s*,%s*(%d+%.%d+)%)") if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Found alert position: %s, %s", ModuleName, tostring(x), tostring(y))) end if x and y then PlantTag(tonumber(x), tonumber(y), 2) end end if string.find(msg, "^I am in combat with") then if Heimdall_Data.config.minimapTagger.combatTTL == 0 then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Combat TTL is 0, ignoring message: %s", ModuleName, msg)) end return end if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Found combat alert in message: %s", ModuleName, msg)) end local x, y = string.match(msg, "%((%d+%.%d+)%s*,%s*(%d+%.%d+)%)") if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Found combat position: %s, %s", ModuleName, tostring(x), tostring(y))) end if x and y then PlantBattle(tonumber(x), tonumber(y), 2) end end if string.find(msg, " killed ") then if Heimdall_Data.config.minimapTagger.alertTTL == 0 then if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Alert TTL is 0, ignoring message: %s", ModuleName, msg)) end return end if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Found death alert in message: %s", ModuleName, msg)) end local x, y = string.match(msg, "%((%d+%.%d+)%s*,%s*(%d+%.%d+)%)") if Heimdall_Data.config.minimapTagger.debug then print(string.format("[%s] Found death position: %s, %s", ModuleName, tostring(x), tostring(y))) end if x and y then PlantAlert(tonumber(x), tonumber(y), 2) end end end) print("[Heimdall] MinimapTagger loaded") end SlashCmdList["HEIMDALL_MINIMAPTAGGER"] = function(args) shared.MinimapTagger.Init() end SLASH_HEIMDALL_MINIMAPTAGGER1 = "/mf"