local addonname, data = ... ---@cast data HeimdallData ---@cast addonname string data.DeathReporter = {} function data.DeathReporter.Init() if not data.config.deathReporter.enabled then return end ---@type table local recentDeaths = {} ---@type table local notifyTimers = {} ---@param source string ---@param destination string ---@param spellName string ---@param overkill number local function RegisterDeath(source, destination, spellName, overkill) if recentDeaths[destination] and GetTime() - recentDeaths[destination] < data.config.deathReporter.throttle then return end recentDeaths[destination] = GetTime() local timer = C_Timer.NewTimer(1, function() local zone = data.config.deathReporter.zoneOverride if not zone then zone = string.format("%s (%s)", GetZoneText(), GetSubZoneText()) end local text = string.format("%s killed %s with %s in %s", tostring(source), tostring(destination), tostring(spellName), tostring(zone)) ---@type Message local msg = { channel = "CHANNEL", data = data.config.deathReporter.notifyChannel, message = text, } table.insert(data.messenger.queue, msg) if data.config.deathReporter.doWhisper then for _, name in pairs(data.config.whisperNotify) do local msg = { channel = "WHISPER", data = name, message = text, } table.insert(data.messenger.queue, msg) end end notifyTimers[destination] = nil end) notifyTimers[destination] = timer end local cleuFrame = CreateFrame("Frame") cleuFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") cleuFrame:SetScript("OnEvent", function(self, event, ...) local overkill, err = CLEUParser.GetOverkill(...) if not err and overkill > 0 then local source, err = CLEUParser.GetSourceName(...) if err then source = "unknown" end local destination, err = CLEUParser.GetDestName(...) if err then destination = "unknown" end local spellName, err = CLEUParser.GetSpellName(...) if err then spellName = "unknown" end local sourceGUID, err = CLEUParser.GetSourceGUID(...) if err or not string.match(sourceGUID, "Player") then return end local destinationGUID, err = CLEUParser.GetDestGUID(...) if err or not string.match(destinationGUID, "Player") then return end RegisterDeath(source, destination, spellName, overkill) end end) local systemMessageFrame = CreateFrame("Frame") systemMessageFrame:RegisterEvent("CHAT_MSG_SYSTEM") systemMessageFrame:SetScript("OnEvent", function(self, event, msg) local source, destination = string.match(msg, "(.+) has defeated (.+) in a duel") if source and destination then print(string.format("Cancelling death reports for %s and %s", source, destination)) if notifyTimers[source] then notifyTimers[source]:Cancel() end if notifyTimers[destination] then notifyTimers[destination]:Cancel() end end end) end