257 lines
7.5 KiB
Lua
257 lines
7.5 KiB
Lua
local NanamiDPS = NanamiDPS
|
|
|
|
local DataStore = {}
|
|
NanamiDPS.DataStore = DataStore
|
|
|
|
local function CreateEmptySegmentData()
|
|
return {
|
|
damage = {},
|
|
healing = {},
|
|
damageTaken = {},
|
|
deaths = {},
|
|
dispels = {},
|
|
interrupts = {},
|
|
threat = {},
|
|
activity = {},
|
|
classes = {},
|
|
}
|
|
end
|
|
|
|
local function CreateSegment(name)
|
|
return {
|
|
name = name or "Unknown",
|
|
startTime = GetTime(),
|
|
endTime = 0,
|
|
duration = 0,
|
|
data = CreateEmptySegmentData(),
|
|
}
|
|
end
|
|
|
|
DataStore.total = CreateSegment("Total")
|
|
DataStore.current = CreateSegment("Current")
|
|
DataStore.history = {}
|
|
|
|
DataStore.inCombat = false
|
|
|
|
function DataStore:GetSegment(index)
|
|
if index == 0 then
|
|
return self.total
|
|
elseif index == 1 then
|
|
return self.current
|
|
elseif index and self.history[index - 1] then
|
|
return self.history[index - 1]
|
|
end
|
|
return self.current
|
|
end
|
|
|
|
function DataStore:GetSegmentList()
|
|
local list = {}
|
|
table.insert(list, { index = 0, name = NanamiDPS.L["Total"] })
|
|
table.insert(list, { index = 1, name = NanamiDPS.L["Current"] })
|
|
for i, seg in ipairs(self.history) do
|
|
table.insert(list, { index = i + 1, name = seg.name })
|
|
end
|
|
return list
|
|
end
|
|
|
|
function DataStore:StartCombat()
|
|
if self.inCombat then return end
|
|
self.inCombat = true
|
|
|
|
self.current = CreateSegment("Current")
|
|
self.current.startTime = GetTime()
|
|
|
|
NanamiDPS:FireCallback("COMBAT_START")
|
|
end
|
|
|
|
function DataStore:StopCombat()
|
|
if not self.inCombat then return end
|
|
self.inCombat = false
|
|
|
|
self.current.endTime = GetTime()
|
|
self.current.duration = self.current.endTime - self.current.startTime
|
|
|
|
local hasData = false
|
|
for _ in pairs(self.current.data.damage) do hasData = true; break end
|
|
if not hasData then
|
|
for _ in pairs(self.current.data.healing) do hasData = true; break end
|
|
end
|
|
|
|
if hasData and self.current.duration >= 2 then
|
|
local segName = date("%H:%M:%S")
|
|
self.current.name = segName
|
|
|
|
table.insert(self.history, 1, self.current)
|
|
|
|
local maxSegs = (NanamiDPS.config and NanamiDPS.config.maxSegments) or 10
|
|
while table.getn(self.history) > maxSegs do
|
|
table.remove(self.history)
|
|
end
|
|
end
|
|
|
|
self.current = CreateSegment("Current")
|
|
|
|
NanamiDPS:FireCallback("COMBAT_STOP")
|
|
NanamiDPS:FireCallback("refresh")
|
|
end
|
|
|
|
function DataStore:AddDamage(source, spell, target, amount, school)
|
|
if not source or not amount then return end
|
|
amount = tonumber(amount)
|
|
if not amount or amount <= 0 then return end
|
|
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.damage
|
|
if not d[source] then
|
|
d[source] = { _sum = 0, _ctime = 1, _tick = 0, spells = {} }
|
|
end
|
|
d[source]._sum = d[source]._sum + amount
|
|
d[source].spells[spell] = (d[source].spells[spell] or 0) + amount
|
|
self:UpdateCombatTime(d[source])
|
|
end
|
|
end
|
|
|
|
function DataStore:AddDamageTaken(target, spell, source, amount, school)
|
|
if not target or not amount then return end
|
|
amount = tonumber(amount)
|
|
if not amount or amount <= 0 then return end
|
|
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.damageTaken
|
|
if not d[target] then
|
|
d[target] = { _sum = 0, _ctime = 1, _tick = 0, spells = {} }
|
|
end
|
|
d[target]._sum = d[target]._sum + amount
|
|
d[target].spells[spell] = (d[target].spells[spell] or 0) + amount
|
|
self:UpdateCombatTime(d[target])
|
|
end
|
|
end
|
|
|
|
function DataStore:AddHealing(source, spell, target, amount, effective)
|
|
if not source or not amount then return end
|
|
amount = tonumber(amount)
|
|
effective = tonumber(effective) or amount
|
|
if not amount or amount <= 0 then return end
|
|
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.healing
|
|
if not d[source] then
|
|
d[source] = { _sum = 0, _esum = 0, _ctime = 1, _tick = 0, spells = {}, effective = {} }
|
|
end
|
|
d[source]._sum = d[source]._sum + amount
|
|
d[source]._esum = d[source]._esum + effective
|
|
d[source].spells[spell] = (d[source].spells[spell] or 0) + amount
|
|
d[source].effective[spell] = (d[source].effective[spell] or 0) + effective
|
|
self:UpdateCombatTime(d[source])
|
|
end
|
|
end
|
|
|
|
function DataStore:AddDeath(playerName, deathLog)
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.deaths
|
|
if not d[playerName] then
|
|
d[playerName] = { _sum = 0, events = {} }
|
|
end
|
|
d[playerName]._sum = d[playerName]._sum + 1
|
|
table.insert(d[playerName].events, deathLog)
|
|
end
|
|
end
|
|
|
|
function DataStore:AddDispel(source, spell, target, aura)
|
|
if not source then return end
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.dispels
|
|
if not d[source] then
|
|
d[source] = { _sum = 0, spells = {} }
|
|
end
|
|
d[source]._sum = d[source]._sum + 1
|
|
d[source].spells[spell] = (d[source].spells[spell] or 0) + 1
|
|
end
|
|
end
|
|
|
|
function DataStore:AddInterrupt(source, spell, target, interrupted)
|
|
if not source then return end
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.interrupts
|
|
if not d[source] then
|
|
d[source] = { _sum = 0, spells = {} }
|
|
end
|
|
d[source]._sum = d[source]._sum + 1
|
|
d[source].spells[spell] = (d[source].spells[spell] or 0) + 1
|
|
end
|
|
end
|
|
|
|
function DataStore:AddThreat(source, amount)
|
|
if not source or not amount then return end
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.threat
|
|
if not d[source] then
|
|
d[source] = { _sum = 0 }
|
|
end
|
|
d[source]._sum = d[source]._sum + amount
|
|
if d[source]._sum < 0 then d[source]._sum = 0 end
|
|
end
|
|
end
|
|
|
|
function DataStore:GetPlayerThreat(source)
|
|
if not source then return 0 end
|
|
local d = self.current.data.threat[source]
|
|
return d and d._sum or 0
|
|
end
|
|
|
|
function DataStore:UpdateActivity(source, timestamp)
|
|
if not source then return end
|
|
local segs = { self.current, self.total }
|
|
for _, seg in ipairs(segs) do
|
|
local d = seg.data.activity
|
|
if not d[source] then
|
|
d[source] = { _firstAction = timestamp, _lastAction = timestamp, _activeTime = 0, _tick = 0 }
|
|
end
|
|
local entry = d[source]
|
|
if entry._tick > 0 and (timestamp - entry._tick) < 5 then
|
|
entry._activeTime = entry._activeTime + (timestamp - entry._tick)
|
|
end
|
|
entry._tick = timestamp
|
|
entry._lastAction = timestamp
|
|
end
|
|
end
|
|
|
|
function DataStore:SetClass(name, class)
|
|
self.current.data.classes[name] = class
|
|
self.total.data.classes[name] = class
|
|
end
|
|
|
|
function DataStore:GetClass(name)
|
|
return self.current.data.classes[name] or self.total.data.classes[name]
|
|
end
|
|
|
|
function DataStore:UpdateCombatTime(entry)
|
|
if not entry._tick then entry._tick = 0 end
|
|
local now = GetTime()
|
|
if entry._tick == 0 then
|
|
entry._tick = now
|
|
return
|
|
end
|
|
local diff = now - entry._tick
|
|
if diff >= 5 then
|
|
entry._ctime = entry._ctime + 5
|
|
else
|
|
entry._ctime = entry._ctime + diff
|
|
end
|
|
entry._tick = now
|
|
end
|
|
|
|
function DataStore:ResetAll()
|
|
self.total = CreateSegment("Total")
|
|
self.current = CreateSegment("Current")
|
|
self.history = {}
|
|
NanamiDPS:FireCallback("refresh")
|
|
end
|