mirror of
https://github.com/akzkak/CombatLedger.git
synced 2026-11-10 22:57:33 +00:00
184 lines
6.4 KiB
Lua
184 lines
6.4 KiB
Lua
--[[
|
|
History - save/trim/delete for CombatLedgerDB.encountersByChar[key].
|
|
Most-recent-first, capped at Options' "Saved fights" (trim-oldest) - PER
|
|
CHARACTER, since CombatLedgerDB itself is account-wide (plain
|
|
SavedVariables, not SavedVariablesPerCharacter - see the .toc) and a
|
|
flat shared list meant every alt on the account saw every other alt's
|
|
saved encounters mixed into the same history.
|
|
|
|
Reads/writes the CombatLedgerDB global directly rather than through
|
|
CL.db - SavedVariables are restored from disk after Core.lua's own
|
|
init line runs, replacing the table wholesale (see Core.lua's
|
|
EnsureSettingsTable for the same issue with .settings), so a cached
|
|
table reference risks writing into an orphaned copy that never
|
|
actually gets saved.
|
|
|
|
encounter.series (Aggregator's bucketed damage/healing/taken-per-2s
|
|
timeline) is real content, not scratch data like mobTally/mobHealth -
|
|
it's kept through the save so UI_EncounterReport can graph a saved
|
|
encounter, not just the live one.
|
|
]]
|
|
|
|
local CL = CombatLedger
|
|
|
|
local function CharKey()
|
|
local name = UnitName("player") or "Unknown"
|
|
local realm = (GetRealmName and GetRealmName()) or ""
|
|
return name .. "-" .. realm
|
|
end
|
|
|
|
-- Returns this character's history key, creating its list if needed.
|
|
-- A legacy account-wide list (CombatLedgerDB.encounters) is moved into
|
|
-- the first character that logs in, then removed so no other character
|
|
-- imports it again.
|
|
local function EnsureEncountersTable()
|
|
if not CombatLedgerDB.encountersByChar then
|
|
CombatLedgerDB.encountersByChar = {}
|
|
end
|
|
local key = CharKey()
|
|
if not CombatLedgerDB.encountersByChar[key] then
|
|
CombatLedgerDB.encountersByChar[key] = {}
|
|
end
|
|
if CombatLedgerDB.encounters and table.getn(CombatLedgerDB.encounters) > 0 then
|
|
local i
|
|
for i = 1, table.getn(CombatLedgerDB.encounters) do
|
|
table.insert(CombatLedgerDB.encountersByChar[key], CombatLedgerDB.encounters[i])
|
|
end
|
|
CombatLedgerDB.encounters = nil
|
|
end
|
|
return key
|
|
end
|
|
|
|
-- Named after the toughest mob in the pull (highest UnitHealthMax
|
|
-- sampled while fighting it - see Aggregator's mobHealth) rather than
|
|
-- the zone name, since every boss pull inside an instance would
|
|
-- otherwise share the same zone name with nothing to tell separate
|
|
-- pulls apart in the segment dropdown/history list. Falls back to
|
|
-- whichever mob took the most tracked-side damage if health sampling
|
|
-- came up empty, then to the zone name.
|
|
local function ComputeLabel(encounter)
|
|
-- A boss fight is named after its boss or BigWigs encounter.
|
|
if encounter.bossName then return encounter.bossName end
|
|
local bestGuid, bestHealth = nil, 0
|
|
local hpGuid, hp
|
|
for hpGuid, hp in pairs(encounter.mobHealth or {}) do
|
|
if hp > bestHealth then
|
|
bestGuid, bestHealth = hpGuid, hp
|
|
end
|
|
end
|
|
|
|
if not bestGuid then
|
|
local bestAmount = 0
|
|
local dmgGuid, amount
|
|
for dmgGuid, amount in pairs(encounter.mobTally or {}) do
|
|
if amount > bestAmount then
|
|
bestGuid, bestAmount = dmgGuid, amount
|
|
end
|
|
end
|
|
end
|
|
|
|
if bestGuid then
|
|
local info = CL.GuidCache and CL.GuidCache.Resolve(bestGuid)
|
|
if info and info.name then return info.name end
|
|
end
|
|
|
|
if IsInInstance and IsInInstance() then
|
|
return (GetRealZoneText and GetRealZoneText()) or encounter.zone or "Instance"
|
|
end
|
|
return encounter.zone or "Unknown"
|
|
end
|
|
|
|
-- Drops the oldest fights beyond Options' "Saved fights" - also called
|
|
-- straight from Options when that number is lowered.
|
|
local function TrimHistory()
|
|
local key = EnsureEncountersTable()
|
|
local list = CombatLedgerDB.encountersByChar[key]
|
|
local cap = CL.GetSetting("maxEncounters") or CL.MAX_SAVED_FIGHTS
|
|
while table.getn(list) > cap do
|
|
table.remove(list, table.getn(list))
|
|
end
|
|
end
|
|
|
|
local function SaveEncounter(encounter)
|
|
if not encounter then return end
|
|
local key = EnsureEncountersTable()
|
|
local list = CombatLedgerDB.encountersByChar[key]
|
|
|
|
if not encounter.label then
|
|
encounter.label = ComputeLabel(encounter)
|
|
end
|
|
encounter.mobTally = nil -- label-only scratch data, not worth persisting
|
|
encounter.mobHealth = nil -- label-only scratch data, not worth persisting
|
|
-- Merge same-named mobs' per-target breakdowns (a trash pull can hit
|
|
-- dozens of GUIDs) - see Aggregator.lua's CompactTargets.
|
|
CL.Aggregator.CompactTargets(encounter)
|
|
|
|
table.insert(list, 1, encounter)
|
|
TrimHistory()
|
|
end
|
|
|
|
-- Fights saved before target compaction existed are still GUID-keyed -
|
|
-- compact them once per session, the first time History is read.
|
|
local compactedOldSaves = false
|
|
|
|
local function GetHistory()
|
|
local key = EnsureEncountersTable()
|
|
local list = CombatLedgerDB.encountersByChar[key]
|
|
if not compactedOldSaves then
|
|
compactedOldSaves = true
|
|
local i
|
|
for i = 1, table.getn(list) do
|
|
CL.Aggregator.CompactTargets(list[i])
|
|
end
|
|
end
|
|
return list
|
|
end
|
|
|
|
-- A saved boss fight. pullBy is only ever set for bosses, which also
|
|
-- covers fights saved before isBoss existed.
|
|
local function IsBossFight(encounter)
|
|
return encounter.isBoss or encounter.pullBy ~= nil
|
|
end
|
|
|
|
-- History as the UI lists it: while "Remember boss fights only" is on,
|
|
-- trash fights saved before the option was turned on are hidden (not
|
|
-- deleted - turning the option off shows them again).
|
|
local function GetShownHistory()
|
|
local list = GetHistory()
|
|
if not CL.GetSetting("historyBossOnly") then return list end
|
|
local shown = {}
|
|
local i
|
|
for i = 1, table.getn(list) do
|
|
if IsBossFight(list[i]) then table.insert(shown, list[i]) end
|
|
end
|
|
return shown
|
|
end
|
|
|
|
-- Deletes a saved fight, identified by the encounter itself (list
|
|
-- positions differ between the full and the shown history).
|
|
local function DeleteEncounter(encounter)
|
|
local list = GetHistory()
|
|
local i
|
|
for i = 1, table.getn(list) do
|
|
if list[i] == encounter then
|
|
table.remove(list, i)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ClearHistory()
|
|
local key = EnsureEncountersTable()
|
|
CombatLedgerDB.encountersByChar[key] = {}
|
|
end
|
|
|
|
CL.History = {
|
|
SaveEncounter = SaveEncounter,
|
|
GetHistory = GetHistory,
|
|
GetShownHistory = GetShownHistory,
|
|
IsBossFight = IsBossFight,
|
|
DeleteEncounter = DeleteEncounter,
|
|
ClearHistory = ClearHistory,
|
|
TrimHistory = TrimHistory,
|
|
}
|