Adds DPSMate_CLEUAdapter.lua -- replaces DPSMate's string-parsing CHAT_MSG_* system with structured COMBAT_LOG_EVENT data from our DLL. Adapter maps CLEU subevents directly to DPSMate.DB API calls: DamageDone, DamageTaken, EnemyDamage, Healing, HealingTaken, DeathHistory, Kick, Dispels, BuildBuffs, CCBreaker, etc. Eliminates all strfind pattern matching from the combat log path. Toggle: /dpscleu (on/off/status) Benchmark: /dpsbench -- always-on per-combat A/B profiling. Resets at combat start, reports at combat end, flips mode for next combat. Reports events, total ms, us/event, GC delta, and percentage comparison between CLEU and original modes. Starts in CLEU mode by default.
299 lines
9.4 KiB
Lua
299 lines
9.4 KiB
Lua
-- Global Variables
|
|
DPSMate.Modules.Damage = {}
|
|
DPSMate.Modules.Damage.Hist = "DMGDone"
|
|
DPSMate.Options.Options[1]["args"]["damage"] = {
|
|
order = 20,
|
|
type = 'toggle',
|
|
name = DPSMate.L["damage"],
|
|
desc = DPSMate.L["show"].." "..DPSMate.L["damage"]..".",
|
|
get = function() return DPSMateSettings["windows"][DPSMate.Options.Dewdrop:GetOpenedParent().Key]["options"][1]["damage"] end,
|
|
set = function() DPSMate.Options:ToggleDrewDrop(1, "damage", DPSMate.Options.Dewdrop:GetOpenedParent()) end,
|
|
}
|
|
DPSMate.Modules.Damage.Events = {
|
|
"CHAT_MSG_COMBAT_SELF_HITS",
|
|
"CHAT_MSG_COMBAT_SELF_MISSES",
|
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
|
"CHAT_MSG_COMBAT_PARTY_HITS",
|
|
"CHAT_MSG_SPELL_PARTY_DAMAGE",
|
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
|
-- Pet Damage
|
|
"CHAT_MSG_COMBAT_PET_HITS",
|
|
"CHAT_MSG_COMBAT_PET_MISSES",
|
|
--"CHAT_MSG_SPELL_PET_BUFF",
|
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
|
}
|
|
|
|
-- Register the moodule
|
|
DPSMate:Register("damage", DPSMate.Modules.Damage, DPSMate.L["damage"])
|
|
|
|
local tinsert = table.insert
|
|
local strformat = string.format
|
|
local pairs = pairs
|
|
|
|
function DPSMate.Modules.Damage:GetSortedTable(arr, k)
|
|
local b, a, total, CV, i, name = {}, {}, 0
|
|
local petsByOwner = DPSMateSettings["mergepets"] and DPSMate:GetPetsByOwner(arr) or {}
|
|
local processedOwners = {}
|
|
for cat, val in pairs(arr) do
|
|
name = DPSMate:GetUserById(cat)
|
|
if not name or not DPSMateUser[name] then
|
|
-- skip unknown users
|
|
elseif (not DPSMateUser[name][4] or (DPSMateUser[name][4] and not DPSMateSettings["mergepets"])) then
|
|
if DPSMate:ApplyFilter(k, name) then
|
|
CV = val["i"] or 0
|
|
if DPSMateSettings["mergepets"] and petsByOwner[cat] then
|
|
processedOwners[cat] = true
|
|
for _, petCat in pairs(petsByOwner[cat]) do
|
|
if arr[petCat] then
|
|
CV = CV + (arr[petCat]["i"] or 0)
|
|
end
|
|
end
|
|
end
|
|
i = 1
|
|
while true do
|
|
if (not b[i]) then
|
|
tinsert(b, i, CV)
|
|
tinsert(a, i, name)
|
|
break
|
|
else
|
|
if b[i] < CV then
|
|
tinsert(b, i, CV)
|
|
tinsert(a, i, name)
|
|
break
|
|
end
|
|
end
|
|
i=i+1
|
|
end
|
|
total = total + CV
|
|
end
|
|
end
|
|
end
|
|
-- Handle owners with no personal damage but with pets that have damage
|
|
if DPSMateSettings["mergepets"] then
|
|
for oid, petList in pairs(petsByOwner) do
|
|
if not processedOwners[oid] and not arr[oid] then
|
|
name = DPSMate:GetUserById(oid)
|
|
if name and DPSMateUser[name] and not DPSMateUser[name][4] and DPSMate:ApplyFilter(k, name) then
|
|
CV = 0
|
|
for _, petCat in pairs(petList) do
|
|
if arr[petCat] then
|
|
CV = CV + (arr[petCat]["i"] or 0)
|
|
end
|
|
end
|
|
if CV > 0 then
|
|
i = 1
|
|
while true do
|
|
if (not b[i]) then
|
|
tinsert(b, i, CV)
|
|
tinsert(a, i, name)
|
|
break
|
|
else
|
|
if b[i] < CV then
|
|
tinsert(b, i, CV)
|
|
tinsert(a, i, name)
|
|
break
|
|
end
|
|
end
|
|
i=i+1
|
|
end
|
|
total = total + CV
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return b, total, a
|
|
end
|
|
|
|
function DPSMate.Modules.Damage:EvalTable(user, k)
|
|
if not user then return end
|
|
local a, u, p, d, total, pet = {}, {}, {}, {}, 0, false
|
|
local arr = DPSMate:GetMode(k)
|
|
u = {user[1]}
|
|
if DPSMateSettings["mergepets"] then
|
|
local petsByOwner = DPSMate:GetPetsByOwner(arr)
|
|
if petsByOwner[user[1]] then
|
|
for _, petCat in pairs(petsByOwner[user[1]]) do
|
|
tinsert(u, petCat)
|
|
end
|
|
end
|
|
end
|
|
if not arr[user[1]] and getn(u) <= 1 then return end
|
|
for _, v in pairs(u) do
|
|
if arr[v] then
|
|
for cat, val in pairs(arr[v]) do
|
|
if (type(val) == "table" and cat~="i") then
|
|
if val[13] and val[13]~=0 and cat~="" then
|
|
local vname = DPSMate:GetUserById(v)
|
|
if vname and DPSMateUser[vname] and DPSMateUser[vname][4] then pet=vname; else pet=false; end
|
|
local i = 1
|
|
while true do
|
|
if (not d[i]) then
|
|
tinsert(a, i, cat)
|
|
tinsert(d, i, {val[13], pet})
|
|
break
|
|
else
|
|
if (d[i][1] < val[13]) then
|
|
tinsert(a, i, cat)
|
|
tinsert(d, i, {val[13], pet})
|
|
break
|
|
end
|
|
end
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
total=total+(arr[v]["i"] or 0)
|
|
end
|
|
end
|
|
return a, total, d
|
|
end
|
|
|
|
function DPSMate.Modules.Damage:GetSettingValues(arr, cbt, k,ecbt)
|
|
local pt = ""
|
|
local name, value, perc, sortedTable, total, a, p, strt = {}, {}, {}, {}, 0, 0, "", {[1]="",[2]=""}
|
|
if DPSMateSettings["windows"][k]["numberformat"] == 2 or DPSMateSettings["windows"][k]["numberformat"] == 4 then p = "K"; pt = "K" end
|
|
sortedTable, total, a = DPSMate.Modules.Damage:GetSortedTable(arr, k)
|
|
local validCbt = cbt and cbt > 0.001
|
|
for cat, val in pairs(sortedTable) do
|
|
local dmg, tot, sort, dmgr, totr, sortr = DPSMate:FormatNumbers(val, total, sortedTable[1], k)
|
|
if dmgr==0 then break end; if totr <= 10000 then pt = "" end; if dmgr<=10000 then p = "" end
|
|
local str = {[1]="",[2]="",[3]="",[4]=""}
|
|
local pname = a[cat]
|
|
if DPSMateSettings["columnsdmg"][1] then str[1] = " "..DPSMate:Commas(dmg, k)..p; strt[2] = DPSMate:Commas(tot, k)..pt end
|
|
if DPSMateSettings["columnsdmg"][2] and validCbt then str[2] = "("..strformat("%.1f", (dmg/cbt))..p..")"; strt[1] = "("..strformat("%.1f", (tot/cbt))..pt..") " end
|
|
if DPSMateSettings["columnsdmg"][3] then str[3] = " ("..strformat("%.1f", 100*dmgr/totr).."%)" end
|
|
if DPSMateSettings["columnsdmg"][4] then local ev = (type(ecbt)=="table" and ecbt[pname]) or cbt; if ev and ev > 0.001 then str[4] = " ("..strformat("%.1f", dmg/ev)..p..")" end end
|
|
tinsert(name, a[cat])
|
|
tinsert(value, str[2]..str[1]..str[4]..str[3])
|
|
tinsert(perc, 100*(dmgr/sortr))
|
|
end
|
|
return name, value, perc, strt
|
|
end
|
|
|
|
function DPSMate.Modules.Damage:ShowTooltip(user,k)
|
|
if DPSMateSettings["informativetooltips"] then
|
|
if not DPSMateUser[user] then return end
|
|
local a,b,c = DPSMate.Modules.Damage:EvalTable(DPSMateUser[user], k)
|
|
local db = DPSMate:GetModeByArr(DPSMateEDT, k, "EDTaken")
|
|
local i, p = 1, 0
|
|
local pet = 0
|
|
local edtaken, edtakenPet = {}, {}
|
|
|
|
-- Find all pet IDs for this owner
|
|
local ownerId = DPSMateUser[user][1]
|
|
local petIds = {}
|
|
local petNames = {}
|
|
for pname, pdata in pairs(DPSMateUser) do
|
|
if pdata[4] and pdata[6] == ownerId then
|
|
tinsert(petIds, pdata[1])
|
|
tinsert(petNames, pname)
|
|
end
|
|
end
|
|
|
|
-- Getting the value of the pet
|
|
while a and a[i] do
|
|
if c[i][2] then
|
|
pet = pet + c[i][1]
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
-- Getting edt values
|
|
for cat, val in pairs(db) do
|
|
if val[ownerId] then
|
|
if val[ownerId]["i"] and val[ownerId]["i"]>0 then
|
|
i = 1
|
|
while true do
|
|
if (not edtaken[i]) then
|
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
|
break
|
|
else
|
|
if (edtaken[i][2] < val[ownerId]["i"]) then
|
|
tinsert(edtaken, i, {cat, val[ownerId]["i"]})
|
|
break
|
|
end
|
|
end
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
-- Aggregate EDT from all pets for this enemy
|
|
local petTotal = 0
|
|
for _, pid in pairs(petIds) do
|
|
if val[pid] and (val[pid]["i"] or 0) > 0 then
|
|
petTotal = petTotal + (val[pid]["i"] or 0)
|
|
end
|
|
end
|
|
if petTotal > 0 then
|
|
i = 1
|
|
while true do
|
|
if (not edtakenPet[i]) then
|
|
tinsert(edtakenPet, i, {cat, petTotal})
|
|
break
|
|
else
|
|
if (edtakenPet[i][2] < petTotal) then
|
|
tinsert(edtakenPet, i, {cat, petTotal})
|
|
break
|
|
end
|
|
end
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
|
for i=1, DPSMateSettings["subviewrows"] do
|
|
if not a[i] then break end
|
|
if not c[i][2] then
|
|
local div = (b-pet) ~= 0 and (b-pet) or 1
|
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetAbilityById(a[i]),c[i][1].." ("..strformat("%.2f", 100*c[i][1]/div).."%)",1,1,1,1,1,1)
|
|
end
|
|
end
|
|
|
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttattacked"])
|
|
for i=1, DPSMateSettings["subviewrows"] do
|
|
if not edtaken[i] then break end
|
|
local ediv = (b-pet) ~= 0 and (b-pet) or 1
|
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtaken[i][1]), edtaken[i][2].." ("..strformat("%.2f", 100*edtaken[i][2]/ediv).."%)", 1,1,1,1,1,1)
|
|
end
|
|
|
|
if pet~=0 and getn(petIds) > 0 then
|
|
local petDisplay = table.concat(petNames, ", ")
|
|
GameTooltip:AddLine(" ")
|
|
GameTooltip:AddDoubleLine(DPSMate.L["ttpet2"],petDisplay.."<"..user.."> ("..strformat("%.2f", 100*pet/b).."%)",1,0.82,0,1,1,1)
|
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttdamage"]..DPSMate.L["ttabilities"])
|
|
i, p = 1,1
|
|
while DPSMateSettings["subviewrows"]>=p do
|
|
if not a[i] then break end
|
|
if c[i][2] then
|
|
GameTooltip:AddDoubleLine(p..". "..DPSMate:GetAbilityById(a[i]),c[i][1].." ("..strformat("%.2f", 100*c[i][1]/pet).."%)",1,1,1,1,1,1)
|
|
p = p + 1
|
|
end
|
|
i = i + 1
|
|
end
|
|
GameTooltip:AddLine(DPSMate.L["tttop"]..DPSMateSettings["subviewrows"]..DPSMate.L["ttpet"]..DPSMate.L["ttattacked"])
|
|
for i=1, DPSMateSettings["subviewrows"] do
|
|
if not edtakenPet[i] then break end
|
|
GameTooltip:AddDoubleLine(i..". "..DPSMate:GetUserById(edtakenPet[i][1]), edtakenPet[i][2].." ("..strformat("%.2f", 100*edtakenPet[i][2]/pet).."%)", 1,1,1,1,1,1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function DPSMate.Modules.Damage:OpenDetails(obj, key, bool)
|
|
if bool then
|
|
DPSMate.Modules.DetailsDamage:UpdateCompare(obj, key, bool)
|
|
else
|
|
DPSMate.Modules.DetailsDamage:UpdateDetails(obj, key)
|
|
end
|
|
end
|
|
|
|
function DPSMate.Modules.Damage:OpenTotalDetails(obj, key)
|
|
DPSMate.Modules.DetailsDamageTotal:UpdateDetails(obj, key)
|
|
end
|