Files
Nanami-DPS/DataStore.lua
rucky 5c3f2243c4 更新发送到功能
更新仇恨计算方式 还在开发
更新其他细节
2026-03-23 10:26:31 +08:00

250 lines
7.3 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
end
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