Quicklog/Quicklog.lua

419 lines
13 KiB
Lua

local name, addon = ...
addon.f = CreateFrame("Frame")
local bit = bit
local segStarted = false
local COMBATLOG_OBJECT_AFFILIATION_OUTSIDER = COMBATLOG_OBJECT_AFFILIATION_OUTSIDER
local function purgeDB(tbl)
for k, v in pairs(tbl) do
if(type(v) == 'table') then
tbl[k] = purgeDB(v)
elseif(type(v) == 'function') then
tbl[k] = nil
end
end
return tbl
end
local dbdefaults = {
['maxSegments'] = 10,
['maxTooltipSpells'] = 6,
['maxTooltipUnits'] = 5,
['currentSegment'] = 0,
['dbversion'] = 1
}
local dbfunc = {}
function dbfunc:Get(key, id)
if(key) then
if(key == 'segment' and type(id) == 'number' and id > 0 and self['segments'][id]) then
return self['segments'][id]
elseif(key == 'segments') then
return self['segments']
else
if(type(self['settings'][key])~='nil') then
return self['settings'][key]
else
if(type(dbdefaults[key])~='nil') then
return dbdefaults[key]
end
end
end
end
end
function dbfunc:Set(key, value, id)
if(key) then
if(key == 'segments' and type(value) == 'table') then
self['segments'] = value
elseif(key == 'segment' and type(id) == 'number' and id > 0 and self['segments'][id] and type(value) == 'table') then
self['segments'][id] = value
else
if(value == dbdefaults[key]) then
self['settings'][key] = nil
else
self['settings'][key] = value
end
end
end
end
function addon:PLAYER_LOGOUT(event)
QuicklogDB['GuidDB'] = addon:PurgeGuidInfo()
QuicklogDB = purgeDB(QuicklogDB)
-- QuicklogDB['GuidDB'] = nil
end
local function init(seg, data)
print('initSeg', data and #data)
if(data) then
-- print(unpack(data))
end
seg['startevent'] = data
return seg
end
local computeAllowed = {
'DAMAGE','HEAL','ABSORBED',
}
local function canCompute(typ)
for i = 1, #computeAllowed do
if(computeAllowed[i] == typ) then
return true
end
end
end
local function NoSource(data)
if(data[3] == "ENVIRONMENTAL_DAMAGE" or data[3] == "ENVIRONMENTAL_HEAL") then
-- print('aoe',data[3])
local store = addon:GetStore(addon:GetSegment())
return store:GetSource(data[9], data, 9, true)
end
end
local function computeEvent(data, prefix, suffix)
-- local prefix, suffix = unpack(addon:SplitCLEvent(data[3]))
if(canCompute(suffix)) then
local res = addon:GetSegment()
local store = addon:GetStore(res)
local data_src = data:GetSource()
local gis = addon:GetGuidInfo2(data_src)
local source
if(data_src and gis:IsPet()) then
source = store:GetSource(data_src['ownerGuid'], data)
else
source = store:GetSource(data[5], data)
end
if(not source) then
source = NoSource(data)
if(not source) then
source = store:GetSourceEmpty(data)
end
end
local dest = source:GetDestination(data[9])
if(suffix == 'DAMAGE') then
local spellId, spellName, spellSchool, environmentalType
local amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand
if(prefix == 'ENVIRONMENTAL') then
environmentalType, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand = select(13, unpack(data))
spellId, spellName, spellSchool = 'ENVIRONMENTAL', format('ENVIRONMENTAL (%s)', environmentalType), environmentalType
elseif(prefix == 'SWING') then
amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand = select(13, unpack(data))
spellId, spellName, spellSchool = 'SWING', ACTION_SWING, school
else
spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand = select(13, unpack(data))
end
if(overkill > -1) then
amount = amount - overkill
end
if(resisted or blocked) then
local destSource = store:GetSource(dest[1], data)
if(resisted and resisted > 0) then
destSource:addTotal('totalAbsorbed', resisted)
end
if(blocked and blocked > 0) then
destSource:addTotal('totalAbsorbed', blocked)
end
end
if(amount > 0) then
source:addTotal('total', amount)
if(spellId) then
dest:addSpell(spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand)
if(resisted or blocked) then
local destSource = store:GetSource(dest[1], data)
local destSourceDest = destSource:GetDestination(dest[1])
if(resisted and resisted > 0) then
destSourceDest:addAbsorbSpell('RESISTED', 'RESISTED', 1, resisted)
end
if(blocked and blocked > 0) then
destSourceDest:addAbsorbSpell('BLOCKED', 'BLOCKED', 1, blocked)
end
end
end
else
-- print("no amount")
-- print(unpack(data))
end
elseif(suffix == 'ABSORBED') then
local spellId, spellName, spellSchool, extraGUID, extraName, extraFlags, extraRaidFlags, extraSpellID, extraSpellName, extraSchool, amount
if(#data == 24) then
spellId, spellName, spellSchool, extraGUID, extraName, extraFlags, extraRaidFlags, extraSpellID, extraSpellName, extraSchool, amount = select(13, unpack(data))
else
extraGUID, extraName, extraFlags, extraRaidFlags, extraSpellID, extraSpellName, extraSchool, amount = select(13, unpack(data))
spellId, spellName, spellSchool = 'SWING', ACTION_SWING, nil
end
if(amount > 0 and extraGUID) then
if(type(data[13]) ~= 'number') then
local extraSource = store:GetSource(extraGUID, data, 13, true)
local dest2 = extraSource:GetDestination(data[9])
extraSource:addTotal('totalAbsorbed', amount)
-- dest2:addTotal('totalAbsorbed', amount)
if(extraSpellID) then
dest2:addAbsorbSpell(extraSpellID, extraSpellName, extraSchool, amount)
end
else
-- print("es", data[13], data[14], data[15])
end
end
elseif(suffix == 'HEAL') then
local spellId, spellName, spellSchool, amount, overhealing, absorbed, critical = select(13, unpack(data))
if(overhealing > 0) then
amount = amount - overhealing
source:addTotal('totalOverheal', overhealing)
end
if(absorbed > 0) then
amount = amount - absorbed
end
if(amount > 0) then
source:addTotal('totalHeal', amount)
if(spellId) then
dest:addHealSpell(spellId, spellName, spellSchool, amount, overhealing, absorbed, critical)
-- dest:addTotal('totalHeal', amount)
else
print("no sid")
end
end
end
-- store:Store()
else
print('skip', data[3], suffix)
end
data = nil
end
local function startSegment(data)
segStarted = true
addon:NewSegment(init, data)
addon:UpdateWindows()
end
local function stopSegment(...)
if(segStarted) then
addon:UpdateWindows()
segStarted = false
addon:PurgeGuidInfo()
addon:GetSegment():stop()
else
print("stop not", ...)
end
end
local throttleUpdate,trottleDelay = time(), 0.4
function addon:summon(reg, data, prefix, suffix)
self:CreateDataObject(data, prefix, suffix)
local summon = addon:GetGuidInfo2(data:GetDestination())
if(not summon:HasOwner()) then
-- summon:scanTooltip()
local owner = addon:GetGuidInfo2(data:GetSource())
summon:SetOwner(owner)
end
-- summon['isPet'] = true
-- summon['ownerFlags'] = data[7]
-- summon['ownerName'] = data[6]
-- summon['ownerGuid'] = data[5]
-- addon:IsInParty(data[11], data[10], data[9])
end
local function prepData(data, offset)
local offset = offset or 5
if(data[offset + 1]) then
local gis = addon:GetGuidInfo2({data[offset], data[offset + 1], data[offset + 2]})
if(segStarted and gis['isBoss']) then
QuicklogDB['segments'][#QuicklogDB['segments']]['hasBoss'] = true
QuicklogDB['segments'][#QuicklogDB['segments']]['BossNames'][data[offset]] = data[offset + 1]
end
end
return data
end
function addon:dmg(reg, data, prefix, suffix)
-- print(data, prefix, suffix)
--[[ [1] = event,
[2] = time,
[3] = type,
[4] = hideCaster,
[5] = sourceGUID,
[6] = sourceName,
[7] = sourceFlags,
[8] = sourceRaidFlags,
[9] = destGUID,
[10] = destName,
[11] = destFlags,
[12] = destRaidFlags,
]]
self:CreateDataObject(data, prefix, suffix)
local data_src = data:GetSource()
local data_dest = data:GetDestination()
local data_extrasrc = data:GetExtraSource()
if(not segStarted and not data_src and not data_extrasrc) then
-- print('environmental/aoe?', data[3], data[10])
return
end
data = prepData(data, 5)
data = prepData(data, 9)
if(not segStarted) then
local gis = addon:GetGuidInfo2(data_extrasrc and data_extrasrc or data_src)
if(gis and not gis['died'] and not (suffix == 'HEAL') and not(prefix == 'ENVIRONMENTAL')) then
local gid = addon:GetGuidInfo2(data_dest)
if(gis:IsParty()) then
if(gis[1] and gid[1] and gis[1] ~= gid[1]) then
startSegment(data)
end
end
end
end
if(segStarted) then
computeEvent(data, prefix, suffix)
if(time()>throttleUpdate) then
throttleUpdate = data[2] + trottleDelay
addon:UpdateWindows()
end
end
end
function addon:ENCOUNTER_END(event, encounterID, encounterName, difficultyID, groupSize, success)
-- print(event, encounterID, encounterName, difficultyID, groupSize)
addon:UpdateWindows()
stopSegment(event, encounterID, encounterName, difficultyID, groupSize, success)
self:UnregisterEvent(event)
self:RegisterEvent('ENCOUNTER_START')
end
function addon:ENCOUNTER_START(event, encounterID, encounterName, difficultyID, groupSize)
-- print(event, encounterID, encounterName, difficultyID, groupSize)
if(not segStarted) then
startSegment()
end
local seg = addon:GetSegment()
seg['isEncounter'] = true
seg['encounter'] = {encounterID, encounterName, difficultyID, groupSize}
self:RegisterEvent("ENCOUNTER_END")
self:UnregisterEvent(event)
end
function addon:SCENARIO_COMPLETED(event, questID, xp, money)
-- print("scenario end", event, questID, xp, money)
stopSegment(event, questID, xp, money)
end
function addon:UNIT_EXITED_VEHICLE(event, unit)
-- print("uev", event, unit)
if(unit=='player') then
stopSegment(event, unit)
end
end
function addon:UNIT_NAME_UPDATE(event, unit)
local gi = addon:GetGuidInfo2(UnitGUID(unit))
if(gi) then
gi:SetName(UnitName(unit))
end
end
function addon:PLAYER_ENTERING_WORLD(event, isInitialLogin, isReloadingUi)
-- print("PEW")
if(not isInitialLogin and not isReloadingUi) then
stopSegment(event, isInitialLogin, isReloadingUi)
end
end
function addon:cmbStatus(reg, event)
-- print(reg, event)
if(event=='PLAYER_REGEN_ENABLED') then
if(segStarted and not addon:GetSegment()['isEncounter']) then
if(not UnitIsDeadOrGhost('PLAYER')) then
stopSegment(event)
end
end
addon['LibGUID']:PruneGUIDCache(600)
elseif(event=='PLAYER_REGEN_DISABLED') then
if(not segStarted) then
startSegment()
end
end
end
function addon:died(event, data, prefix, suffix)
-- print(unpack(data))
self:CreateDataObject(data, prefix, suffix)
local gi = addon:GetGuidInfo2(data:GetDestination())
gi['died'] = gi['died'] or {}
gi['died'][#gi['died'] + 1] = data
gi['dead'] = true
end
function addon:resurrect(event, data)
-- local gis = addon:GetGuidInfo(data[5], data[7], data[6])
-- print('res', gis['name'])
self:CreateDataObject(data, prefix, suffix)
local gi = addon:GetGuidInfo2(data:GetDestination())
-- print('res dest', gi['name'])
gi['resurrect'] = gi['resurrect'] or {}
gi['resurrect'][#gi['resurrect'] + 1] = data
gi['dead'] = nil
end
addon['f']:SetScript("OnEvent", function(self, event, arg1, ...)
if(event == "ADDON_LOADED" and arg1 == name) then
QuicklogDB = QuicklogDB or {
['segments'] = {},
['settings'] = {},
}
for k,v in pairs(dbfunc) do
QuicklogDB[k] = v
end
if(QuicklogDB['GuidDB']) then
addon:SetGuidInfoDB(QuicklogDB['GuidDB'])
end
self:UnregisterEvent(event)
local seg = addon:GetSegment()
-- seg['end'] = time()
if(not seg['end']) then
print('seg is running')
segStarted = true
else
print('no seg running')
addon:PurgeGuidInfo()
end
LibStub("LibCombatLog"):Embed(addon)
LibStub("LibCombatLog_data"):Embed(addon)
addon:RegisterCLEvent({'UNIT_DIED', 'UNIT_DESTROYED', 'UNIT_DISSIPATES'}, 'died')
addon:RegisterCLSuffix({'DAMAGE','HEAL','ABSORBED'}, 'dmg')
addon:RegisterCLSuffix({'SUMMON', 'CREATE'}, 'summon')
addon:RegisterCLSuffix({'RESURRECT'}, 'resurrect')
addon:RegisterCLStatus('cmbStatus')
addon:UpdateWindows()
elseif(type(addon[event]) == 'function') then
addon[event](self, event, arg1, ...)
else
print('else',event, arg1, ...)
end
end)
addon['f']:RegisterEvent("ADDON_LOADED")
addon['f']:RegisterEvent("PLAYER_LOGOUT")
addon['f']:RegisterEvent("RAID_ROSTER_UPDATE")
addon['f']:RegisterEvent("GROUP_ROSTER_UPDATE")
addon['f']:RegisterEvent("UNIT_TARGET")
addon['f']:RegisterEvent("ENCOUNTER_START")
addon['f']:RegisterEvent("UNIT_NAME_UPDATE")
--[[addon['f']:RegisterEvent("PLAYER_GAINS_VEHICLE_DATA") -- ?
addon['f']:RegisterEvent("PLAYER_LOSES_VEHICLE_DATA") -- ?
addon['f']:RegisterEvent("SCENARIO_COMPLETED") -- ?
addon['f']:RegisterEvent("PLAYER_ENTERING_WORLD") -- ?
addon['f']:RegisterEvent("WORLD_QUEST_COMPLETED_BY_SPELL") -- ?
addon['f']:RegisterEvent("QUEST_COMPLETE") -- ?
addon['f']:RegisterEvent("PLAYER_CONTROL_GAINED") -- ?
addon['f']:RegisterEvent("TASK_PROGRESS_UPDATE") -- ?
addon['f']:RegisterEvent("INSTANCE_ENCOUNTER_OBJECTIVE_COMPLETE") -- ?
addon['f']:RegisterEvent("SCENARIO_UPDATE") -- ?
]]
addon['f']:RegisterEvent("UNIT_EXITED_VEHICLE") -- Marasius