You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
11 KiB

local _, Cell = ...
local L = Cell.L
local F = Cell.funcs
local UnitIsFeignDeath = UnitIsFeignDeath
local IsInGroup = IsInGroup
local IsEncounterInProgress = IsEncounterInProgress
----------------------------------------------------
-- vars
----------------------------------------------------
local init, instanceType, inInstance
local deathLogs = {
-- time, type, name, ability, school, amount, overkill, resisted, blocked, absorbed, critical, sourceName
}
local limit, count
local blacklist = {
[124255] = true
}
local overkillFormat, resistedFormat, blockedFormat, absorbedFormat, criticalText
if Cell.isAsian then
overkillFormat = string.sub(_G.TEXT_MODE_A_STRING_RESULT_OVERKILLING, 4, string.len(_G.TEXT_MODE_A_STRING_RESULT_OVERKILLING)-3)
resistedFormat = string.sub(_G.TEXT_MODE_A_STRING_RESULT_RESIST, 4, string.len(_G.TEXT_MODE_A_STRING_RESULT_RESIST)-3)
blockedFormat = string.sub(_G.TEXT_MODE_A_STRING_RESULT_BLOCK, 4, string.len(_G.TEXT_MODE_A_STRING_RESULT_BLOCK)-3)
absorbedFormat = string.sub(_G.TEXT_MODE_A_STRING_RESULT_ABSORB, 4, string.len(_G.TEXT_MODE_A_STRING_RESULT_ABSORB)-3)
criticalText = string.sub(_G.TEXT_MODE_A_STRING_RESULT_CRITICAL, 4, string.len(_G.TEXT_MODE_A_STRING_RESULT_CRITICAL)-3)
else
overkillFormat = strlower(string.gsub(_G.TEXT_MODE_A_STRING_RESULT_OVERKILLING, "[()]", ""))
resistedFormat = strlower(string.gsub(_G.TEXT_MODE_A_STRING_RESULT_RESIST, "[()]", ""))
blockedFormat = strlower(string.gsub(_G.TEXT_MODE_A_STRING_RESULT_BLOCK, "[()]", ""))
absorbedFormat = strlower(string.gsub(_G.TEXT_MODE_A_STRING_RESULT_ABSORB, "[()]", ""))
criticalText = strlower(string.gsub(_G.TEXT_MODE_A_STRING_RESULT_CRITICAL, "[()]", ""))
end
----------------------------------------------------
-- functions
----------------------------------------------------
local function UpdateDeathLog(guid, ...)
if not deathLogs[guid] then
deathLogs[guid] = {}
end
deathLogs[guid]["time"], deathLogs[guid]["type"], deathLogs[guid]["name"], deathLogs[guid]["ability"],
deathLogs[guid]["school"], deathLogs[guid]["amount"], deathLogs[guid]["overkill"], deathLogs[guid]["resisted"],
deathLogs[guid]["blocked"], deathLogs[guid]["absorbed"], deathLogs[guid]["critical"], deathLogs[guid]["sourceName"] = ...
deathLogs[guid]["reported"] = false
end
local function Send(msg)
-- F:Print(strupper(ACTION_UNIT_DIED)..": "..msg)
if Cell.hasHighestPriority then
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
SendChatMessage(strupper(ACTION_UNIT_DIED)..": "..msg, "INSTANCE_CHAT")
else
SendChatMessage(strupper(ACTION_UNIT_DIED)..": "..msg, IsInRaid() and "RAID" or "PARTY")
end
end
end
local function Report(guid)
if not deathLogs[guid] or deathLogs[guid]["reported"] then return end
deathLogs[guid]["reported"] = true
if instanceType == "raid" and IsEncounterInProgress() then
count = count + 1
if count > limit then
return
end
end
if not deathLogs[guid]["type"] or time()-deathLogs[guid]["time"]>=1 then -- unkown
-- Send(deathLogs[guid]["name"].." > "..strlower(_G.UNKNOWN))
Send(deathLogs[guid]["name"])
elseif deathLogs[guid]["type"] == "INSTAKILL" then
Send(deathLogs[guid]["name"].." > "..L["instakill"])
elseif deathLogs[guid]["type"] == "ENVIRONMENTAL" then
Send(deathLogs[guid]["name"].." > "..F:FormatNumber(deathLogs[guid]["amount"]).." ("..deathLogs[guid]["ability"]..")")
else -- SPELL & RANGE & SWING
-- local damageDetails = {}
local damageDetails = ""
if deathLogs[guid]["overkill"] > 0 then
-- tinsert(damageDetails, string.format(overkillFormat, F:FormatNumber(deathLogs[guid]["overkill"])))
damageDetails = " ("..string.format(overkillFormat, F:FormatNumber(deathLogs[guid]["overkill"]))..") "
end
-- if deathLogs[guid]["critical"] == 1 then
-- tinsert(damageDetails, criticalText)
-- end
-- if deathLogs[guid]["resisted"] then
-- tinsert(damageDetails, string.format(resistedFormat, F:FormatNumber(deathLogs[guid]["resisted"])))
-- end
-- if deathLogs[guid]["blocked"] then
-- tinsert(damageDetails, string.format(blockedFormat, F:FormatNumber(deathLogs[guid]["blocked"])))
-- end
-- if deathLogs[guid]["absorbed"] then
-- tinsert(damageDetails, string.format(absorbedFormat, F:FormatNumber(deathLogs[guid]["absorbed"])))
-- end
-- damageDetails = table.concat(damageDetails, ", ")
local sourceName = (deathLogs[guid]["sourceName"] and deathLogs[guid]["name"]~=deathLogs[guid]["sourceName"]) and (" ["..deathLogs[guid]["sourceName"].."]") or ""
local ability
if deathLogs[guid]["type"] == "SPELL" then -- including RANGE
-- tinsert(damageDetails, strlower(CombatLog_String_SchoolString(deathLogs[guid]["school"])))
ability = deathLogs[guid]["ability"]
else -- SWING
ability = strlower(_G.MELEE)
end
-- damageDetails = table.concat(damageDetails, ", ")
-- if damageDetails ~= "" then damageDetails = " ("..damageDetails..") " end
Send(deathLogs[guid]["name"].." > "..ability.." "..F:FormatNumber(deathLogs[guid]["amount"])..damageDetails..sourceName)
end
-- wipe(deathLogs[guid])
end
----------------------------------------------------
-- event
----------------------------------------------------
local frame = CreateFrame("Frame")
-- frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
function frame:PLAYER_ENTERING_WORLD()
local isIn, iType = IsInInstance()
instanceType = iType
if instanceType == "pvp" or instanceType == "arena" then
frame:UnregisterEvent("ENCOUNTER_START")
frame:UnregisterEvent("ENCOUNTER_END")
frame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:UnregisterEvent("GROUP_ROSTER_UPDATE")
return
else
frame:RegisterEvent("GROUP_ROSTER_UPDATE")
end
if not init then frame:GROUP_ROSTER_UPDATE() end
if isIn then
inInstance = true
if instanceType == "raid" then
frame:RegisterEvent("ENCOUNTER_START")
count = 0
else
frame:UnregisterEvent("ENCOUNTER_START")
end
elseif inInstance then -- left insntance
inInstance = false
wipe(deathLogs)
frame:UnregisterEvent("ENCOUNTER_START")
end
-- texplore(deathLogs)
end
local timer
function frame:GROUP_ROSTER_UPDATE()
if IsInGroup() then
if IsEncounterInProgress() then
frame:RegisterEvent("ENCOUNTER_END")
else
if timer then timer:Cancel() end
timer = C_Timer.NewTimer(7, function()
F:CheckPriority()
end)
end
else
frame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
init = true
end
function frame:ENCOUNTER_END()
frame:UnregisterEvent("ENCOUNTER_END")
frame:GROUP_ROSTER_UPDATE()
end
function frame:ENCOUNTER_START()
count = 0
end
function frame:COMBAT_LOG_EVENT_UNFILTERED(...)
local timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, arg12, arg13, arg14 = ...
local amount, overkill, school, resisted, blocked, absorbed, critical -- glancing, crushing
-- arg12, arg13, arg14,
-- UNIT_DIED: recapID, unconsciousOnDeath
-- ENVIRONMENTAL: environmentalType
-- SPELL/RANGE: spellId, spellName, spellSchool
-- if string.find(destGUID, "^Player") then -- debug
if string.find(destGUID, "^Player") and F:IsFriend(destFlags) then
if event == "SPELL_INSTAKILL" then
UpdateDeathLog(destGUID, timestamp, "INSTAKILL", destName)
end
if event == "ENVIRONMENTAL_DAMAGE" then
amount, overkill, school, resisted, blocked, absorbed, critical = select(13, ...)
amount = amount == 0 and absorbed or amount
-- _G.ENVIRONMENTAL_DAMAGE.." "..
UpdateDeathLog(destGUID, timestamp, "ENVIRONMENTAL", destName, strlower(_G["ACTION_ENVIRONMENTAL_DAMAGE_" .. strupper(arg12)]), nil, amount)
end
if event == "SWING_DAMAGE" then
amount, overkill, school, resisted, blocked, absorbed, critical = select(12, ...)
UpdateDeathLog(destGUID, timestamp, "SWING", destName, nil, school, amount, overkill or -1, resisted, blocked, absorbed, critical, sourceName)
end
if event == "SPELL_DAMAGE" or event == "SPELL_PERIODIC_DAMAGE" or event == "RANGE_DAMAGE" then
if not blacklist[arg12] then
amount, overkill, school, resisted, blocked, absorbed, critical = select(15, ...)
local spellLink = GetSpellLink(arg12)
UpdateDeathLog(destGUID, timestamp, "SPELL", destName, spellLink, school, amount, overkill or -1, resisted, blocked, absorbed, critical, sourceName)
end
end
if event == "SPELL_AURA_APPLIED" then
-- print(arg12, arg13, arg14)
if arg12 == 27827 or arg12 == 358164 then -- 救赎之魂 or 灵魂疲惫
C_Timer.After(0.25, function()
Report(destGUID)
end)
end
end
if event == "UNIT_DIED" and not UnitIsFeignDeath(destName) then
C_Timer.After(0.5, function()
if not deathLogs[destGUID] then deathLogs[destGUID] = {["name"]=destName} end
Report(destGUID)
end)
end
end
end
frame:SetScript("OnEvent", function(self, event, ...)
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
self:COMBAT_LOG_EVENT_UNFILTERED(CombatLogGetCurrentEventInfo())
else
self[event](self, ...)
end
end)
----------------------------------------------------
-- priority
----------------------------------------------------
local function UpdatePriority(hasHighestPriority)
if hasHighestPriority and CellDB["tools"]["deathReport"][1] then
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
else
frame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
end
Cell:RegisterCallback("UpdatePriority", "DeathReport_UpdatePriority", UpdatePriority)
----------------------------------------------------
-- UpdateTools
----------------------------------------------------
local enabled
local function UpdateTools(which)
if not which or which == "deathReport" then
if CellDB["tools"]["deathReport"][1] then
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("GROUP_ROSTER_UPDATE")
limit = CellDB["tools"]["deathReport"][2]
count = 0
if not enabled and which == "deathReport" then -- already in world, manually enabled
frame:PLAYER_ENTERING_WORLD()
end
enabled = true
else
frame:UnregisterAllEvents()
wipe(deathLogs)
enabled = false
end
end
end
Cell:RegisterCallback("UpdateTools", "DeathReport_UpdateTools", UpdateTools)