bbe2492a5b
Each DataStore_* / Altoholic_* addon now lives at the repo root, matching the Exiles fork-layout convention (one folder per addon, no wrapper dir).
312 lines
8.5 KiB
Lua
312 lines
8.5 KiB
Lua
local addonName = ...
|
|
local addon = _G[addonName]
|
|
|
|
local WHITE = "|cFFFFFFFF"
|
|
|
|
local THIS_ACCOUNT = "Default"
|
|
local INFO_REALM_LINE = 0
|
|
local INFO_CHARACTER_LINE = 1
|
|
local INFO_TOTAL_LINE = 2
|
|
|
|
local THISREALM_THISACCOUNT = 1
|
|
local THISREALM_ALLACCOUNTS = 2
|
|
local ALLREALMS_THISACCOUNT = 3
|
|
local ALLREALMS_ALLACCOUNTS = 4
|
|
|
|
|
|
addon.Characters = {}
|
|
|
|
local ns = addon.Characters -- ns = namespace
|
|
|
|
local characterList
|
|
local view
|
|
|
|
local function ProcessRealms(func)
|
|
local mode = addon.Options:Get("TabSummaryMode")
|
|
local thisRealm = GetRealmName()
|
|
|
|
-- this account only
|
|
if mode == THISREALM_THISACCOUNT then
|
|
func(THIS_ACCOUNT, thisRealm)
|
|
|
|
elseif mode == ALLREALMS_THISACCOUNT then
|
|
for realm in pairs(DataStore:GetRealms()) do
|
|
func(THIS_ACCOUNT, realm)
|
|
end
|
|
|
|
-- all accounts
|
|
elseif mode == THISREALM_ALLACCOUNTS then
|
|
for account in pairs(DataStore:GetAccounts()) do
|
|
for realm in pairs(DataStore:GetRealms(account)) do
|
|
if realm == thisRealm then
|
|
func(account, realm)
|
|
end
|
|
end
|
|
end
|
|
|
|
elseif mode == ALLREALMS_ALLACCOUNTS then
|
|
for account in pairs(DataStore:GetAccounts()) do
|
|
for realm in pairs(DataStore:GetRealms(account)) do
|
|
func(account, realm)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local totalMoney
|
|
local totalPlayed
|
|
local totalLevels
|
|
local realmCount
|
|
|
|
local function AddRealm(AccountName, RealmName)
|
|
|
|
local comm = Altoholic.Comm.Sharing
|
|
if comm.SharingInProgress then
|
|
if comm.account == AccountName and RealmName == GetRealmName() then
|
|
-- if we're trying to add the account+realm we're currently copying, then don't add it now.
|
|
return
|
|
end
|
|
end
|
|
|
|
local realmMoney = 0
|
|
local realmPlayed = 0
|
|
local realmLevels = 0
|
|
local realmBagSlots = 0
|
|
local realmFreeBagSlots = 0
|
|
local realmBankSlots = 0
|
|
local realmFreeBankSlots = 0
|
|
|
|
local SkillsCache = { {name = "", rank = 0}, {name = "", rank = 0} }
|
|
|
|
-- 1) Add the realm name
|
|
table.insert(characterList, { linetype = INFO_REALM_LINE + (realmCount*3),
|
|
isCollapsed = false,
|
|
account = AccountName,
|
|
realm = RealmName
|
|
} )
|
|
|
|
-- 2) Add the characters
|
|
for characterName, character in pairs(DataStore:GetCharacters(RealmName, AccountName)) do
|
|
SkillsCache[1].name = ""
|
|
SkillsCache[1].rank = 0
|
|
SkillsCache[1].spellID = nil
|
|
SkillsCache[2].name = ""
|
|
SkillsCache[2].rank = 0
|
|
SkillsCache[2].spellID = nil
|
|
|
|
local i = 1
|
|
local professions = DataStore:GetPrimaryProfessions(character)
|
|
if professions then
|
|
for SkillName, s in pairs(professions) do
|
|
SkillsCache[i].name = SkillName
|
|
SkillsCache[i].rank = DataStore:GetSkillInfo(character, SkillName)
|
|
SkillsCache[i].spellID = DataStore:GetProfessionSpellID(SkillName)
|
|
i = i + 1
|
|
|
|
if i > 2 then -- it seems that under certain conditions, the loop continues after 2 professions.., so break
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
table.insert(characterList, { linetype = INFO_CHARACTER_LINE + (realmCount*3),
|
|
key = character,
|
|
skillName1 = SkillsCache[1].name,
|
|
skillRank1 = SkillsCache[1].rank,
|
|
spellID1 = SkillsCache[1].spellID,
|
|
skillName2 = SkillsCache[2].name,
|
|
skillRank2 = SkillsCache[2].rank,
|
|
spellID2 = SkillsCache[2].spellID,
|
|
cooking = DataStore:GetCookingRank(character),
|
|
firstaid = DataStore:GetFirstAidRank(character),
|
|
fishing = DataStore:GetFishingRank(character),
|
|
riding = DataStore:GetRidingRank(character),
|
|
} )
|
|
|
|
realmLevels = realmLevels + (DataStore:GetCharacterLevel(character) or 0)
|
|
realmMoney = realmMoney + (DataStore:GetMoney(character) or 0)
|
|
realmPlayed = realmPlayed + (DataStore:GetPlayTime(character) or 0)
|
|
|
|
realmBagSlots = realmBagSlots + (DataStore:GetNumBagSlots(character) or 0)
|
|
realmFreeBagSlots = realmFreeBagSlots + (DataStore:GetNumFreeBagSlots(character) or 0)
|
|
realmBankSlots = realmBankSlots + (DataStore:GetNumBankSlots(character) or 0)
|
|
realmFreeBankSlots = realmFreeBankSlots + (DataStore:GetNumFreeBankSlots(character) or 0)
|
|
end -- end char
|
|
|
|
-- 3) Add the totals
|
|
table.insert(characterList, { linetype = INFO_TOTAL_LINE + (realmCount*3),
|
|
level = WHITE .. realmLevels,
|
|
money = realmMoney,
|
|
played = Altoholic:GetTimeString(realmPlayed),
|
|
bagSlots = realmBagSlots,
|
|
freeBagSlots = realmFreeBagSlots,
|
|
bankSlots = realmBankSlots,
|
|
freeBankSlots = realmFreeBankSlots
|
|
} )
|
|
|
|
totalMoney = totalMoney + realmMoney
|
|
totalPlayed = totalPlayed + realmPlayed
|
|
totalLevels = totalLevels + realmLevels
|
|
realmCount = realmCount + 1
|
|
end
|
|
|
|
function ns:BuildList()
|
|
characterList = characterList or {}
|
|
wipe(characterList)
|
|
|
|
totalMoney = 0
|
|
totalPlayed = 0
|
|
totalLevels = 0
|
|
realmCount = 0 -- will be required for sorting purposes
|
|
ProcessRealms(AddRealm)
|
|
|
|
AltoholicFrameTotalLv:SetText(format("%s |rLv", WHITE .. totalLevels))
|
|
AltoholicFrameTotalGold:SetText(format(GOLD_AMOUNT_TEXTURE, floor( totalMoney / 10000 ), 13, 13))
|
|
AltoholicFrameTotalPlayed:SetText(floor(totalPlayed / 86400) .. "|cFFFFD700d")
|
|
end
|
|
|
|
local function AddRealmView(AccountName, RealmName)
|
|
for index, line in pairs(characterList) do
|
|
if mod(line.linetype, 3) == INFO_REALM_LINE then
|
|
if (line.account == AccountName) and (line.realm == RealmName) then
|
|
-- insert index to current line (INFO_REALM_LINE)
|
|
table.insert(view, index)
|
|
index = index + 1
|
|
|
|
-- insert index to the rest of the realm
|
|
local linetype = mod(characterList[index].linetype, 3)
|
|
while (linetype ~= INFO_REALM_LINE) do
|
|
table.insert(view, index)
|
|
index = index + 1
|
|
if index > #characterList then
|
|
return
|
|
end
|
|
linetype = mod(characterList[index].linetype, 3)
|
|
end
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function ns:BuildView()
|
|
-- The character info index is a small table that basically indexes character info
|
|
-- ex: character info contains data for 4 realms on two accounts, but the index only cares about the summary tab filter,
|
|
-- and indexes just one realm, or one account
|
|
view = view or {}
|
|
wipe(view)
|
|
|
|
ProcessRealms(AddRealmView)
|
|
end
|
|
|
|
local function SortByPrimarySkill(a, b, skillName, ascending)
|
|
if (a.linetype ~= b.linetype) then -- sort by linetype first ..
|
|
return a.linetype < b.linetype
|
|
else -- and when they're identical, sort by field xx
|
|
if mod(a.linetype, 3) ~= INFO_CHARACTER_LINE then
|
|
return false -- don't swap lines if they're not INFO_CHARACTER_LINE
|
|
end
|
|
|
|
local skillA = DataStore:GetSkillInfo(a.key, a[skillName])
|
|
local skillB = DataStore:GetSkillInfo(b.key, b[skillName])
|
|
|
|
if ascending then
|
|
return skillA < skillB
|
|
else
|
|
return skillA > skillB
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SortByFunction(a, b, func, ascending)
|
|
if (a.linetype ~= b.linetype) then -- sort by linetype first ..
|
|
return a.linetype < b.linetype
|
|
else -- and when they're identical, sort by func xx
|
|
if mod(a.linetype, 3) ~= INFO_CHARACTER_LINE then
|
|
return false -- don't swap lines if they're not INFO_CHARACTER_LINE
|
|
end
|
|
|
|
local retA = DataStore[func](self, a.key) or 0 -- set to zero if a return value is nil, so that they can be compared
|
|
local retB = DataStore[func](self, b.key) or 0
|
|
|
|
if ascending then
|
|
return retA < retB
|
|
else
|
|
return retA > retB
|
|
end
|
|
end
|
|
end
|
|
|
|
function ns:Sort(frame, field)
|
|
local ascending = frame.ascendingSort
|
|
|
|
-- Primary Skill
|
|
if (field == "skillName1") or (field == "skillName2") then
|
|
table.sort(characterList, function(a, b) return SortByPrimarySkill(a, b, field, ascending)
|
|
end)
|
|
else
|
|
table.sort(characterList, function(a, b) return SortByFunction(a, b, field, ascending) end)
|
|
end
|
|
|
|
addon.Tabs.Summary:Refresh()
|
|
end
|
|
|
|
function ns:Get(index)
|
|
return characterList[index]
|
|
end
|
|
|
|
function ns:GetView()
|
|
return view
|
|
end
|
|
|
|
function ns:GetNum()
|
|
return #characterList or 0
|
|
end
|
|
|
|
function ns:GetInfo(index)
|
|
-- with the line number in the characterList table, return the name, realm & account of a char.
|
|
local lineType = ns:GetLineType(index)
|
|
|
|
if lineType == INFO_REALM_LINE then
|
|
local line = characterList[index]
|
|
return _, line.realm, line.account
|
|
elseif lineType == INFO_CHARACTER_LINE then
|
|
local account, realm, name = strsplit(".", characterList[index].key)
|
|
return name, realm, account
|
|
end
|
|
end
|
|
|
|
function ns:GetLineType(index)
|
|
return mod(characterList[index].linetype, 3)
|
|
end
|
|
|
|
function ns:GetField(index, field)
|
|
local character = characterList[index]
|
|
if character then
|
|
return character[field]
|
|
end
|
|
end
|
|
|
|
function ns:ToggleView(frame)
|
|
for _, line in pairs(characterList) do
|
|
if mod(line.linetype, 3) == INFO_REALM_LINE then
|
|
line.isCollapsed = (frame.isCollapsed) or false
|
|
end
|
|
end
|
|
end
|
|
|
|
function ns:ToggleHeader(frame)
|
|
local line = frame:GetParent():GetID()
|
|
if line == 0 then return end
|
|
|
|
local header = characterList[line]
|
|
|
|
if header.isCollapsed ~= nil then
|
|
if header.isCollapsed == true then
|
|
header.isCollapsed = false
|
|
else
|
|
header.isCollapsed = true
|
|
end
|
|
end
|
|
end
|