-- 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