Last active
December 23, 2015 12:29
-
-
Save GabeStah/6636046 to your computer and use it in GitHub Desktop.
WeakAuras: Amount per Interval Skeleton - Custom Trigger Function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function(...) -- CUSTOM TRIGGER | |
-- BEGIN VARIABLES | |
local ID = 'AmountPerIntervalTracker' | |
local AMOUNT_TYPE = 'healing' | |
local DESTINATION_FLAG = COMBATLOG_OBJECT_TYPE_PLAYER | |
local EVENT_TYPE = 'SPELL_HEAL' | |
local INTERVAL_TIME = 4 | |
local SOURCE = 'player' | |
local SPELL_NAME = 'Spinning Crane Kick' | |
-- END VARIABLES | |
-- BEGIN BASE FUNCTIONS | |
local GetValue = function(...) | |
if not WeakAuras.CustomValues then WeakAuras.CustomValues = {} end | |
if not ... then return end | |
local count, data = #{...} | |
if count and (count > 1) then | |
for i,v in pairs({...}) do | |
if i==1 then WeakAuras.CustomValues[v] = WeakAuras.CustomValues[v] or {} data = WeakAuras.CustomValues[v] | |
else if i ~= count then if not data[v] then data[v] = {} else data = data[v] end else data = data[v] end end | |
end | |
else data = WeakAuras.CustomValues[select(1, ...)] end | |
return data | |
end | |
local SetValue = function(value, ...) | |
if not WeakAuras.CustomValues then WeakAuras.CustomValues = {} end | |
if not ... then return end | |
local count, data = #{...} | |
for i,v in pairs({...}) do | |
if i==1 then if count and count == 1 then WeakAuras.CustomValues[v] = value else | |
WeakAuras.CustomValues[v] = WeakAuras.CustomValues[v] or {} | |
data = WeakAuras.CustomValues[v] end | |
else if i ~= count then if not data[v] then data[v] = {} end data = data[v] else data[v] = value end end | |
end | |
end | |
local GetDestination = function(returnType, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' then return end | |
local GetUnitId = function(unit) | |
local id | |
if not unit then return end | |
if type(unit) == 'string' then -- name or unitId | |
if UnitInRaid(unit) then return 'raid'..UnitInRaid(unit) end -- Player in raid | |
for i=1,10 do id = 'boss'..i if id == unit then return unit end if UnitExists(id) and UnitName(id) == unit then return id end end | |
if UnitExists('player') and UnitName('player') == unit then return 'player' end | |
if UnitExists('pet') and UnitName('pet') == unit then return 'pet' end | |
if UnitExists('target') and UnitName('target') == unit then return 'target' end | |
if UnitExists('focus') and UnitName('focus') == unit then return 'focus' end | |
if UnitExists('mouseover') and UnitName('mouseover') == unit then return 'mouseover' end | |
end | |
end | |
returnType = returnType or 'name' | |
local GUID = select(9, ...) | |
if not GUID then return end | |
if returnType == 'guid' then return GUID end | |
local name = select(10, ...) | |
local unitId = GetUnitId(name) | |
local maskedTypeBit = tonumber(GUID:sub(5,5), 16) % 8 | |
local id = tonumber(GUID:sub(6,10), 16) | |
-- 0 player, 1 object, 3 npc, 4 pet, 5 vehicle | |
if maskedTypeBit == 0 then -- Player | |
if returnType == 'name' then return (name ~= 'Unknown') and name | |
elseif returnType == 'unit-id' or returnType == 'unitId' then return unitId end | |
else | |
if returnType == 'name' then return (name ~= 'Unknown') and name | |
elseif returnType == 'unit-id' or returnType == 'unitId' then return unitId | |
elseif returnType == 'id' then return id end | |
end | |
end | |
local HasDestinationFlag = function(value, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' or not value then return end | |
local flags = select(11, ...) | |
if not flags then return end | |
return (bit.band(flags, value) ~= 0) | |
end | |
local IsEventType = function(value, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' or not value or type(value) ~= 'string' then return end | |
local event = select(3, ...) | |
if not event then return end | |
if event == value then return true end | |
end | |
local IsSource = function(value, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' or not value then return end | |
local comparison | |
local GUID = select(5, ...) | |
if type(value) == 'string' then comparison = select(6, ...) | |
if value == GUID then return true end | |
for i,v in pairs({'player', 'target', 'focus', 'raid'}) do | |
if string.find(value, v) then value = UnitExists(value) and UnitName(value) end | |
end | |
elseif type(value) == 'number' then | |
if GUID then comparison = tonumber(GUID:sub(6,10), 16) end | |
else return end | |
if not comparison then return end | |
return (value == comparison) | |
end | |
local IsSpell = function(value, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' or not value then return end | |
local comparison | |
if type(value) == 'string' then comparison = select(14, ...) | |
elseif type(value) == 'number' then local n = select(13, ...) comparison = tonumber(n) | |
else return end | |
if not comparison then return end | |
return (value == comparison) | |
end | |
local GetAmount = function(returnType, ...) | |
if not select(1, ...) or select(1, ...) ~= 'COMBAT_LOG_EVENT_UNFILTERED' then return end | |
returnType = returnType or 'amount' | |
local amount, overkill, absorbed = select(16, ...) | |
if returnType == 'amount' or returnType == 'damage' then | |
return amount | |
elseif returnType == 'overhealing' or returnType == 'overkill' then | |
return overkill | |
elseif returnType == 'healing' or returnType == 'effective-healing' then | |
if amount then return (amount - overkill) end | |
end | |
end | |
-- END BASE FUNCTIONS | |
-- BEGIN CUSTOM FUNCTIONS | |
local AddEntry = function(data, time, destination, value) | |
-- Increment value | |
data.totalValue = (data.totalValue and data.totalValue or 0) + value | |
-- Increment destination | |
data.destinations[destination] = (data.destinations[destination] and data.destinations[destination] or 0) + 1 | |
-- Add entry | |
table.insert(data.events, {time = time, destination = destination, value = value}) | |
end | |
local GetDestinationCount = function(data) | |
if not data or not data.destinations then return end | |
local count | |
for i,v in pairs(data.destinations) do | |
count = (count and count or 0) + 1 | |
end | |
return count | |
end | |
local GetExpiredCount = function(events, expiration) | |
local count = 0 | |
for i,v in ipairs(events) do | |
if (v.time < expiration) then | |
count = count + 1 | |
else | |
break | |
end | |
end | |
return count | |
end | |
local RemoveEntries = function(data, count) | |
if not count or count == 0 then return end | |
local event | |
for i=1,count do | |
event = data.events[1] -- Always first entry since automatically time-sorted | |
-- Decrement destination record | |
if data.destinations[event.destination] then | |
data.destinations[event.destination] = data.destinations[event.destination] - 1 | |
else | |
data.destinations[event.destination] = 0 | |
end | |
-- Remove destination record if empty | |
if data.destinations[event.destination] == 0 then data.destinations[event.destination] = nil end | |
-- Decrement totalValue | |
data.totalValue = data.totalValue - event.value | |
-- Remove entry | |
table.remove(data.events, 1) -- Remove first entry | |
end | |
end | |
-- END CUSTOM FUNCTIONS | |
-- Cleanup | |
local currentTime = time() | |
local expiration = currentTime - INTERVAL_TIME | |
local data = GetValue(ID) -- Retrieve stored data | |
if not data then data = {totalValue = 0, destinations = {}, events = {}} end | |
-- Cleanup old entries | |
RemoveEntries(data, GetExpiredCount(data.events, expiration)) | |
-- Add potential entry | |
if IsSource(SOURCE, ...) and IsSpell(SPELL_NAME, ...) and IsEventType(EVENT_TYPE, ...) and HasDestinationFlag(DESTINATION_FLAG, ...) then | |
-- Add entry | |
AddEntry(data, currentTime, GetDestination('name', ...), GetAmount(AMOUNT_TYPE, ...)) | |
end | |
-- Reassign global | |
SetValue(data, ID) | |
-- Return true to force display | |
return true | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment