coa.5: refactor char display into guarded helpers; fix missed sites; restore login scan
release / release (push) Successful in 5s
release / release (push) Successful in 5s
- Extract AddCharacterTooltipHeader() + SetCharacterRowNameLevel() (Altoholic.lua);
nil-guards centralized, callers in AccountSummary/Activity/BagUsage/Skills/tooltip.
- Fix sites the manual sweep missed: Skills.lua (row + skill ranks), Keys.lua x3,
ShowClassIcons sort (Altoholic.lua:705, getters bypass their own or-0 via the wrapper).
- Restore login scan: OnPlayerAlive was ghost-only (fdcb25a) so iLvl never populated;
now scans once per session. Removed dated DEBUG leftovers.
This commit is contained in:
+25
-13
@@ -249,10 +249,12 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- *** Event Handlers ***
|
-- *** Event Handlers ***
|
||||||
|
local hasScannedThisSession
|
||||||
local function OnPlayerAlive()
|
local function OnPlayerAlive()
|
||||||
-- print("Altoholic.lua") -- DEBUG 2025 07 21
|
-- CoA: scan once at login (see DataStore_Inventory / commit fdcb25a). FRIENDLIST_UPDATE also
|
||||||
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard
|
-- keeps the friends list fresh; this just guarantees an initial scan without rescanning on res.
|
||||||
|
if hasScannedThisSession then return end
|
||||||
|
hasScannedThisSession = true
|
||||||
ScanFriends()
|
ScanFriends()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -585,6 +587,22 @@ function addon:GetDelayInDays(delay)
|
|||||||
return floor((time() - delay) / 86400)
|
return floor((time() - delay) / 86400)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- CoA: shared, nil-safe character display helpers.
|
||||||
|
-- DataStore char-based getters return *no value* for any module that hasn't
|
||||||
|
-- scanned a given character (DataStore.lua: "if not arg1.lastUpdate then return end").
|
||||||
|
-- Fresh alts have partial per-module data, so every field is guarded here once
|
||||||
|
-- instead of being copy-pasted (and missed) across the frames.
|
||||||
|
function Altoholic:AddCharacterTooltipHeader(character)
|
||||||
|
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character) or "?", DS:GetColoredCharacterFaction(character) or "")
|
||||||
|
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"],
|
||||||
|
GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", DS:GetCharacterClass(character) or ""), 1, 1, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Altoholic:SetCharacterRowNameLevel(entry, i, icon, character)
|
||||||
|
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", DS:GetCharacterClass(character) or ""))
|
||||||
|
_G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0))
|
||||||
|
end
|
||||||
|
|
||||||
function Altoholic:FormatDelay(timeStamp)
|
function Altoholic:FormatDelay(timeStamp)
|
||||||
-- timeStamp = value when time() was last called for a given variable (ex: last time the mailbox was checked)
|
-- timeStamp = value when time() was last called for a given variable (ex: last time the mailbox was checked)
|
||||||
if not timeStamp then
|
if not timeStamp then
|
||||||
@@ -679,19 +697,16 @@ function Altoholic:ShowClassIcons()
|
|||||||
local realm, account = Altoholic:GetCurrentRealm()
|
local realm, account = Altoholic:GetCurrentRealm()
|
||||||
|
|
||||||
|
|
||||||
-- ####################
|
-- Sort characters by level first, then average item level. The getters yield no value
|
||||||
|
-- for alts whose Characters/Inventory module hasn't scanned them, so default [3]/[4] to 0.
|
||||||
local CharNameList = DS:GetCharacters(realm, account)
|
local CharNameList = DS:GetCharacters(realm, account)
|
||||||
local CharNameList_sort = {}
|
local CharNameList_sort = {}
|
||||||
|
|
||||||
for k,v in pairs(CharNameList) do
|
for k,v in pairs(CharNameList) do
|
||||||
table.insert(CharNameList_sort,{k,v, DS:GetAverageItemLevel(v), DS:GetCharacterLevel(v)})
|
table.insert(CharNameList_sort, {k, v, DS:GetAverageItemLevel(v) or 0, DS:GetCharacterLevel(v) or 0})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- sort for level first, avg iLevel secondly
|
|
||||||
table.sort(CharNameList_sort, function(a,b) return b[3]+b[4]*10000 < a[3]+a[4]*10000 end)
|
table.sort(CharNameList_sort, function(a,b) return b[3]+b[4]*10000 < a[3]+a[4]*10000 end)
|
||||||
-- DEBUG_CHARLIST = CharNameList
|
|
||||||
-- print("-- altoholic DEBUG READY")
|
|
||||||
-- ####################
|
|
||||||
|
|
||||||
|
|
||||||
-- for characterName, character in pairs(DS:GetCharacters(realm, account)) do
|
-- for characterName, character in pairs(DS:GetCharacters(realm, account)) do
|
||||||
@@ -763,10 +778,7 @@ function Altoholic:DrawCharacterTooltip(self, charName)
|
|||||||
|
|
||||||
AltoTooltip:SetOwner(self, "ANCHOR_LEFT");
|
AltoTooltip:SetOwner(self, "ANCHOR_LEFT");
|
||||||
AltoTooltip:ClearLines();
|
AltoTooltip:ClearLines();
|
||||||
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character), DS:GetColoredCharacterFaction(character))
|
Altoholic:AddCharacterTooltipHeader(character)
|
||||||
|
|
||||||
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"],
|
|
||||||
GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", DS:GetCharacterClass(character) or ""),1,1,1)
|
|
||||||
|
|
||||||
local zone, subZone = DS:GetLocation(character)
|
local zone, subZone = DS:GetLocation(character)
|
||||||
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
## Author: Thaoky, Telkar-RG
|
## Author: Thaoky, Telkar-RG
|
||||||
## X-Edited-By: Exiles (Sub-Net) — florian.berthold@sub-net.at
|
## X-Edited-By: Exiles (Sub-Net) — florian.berthold@sub-net.at
|
||||||
## Version: 3.3.002b-coa.4
|
## Version: 3.3.002b-coa.5
|
||||||
## X-Category: Inventory, Tradeskill, Mail
|
## X-Category: Inventory, Tradeskill, Mail
|
||||||
## X-Localizations: enUS, frFR, zhCN, zhTW, deDE, koKR, esES, esMX, ruRU
|
## X-Localizations: enUS, frFR, zhCN, zhTW, deDE, koKR, esES, esMX, ruRU
|
||||||
## X-Website: http://wow.curse.com/downloads/wow-addons/details/altoholic.aspx
|
## X-Website: http://wow.curse.com/downloads/wow-addons/details/altoholic.aspx
|
||||||
|
|||||||
@@ -249,10 +249,7 @@ function ns:Update()
|
|||||||
_G[entry..i.."Name"]:SetWidth(170)
|
_G[entry..i.."Name"]:SetWidth(170)
|
||||||
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
||||||
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
||||||
-- CoA: DataStore char-based getters return *no value* for any module that hasn't scanned this char
|
addon:SetCharacterRowNameLevel(entry, i, icon, character)
|
||||||
-- (DataStore.lua: "if not arg1.lastUpdate then return end"). Fresh alts have partial module data, so guard every result.
|
|
||||||
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", DS:GetCharacterClass(character) or ""))
|
|
||||||
_G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0))
|
|
||||||
|
|
||||||
_G[entry..i.."Money"]:SetText(addon:GetMoneyString(DS:GetMoney(character) or 0))
|
_G[entry..i.."Money"]:SetText(addon:GetMoneyString(DS:GetMoney(character) or 0))
|
||||||
_G[entry..i.."Played"]:SetText(addon:GetTimeString(DS:GetPlayTime(character) or 0))
|
_G[entry..i.."Played"]:SetText(addon:GetTimeString(DS:GetPlayTime(character) or 0))
|
||||||
@@ -344,9 +341,7 @@ function ns:Level_OnEnter(frame)
|
|||||||
AltoTooltip:ClearLines();
|
AltoTooltip:ClearLines();
|
||||||
AltoTooltip:SetOwner(frame, "ANCHOR_RIGHT");
|
AltoTooltip:SetOwner(frame, "ANCHOR_RIGHT");
|
||||||
|
|
||||||
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character), DS:GetColoredCharacterFaction(character))
|
addon:AddCharacterTooltipHeader(character)
|
||||||
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"],
|
|
||||||
GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", DS:GetCharacterClass(character) or ""),1,1,1)
|
|
||||||
|
|
||||||
local zone, subZone = DS:GetLocation(character)
|
local zone, subZone = DS:GetLocation(character)
|
||||||
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
||||||
|
|||||||
@@ -100,8 +100,7 @@ function ns:Update()
|
|||||||
_G[entry..i.."Name"]:SetWidth(170)
|
_G[entry..i.."Name"]:SetWidth(170)
|
||||||
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
||||||
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
||||||
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", DS:GetCharacterClass(character) or ""))
|
addon:SetCharacterRowNameLevel(entry, i, icon, character)
|
||||||
_G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0))
|
|
||||||
|
|
||||||
local color
|
local color
|
||||||
local num = DS:GetNumMails(character) or 0
|
local num = DS:GetNumMails(character) or 0
|
||||||
@@ -181,9 +180,7 @@ function ns:OnEnter(self)
|
|||||||
AltoTooltip:ClearLines();
|
AltoTooltip:ClearLines();
|
||||||
AltoTooltip:SetOwner(self, "ANCHOR_RIGHT");
|
AltoTooltip:SetOwner(self, "ANCHOR_RIGHT");
|
||||||
|
|
||||||
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character), DS:GetColoredCharacterFaction(character))
|
addon:AddCharacterTooltipHeader(character)
|
||||||
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"],
|
|
||||||
GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", DS:GetCharacterClass(character) or ""),1,1,1)
|
|
||||||
|
|
||||||
local zone, subZone = DS:GetLocation(character)
|
local zone, subZone = DS:GetLocation(character)
|
||||||
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
AltoTooltip:AddLine(format("%s: %s |r(%s|r)", L["Zone"], GOLD..(zone or "?"), GOLD..(subZone or "")),1,1,1)
|
||||||
|
|||||||
@@ -96,8 +96,7 @@ function ns:Update()
|
|||||||
_G[entry..i.."Name"]:SetWidth(170)
|
_G[entry..i.."Name"]:SetWidth(170)
|
||||||
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
||||||
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
||||||
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", DS:GetCharacterClass(character) or ""))
|
addon:SetCharacterRowNameLevel(entry, i, icon, character)
|
||||||
_G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0))
|
|
||||||
|
|
||||||
_G[entry..i.."FreeBags"]:SetText(GREEN .. (DS:GetNumFreeBagSlots(character) or 0))
|
_G[entry..i.."FreeBags"]:SetText(GREEN .. (DS:GetNumFreeBagSlots(character) or 0))
|
||||||
_G[entry..i.."FreeBank"]:SetText(GREEN .. (DS:GetNumFreeBankSlots(character) or 0))
|
_G[entry..i.."FreeBank"]:SetText(GREEN .. (DS:GetNumFreeBankSlots(character) or 0))
|
||||||
@@ -182,9 +181,7 @@ function ns:OnEnter(self)
|
|||||||
|
|
||||||
AltoTooltip:ClearLines();
|
AltoTooltip:ClearLines();
|
||||||
AltoTooltip:SetOwner(self, "ANCHOR_RIGHT");
|
AltoTooltip:SetOwner(self, "ANCHOR_RIGHT");
|
||||||
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character), DS:GetColoredCharacterFaction(character))
|
addon:AddCharacterTooltipHeader(character)
|
||||||
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"],
|
|
||||||
GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", DS:GetCharacterClass(character) or ""),1,1,1)
|
|
||||||
AltoTooltip:AddLine(" ",1,1,1);
|
AltoTooltip:AddLine(" ",1,1,1);
|
||||||
|
|
||||||
local id = self:GetID()
|
local id = self:GetID()
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ function ns:Item_OnEnter(frame)
|
|||||||
|
|
||||||
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
||||||
AltoTooltip:ClearLines()
|
AltoTooltip:ClearLines()
|
||||||
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character), nameKey) )
|
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character) or "?", nameKey) )
|
||||||
AltoTooltip:AddLine(" ")
|
AltoTooltip:AddLine(" ")
|
||||||
|
|
||||||
local questDone, cr,cg,cb
|
local questDone, cr,cg,cb
|
||||||
@@ -848,7 +848,7 @@ function ns:Item_OnEnter(frame)
|
|||||||
else
|
else
|
||||||
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
||||||
AltoTooltip:ClearLines()
|
AltoTooltip:ClearLines()
|
||||||
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character), nameKey) )
|
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character) or "?", nameKey) )
|
||||||
AltoTooltip:AddLine(" ")
|
AltoTooltip:AddLine(" ")
|
||||||
|
|
||||||
local questDone, cr,cg,cb
|
local questDone, cr,cg,cb
|
||||||
@@ -912,7 +912,7 @@ function ns:Item_OnEnter(frame)
|
|||||||
else
|
else
|
||||||
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
AltoTooltip:SetOwner(frame, "ANCHOR_LEFT")
|
||||||
AltoTooltip:ClearLines()
|
AltoTooltip:ClearLines()
|
||||||
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character), nameKey) )
|
AltoTooltip:AddLine( format("%s|r: %s", DS:GetColoredCharacterName(character) or "?", nameKey) )
|
||||||
AltoTooltip:AddLine(" ")
|
AltoTooltip:AddLine(" ")
|
||||||
AltoTooltip:AddLine(L["Required reputation"] .. ":",1,1,1)
|
AltoTooltip:AddLine(L["Required reputation"] .. ":",1,1,1)
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,7 @@ function ns:Update()
|
|||||||
_G[entry..i.."Name"]:SetWidth(170)
|
_G[entry..i.."Name"]:SetWidth(170)
|
||||||
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
|
||||||
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
_G[entry..i.."NameNormalText"]:SetWidth(170)
|
||||||
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character), DS:GetCharacterClass(character)))
|
addon:SetCharacterRowNameLevel(entry, i, icon, character)
|
||||||
_G[entry..i.."Level"]:SetText(GREEN .. DS:GetCharacterLevel(character))
|
|
||||||
|
|
||||||
-- profession 1
|
-- profession 1
|
||||||
local field = Characters:GetField(line, "spellID1")
|
local field = Characters:GetField(line, "spellID1")
|
||||||
@@ -251,6 +250,7 @@ function ns:OnEnter(frame)
|
|||||||
local DS = DataStore
|
local DS = DataStore
|
||||||
local character = DS:GetCharacter(Characters:GetInfo(line))
|
local character = DS:GetCharacter(Characters:GetInfo(line))
|
||||||
local curRank, maxRank = DS:GetSkillInfo(character, skillName)
|
local curRank, maxRank = DS:GetSkillInfo(character, skillName)
|
||||||
|
curRank, maxRank = curRank or 0, maxRank or 0 -- CoA: getter returns no value for skills DataStore_Skills hasn't scanned
|
||||||
local profession = DS:GetProfession(character, skillName)
|
local profession = DS:GetProfession(character, skillName)
|
||||||
|
|
||||||
if (id >= 1) and (id <= 6) then
|
if (id >= 1) and (id <= 6) then
|
||||||
@@ -268,6 +268,7 @@ function ns:OnEnter(frame)
|
|||||||
skillName = L["Rogue Proficiencies"]
|
skillName = L["Rogue Proficiencies"]
|
||||||
|
|
||||||
local curLock, maxLock = DS:GetSkillInfo(character, L["Lockpicking"])
|
local curLock, maxLock = DS:GetSkillInfo(character, L["Lockpicking"])
|
||||||
|
curLock, maxLock = curLock or 0, maxLock or 0 -- CoA: guard unscanned lockpicking
|
||||||
rank = TEAL .. L["Lockpicking"] .. " " .. curLock .. "/" .. maxLock
|
rank = TEAL .. L["Lockpicking"] .. " " .. curLock .. "/" .. maxLock
|
||||||
suggestion = addon:GetSuggestion(L["Lockpicking"], curLock)
|
suggestion = addon:GetSuggestion(L["Lockpicking"], curLock)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -167,10 +167,13 @@ function ScanInventory()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- *** Event Handlers ***
|
-- *** Event Handlers ***
|
||||||
|
local hasScannedThisSession
|
||||||
local function OnPlayerAlive()
|
local function OnPlayerAlive()
|
||||||
-- print("DataStore_Inventory.lua") -- DEBUG 2025 07 21
|
-- CoA: scan once at login. PLAYER_ALIVE also fires on resurrect / Feign-Death cancel where gear
|
||||||
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard
|
-- is unchanged, so skip those. (The previous "only when ghost" gate also skipped login, so iLvl
|
||||||
|
-- never populated and UNIT_INVENTORY_CHANGED was the only scan path - see commit fdcb25a.)
|
||||||
|
if hasScannedThisSession then return end
|
||||||
|
hasScannedThisSession = true
|
||||||
ScanInventory()
|
ScanInventory()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
## Notes: Stores information about character inventory
|
## Notes: Stores information about character inventory
|
||||||
## Author: Thaoky (EU-Marécages de Zangar)
|
## Author: Thaoky (EU-Marécages de Zangar)
|
||||||
## X-Edited-By: Exiles (Sub-Net)
|
## X-Edited-By: Exiles (Sub-Net)
|
||||||
## Version: 3.3.002-coa.2
|
## Version: 3.3.002-coa.5
|
||||||
## Dependencies: DataStore
|
## Dependencies: DataStore
|
||||||
## OptionalDeps: Ace3
|
## OptionalDeps: Ace3
|
||||||
## SavedVariables: DataStore_InventoryDB
|
## SavedVariables: DataStore_InventoryDB
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ Altoholic: modified development for WotLK
|
|||||||
|
|
||||||
Ported for the Ascension CoA (Vol'jin) 3.3.5a client by the Exiles guild. Released as `*-coa.N` tags via Gitea Actions; see `Exiles/coa-altoholic`.
|
Ported for the Ascension CoA (Vol'jin) 3.3.5a client by the Exiles guild. Released as `*-coa.N` tags via Gitea Actions; see `Exiles/coa-altoholic`.
|
||||||
|
|
||||||
|
- **3.3.002b-coa.5** — Refactor + completeness pass:
|
||||||
|
- Extracted the duplicated character header/row blocks into `Altoholic:AddCharacterTooltipHeader()` and `Altoholic:SetCharacterRowNameLevel()` — the nil-guards now live in one place instead of being copy-pasted across frames.
|
||||||
|
- Fixed crash sites the per-frame sweep had missed: `Skills.lua` (row + skill-rank tooltip), `Keys.lua` (×3 `format` with possibly-nil name), and the latent `ShowClassIcons` sort (`Altoholic.lua` — getters bypass their own `or 0` via the DataStore wrapper).
|
||||||
|
- Restored login scanning: `OnPlayerAlive` in `Altoholic.lua` + `DataStore_Inventory` was gated to ghost-only (commit fdcb25a), so inventory/iLvl never populated on login. Now scans once per session (still skips resurrect/Feign-Death rescans). Removed dated DEBUG leftovers.
|
||||||
- **3.3.002b-coa.4** — Rebranded to the Exiles fork (title `Altoholic (Exiles)`; Thaoky/Telkar-RG still credited as Author). Hardened **all** Altoholic frames against partial alt records: DataStore char-based getters return *no value* for any module that hasn't scanned a char, and the frames assumed full data everywhere. Guarded every `format`/concat/arithmetic/`pairs` site across AccountSummary, Activity, BagUsage, Quests, Reputations, TabCharacters, `DrawCharacterTooltip`, and the recipe tooltip. No DataStore contract change.
|
- **3.3.002b-coa.4** — Rebranded to the Exiles fork (title `Altoholic (Exiles)`; Thaoky/Telkar-RG still credited as Author). Hardened **all** Altoholic frames against partial alt records: DataStore char-based getters return *no value* for any module that hasn't scanned a char, and the frames assumed full data everywhere. Guarded every `format`/concat/arithmetic/`pairs` site across AccountSummary, Activity, BagUsage, Quests, Reputations, TabCharacters, `DrawCharacterTooltip`, and the recipe tooltip. No DataStore contract change.
|
||||||
- **3.3.002b-coa.3** — More partial-record guards in `DataStore_Characters` (own alts seen via guild comm but never fully scanned):
|
- **3.3.002b-coa.3** — More partial-record guards in `DataStore_Characters` (own alts seen via guild comm but never fully scanned):
|
||||||
- `GetXPRate` — guard nil/zero `XPMax` (crashed AccountSummary; also fixes div-by-zero at max level).
|
- `GetXPRate` — guard nil/zero `XPMax` (crashed AccountSummary; also fixes div-by-zero at max level).
|
||||||
|
|||||||
Reference in New Issue
Block a user