Skip to content

Instantly share code, notes, and snippets.

@GabeStah
Last active December 23, 2015 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GabeStah/6636046 to your computer and use it in GitHub Desktop.
Save GabeStah/6636046 to your computer and use it in GitHub Desktop.
WeakAuras: Amount per Interval Skeleton - Custom Trigger Function
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