Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Based on RecountGuessedAbsorbs by Elsia
- local L = LibStub("AceLocale-3.0"):GetLocale("Skada", false)
- local Skada = Skada
- local mod = Skada:NewModule(L["Absorbs"])
- local playermod = Skada:NewModule(L["Absorb details"])
- local combined = Skada:NewModule(L["Absorbs and healing"])
- -- This bit shamelessly copied straight from RecountGuessedAbsorbs - thanks!
- local AbsorbSpellDuration =
- {
- -- Death Knight
- [48707] = 5, -- Anti-Magic Shell (DK) Rank 1 -- Does not currently seem to show tracable combat log events. It shows energizes which do not reveal the amount of damage absorbed
- [51052] = 10, -- Anti-Magic Zone (DK)( Rank 1 (Correct spellID?)
- -- Does DK Spell Deflection show absorbs in the CL?
- [51271] = 20, -- Unbreakable Armor (DK)
- -- Druid
- [62606] = 10, -- Savage Defense proc. (Druid) Tooltip of the original spell doesn't clearly state that this is an absorb, but the buff does.
- -- Mage
- [11426] = 60, -- Ice Barrier (Mage) Rank 1
- [13031] = 60,
- [13032] = 60,
- [13033] = 60,
- [27134] = 60,
- [33405] = 60,
- [43038] = 60,
- [43039] = 60, -- Rank 8
- [6143] = 30, -- Frost Ward (Mage) Rank 1
- [8461] = 30,
- [8462] = 30,
- [10177] = 30,
- [28609] = 30,
- [32796] = 30,
- [43012] = 30, -- Rank 7
- [1463] = 60, -- Mana shield (Mage) Rank 1
- [8494] = 60,
- [8495] = 60,
- [10191] = 60,
- [10192] = 60,
- [10193] = 60,
- [27131] = 60,
- [43019] = 60,
- [43020] = 60, -- Rank 9
- [543] = 30 , -- Fire Ward (Mage) Rank 1
- [8457] = 30,
- [8458] = 30,
- [10223] = 30,
- [10225] = 30,
- [27128] = 30,
- [43010] = 30, -- Rank 7
- -- Paladin
- [58597] = 6, -- Sacred Shield (Paladin) proc (Fixed, thanks to Julith)
- -- Priest
- [17] = 30, -- Power Word: Shield (Priest) Rank 1
- [592] = 30,
- [600] = 30,
- [3747] = 30,
- [6065] = 30,
- [6066] = 30,
- [10898] = 30,
- [10899] = 30,
- [10900] = 30,
- [10901] = 30,
- [25217] = 30,
- [25218] = 30,
- [48065] = 30,
- [48066] = 30, -- Rank 14
- [47509] = 12, -- Divine Aegis (Priest) Rank 1
- [47511] = 12,
- [47515] = 12, -- Divine Aegis (Priest) Rank 3 (Some of these are not actual buff spellIDs)
- [47753] = 12, -- Divine Aegis (Priest) Rank 1
- [54704] = 12, -- Divine Aegis (Priest) Rank 1
- [47788] = 10, -- Guardian Spirit (Priest) (50 nominal absorb, this may not show in the CL)
- -- Warlock
- [7812] = 30, -- Sacrifice (warlock) Rank 1
- [19438] = 30,
- [19440] = 30,
- [19441] = 30,
- [19442] = 30,
- [19443] = 30,
- [27273] = 30,
- [47985] = 30,
- [47986] = 30, -- rank 9
- [6229] = 30, -- Shadow Ward (warlock) Rank 1
- [11739] = 30,
- [11740] = 30,
- [28610] = 30,
- [47890] = 30,
- [47891] = 30, -- Rank 6
- -- Consumables
- [29674] = 86400, -- Lesser Ward of Shielding
- [29719] = 86400, -- Greater Ward of Shielding (these have infinite duration, set for a day here :P)
- [29701] = 86400,
- [28538] = 120, -- Major Holy Protection Potion
- [28537] = 120, -- Major Shadow
- [28536] = 120, -- Major Arcane
- [28513] = 120, -- Major Nature
- [28512] = 120, -- Major Frost
- [28511] = 120, -- Major Fire
- [7233] = 120, -- Fire
- [7239] = 120, -- Frost
- [7242] = 120, -- Shadow Protection Potion
- [7245] = 120, -- Holy
- [6052] = 120, -- Nature Protection Potion
- [53915] = 120, -- Mighty Shadow Protection Potion
- [53914] = 120, -- Mighty Nature Protection Potion
- [53913] = 120, -- Mighty Frost Protection Potion
- [53911] = 120, -- Mighty Fire
- [53910] = 120, -- Mighty Arcane
- [17548] = 120, -- Greater Shadow
- [17546] = 120, -- Greater Nature
- [17545] = 120, -- Greater Holy
- [17544] = 120, -- Greater Frost
- [17543] = 120, -- Greater Fire
- [17549] = 120, -- Greater Arcane
- [28527] = 15, -- Fel Blossom
- [29432] = 3600, -- Frozen Rune usage (Naxx classic)
- -- Item usage
- [36481] = 4, -- Arcane Barrier (TK Kael'Thas) Shield
- [57350] = 6, -- Darkmoon Card: Illusion
- [17252] = 30, -- Mark of the Dragon Lord (LBRS epic ring) usage
- [25750] = 15, -- Defiler's Talisman/Talisman of Arathor Rank 1
- [25747] = 15,
- [25746] = 15,
- [23991] = 15,
- [31000] = 300, -- Pendant of Shadow's End Usage
- [30997] = 300, -- Pendant of Frozen Flame Usage
- [31002] = 300, -- Pendant of the Null Rune
- [30999] = 300, -- Pendant of Withering
- [30994] = 300, -- Pendant of Thawing
- [31000] = 300, --
- [23506]= 20, -- Arena Grand Master Usage (Aura of Protection)
- [12561] = 60, -- Goblin Construction Helmet usage
- [31771] = 20, -- Runed Fungalcap usage
- [21956] = 10, -- Mark of Resolution usage
- [29506] = 20, -- The Burrower's Shell
- [4057] = 60, -- Flame Deflector
- [4077] = 60, -- Ice Deflector
- [39228] = 20, -- Argussian Compass (may not be an actual absorb)
- -- Item procs
- [27779] = 30, -- Divine Protection - Priest dungeon set 1/2 Proc
- [11657] = 20, -- Jang'thraze (Zul Farrak) proc
- [10368] = 15, -- Uther's Strength proc
- [37515] = 15, -- Warbringer Armor Proc
- [42137] = 86400, -- Greater Rune of Warding Proc
- [26467] = 30, -- Scarab Brooch proc
- [26470] = 8, -- Scarab Brooch proc (actual)
- [27539] = 6, -- Thick Obsidian Breatplate proc
- [28810] = 30, -- Faith Set Proc Armor of Faith
- [54808] = 12, -- Noise Machine proc Sonic Shield
- [55019] = 12, -- Sonic Shield (one of these too ought to be wrong)
- [64411] = 15, -- Blessing of the Ancient (Val'anyr Hammer of Ancient Kings equip effect)
- [64413] = 8, -- Val'anyr, Hammer of Ancient Kings proc Protection of Ancient Kings
- -- Misc
- [40322] = 30, -- Teron's Vengeful Spirit Ghost - Spirit Shield
- -- Boss abilities
- [65874] = 15, -- Twin Val'kyr's Shield of Darkness 175000
- [67257] = 15, -- 300000
- [67256] = 15, -- 700000
- [67258] = 15, -- 1200000
- [65858] = 15, -- Twin Val'kyr's Shield of Lights 175000
- [67260] = 15, -- 300000
- [67259] = 15, -- 700000
- [67261] = 15, -- 1200000
- }
- local shields = {}
- local function AuraApplied(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- local spellId, spellName, spellSchool, auraType = ...
- if AbsorbSpellDuration[spellId] then
- shields[dstName] = shields[dstName] or {}
- shields[dstName][spellId] = shields[dstName][spellId] or {}
- shields[dstName][spellId][srcName] = timestamp + AbsorbSpellDuration[spellId]
- end
- end
- local function AuraRemoved(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- local spellId, spellName, spellSchool, auraType = ...
- if AbsorbSpellDuration[spellId] then
- if shields[dstName] and shields[dstName][spellId] and shields[dstName][spellId][dstName] then
- -- As advised in RecountGuessedAbsorbs, do not remove shields straight away as an absorb can come after the aura removed event.
- shields[dstName][spellId][dstName] = timestamp + 0.1
- end
- end
- end
- local function log_absorb(set, srcName, dstName, absorbed)
- -- Get the player.
- local player = Skada:get_player(set, UnitGUID(srcName), UnitName(srcName))
- if player then
- player.totalabsorbs = player.totalabsorbs + absorbed
- player.absorbs[dstName] = (player.absorbs[dstName] or 0) + absorbed
- set.absorbs = set.absorbs + absorbed
- end
- end
- local function consider_absorb(absorbed, dstName, srcName, timestamp)
- local mintime = nil
- local found_shield_src
- for shield_id, spells in pairs(shields[dstName]) do
- for shield_src, ts in pairs(spells) do
- if ts - timestamp > 0 and (mintime == nil or ts - timestamp < mintime) then
- found_shield_src = shield_src
- end
- end
- end
- if found_shield_src then
- log_absorb(Skada.current, found_shield_src, dstName, absorbed)
- log_absorb(Skada.total, found_shield_src, dstName, absorbed)
- end
- end
- local function SwingDamage(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- local samount, soverkill, sschool, sresisted, sblocked, absorbed, scritical, sglancing, scrushing = ...
- if absorbed and absorbed > 0 and dstName and shields[dstName] and srcName then
- --Skada:Print(dstName.." absorbed "..absorbed.." from "..srcName)
- consider_absorb(absorbed, dstName, srcName, timestamp)
- end
- end
- local function SpellDamage(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- local spellId, spellName, spellSchool, samount, soverkill, sschool, sresisted, sblocked, absorbed, scritical, sglancing, scrushing = ...
- if absorbed and absorbed > 0 and dstName and shields[dstName] and srcName then
- --Skada:Print(dstName.." absorbed "..absorbed.." from "..srcName)
- consider_absorb(absorbed, dstName, srcName, timestamp)
- end
- end
- local function SpellMissed(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- local spellId, spellName, spellSchool, misstype, amount = ...
- if misstype == "ABSORB" and amount > 0 and dstName and shields[dstName] and srcName then
- --Skada:Print(dstName.." absorbed "..absorbed.." from "..srcName.." (MISS)")
- consider_absorb(amount, dstName, srcName, timestamp)
- end
- end
- local function SwingMissed(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
- SpellMissed(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, nil, nil, nil, ...)
- end
- function mod:Update(win, set)
- local nr = 1
- local max = 0
- for i, player in ipairs(set.players) do
- if player.totalabsorbs > 0 then
- local d = win.dataset[nr] or {}
- win.dataset[nr] = d
- d.id = player.id
- d.value = player.totalabsorbs
- d.label = player.name
- d.valuetext = Skada:FormatNumber(player.totalabsorbs)..(" (%02.1f%%)"):format(player.totalabsorbs / set.absorbs * 100)
- d.class = player.class
- if player.totalabsorbs > max then
- max = player.totalabsorbs
- end
- nr = nr + 1
- end
- end
- win.metadata.maxvalue = max
- end
- function playermod:Enter(win, id, label)
- playermod.playerid = id
- playermod.title = label..L["'s Absorbs"]
- end
- function playermod:Update(win, set)
- local player = Skada:find_player(set, self.playerid)
- local nr = 1
- local max = 0
- if player then
- for dstName, absorbed in pairs(player.absorbs) do
- local d = win.dataset[nr] or {}
- win.dataset[nr] = d
- d.id = dstName
- d.value = absorbed
- d.label = dstName
- d.valuetext = Skada:FormatNumber(absorbed)..(" (%02.1f%%)"):format(absorbed / player.totalabsorbs * 100)
- d.class = select(2, UnitClass(dstName))
- if absorbed > max then
- max = absorbed
- end
- nr = nr + 1
- end
- win.metadata.maxvalue = max
- end
- end
- local function getAHPS(set, player)
- local totaltime = Skada:PlayerActiveTime(set, player)
- return (player.totalabsorbs + (player.healing or 0)) / math.max(1,totaltime)
- end
- function combined:Update(win, set)
- local nr = 1
- local max = 0
- for i, player in ipairs(set.players) do
- if player.totalabsorbs > 0 or player.healing > 0 then
- local d = win.dataset[nr] or {}
- win.dataset[nr] = d
- d.id = player.id
- d.value = player.totalabsorbs + (player.healing or 0)
- d.label = player.name
- -- d.valuetext = Skada:FormatNumber(player.totalabsorbs + (player.healing or 0))..(" (%02.1f%%)"):format((player.totalabsorbs + (player.healing or 0)) / (set.absorbs + (set.healing or 0)) * 100)
- d.valuetext = Skada:FormatNumber(player.totalabsorbs + (player.healing or 0))..string.format(" (%02.1f,", getAHPS(set, player))..string.format(" %02.1f%%)", (player.totalabsorbs + (player.healing or 0)) / (set.absorbs + (set.healing or 0)) * 100)
- d.class = player.class
- if (player.totalabsorbs + player.healing) > max then
- max = player.totalabsorbs + player.healing
- end
- nr = nr + 1
- end
- end
- win.metadata.maxvalue = max
- end
- function mod:OnEnable()
- combined.metadata = {showspots = 1, click1 = playermod}
- mod.metadata = {showspots = 1, click1 = playermod}
- playermod.metadata = {}
- Skada:RegisterForCL(AuraApplied, 'SPELL_AURA_REFRESH', {src_is_interesting_nopets = true})
- Skada:RegisterForCL(AuraApplied, 'SPELL_AURA_APPLIED', {src_is_interesting_nopets = true})
- Skada:RegisterForCL(AuraRemoved, 'SPELL_AURA_REMOVED', {src_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellDamage, 'DAMAGE_SHIELD', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellDamage, 'SPELL_DAMAGE', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellDamage, 'SPELL_PERIODIC_DAMAGE', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellDamage, 'SPELL_BUILDING_DAMAGE', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellDamage, 'RANGE_DAMAGE', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SwingDamage, 'SWING_DAMAGE', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellMissed, 'SPELL_MISSED', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellMissed, 'SPELL_PERIODIC_MISSED', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellMissed, 'SPELL_BUILDING_MISSED', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SpellMissed, 'RANGE_MISSED', {dst_is_interesting_nopets = true})
- Skada:RegisterForCL(SwingMissed, 'SWING_MISSED', {dst_is_interesting_nopets = true})
- Skada:AddMode(self)
- Skada:AddMode(combined)
- end
- function mod:OnDisable()
- Skada:RemoveMode(self)
- Skada:RemoveMode(combined)
- end
- function mod:AddToTooltip(set, tooltip)
- end
- function mod:GetSetSummary(set)
- return Skada:FormatNumber(set.absorbs)
- end
- function combined:GetSetSummary(set)
- return Skada:FormatNumber(set.absorbs + set.healing)
- end
- -- Called by Skada when a new player is added to a set.
- function mod:AddPlayerAttributes(player)
- if not player.absorbs then
- player.absorbs = {}
- player.totalabsorbs = 0
- end
- end
- -- Called by Skada when a new set is created.
- -- Conveniently this is when a new fight starts, so we can clear our shield cache.
- function mod:AddSetAttributes(set)
- if not set.absorbs then
- set.absorbs = 0
- end
- shields = {}
- end
Advertisement
Add Comment
Please, Sign In to add comment