Compare commits

...

6 Commits

Author SHA1 Message Date
florian.berthold 5f39ea21fa coa.30: show all professions in the character view (4x3 wrapped grid)
release / release (push) Successful in 5s
CoA characters can learn every profession, but the char-view panel only had 2 profession
quick-icons. Added Prof1-12 laid out as a wrapped 4-per-row grid in the open middle-left
area (room exists now that the window is 555 tall), clear of the dropdowns and the bottom
view-groups. UpdateViewIcons already fills/hides them dynamically (coa.13).
2026-05-30 01:33:20 +02:00
florian.berthold 57c603fa8e coa.29: right-size VisibleLines for the taller window (rows were overflowing)
release / release (push) Successful in 5s
All list rows are 22px; the resize had set VisibleLines=20 uniformly (20x22=440 > the 414px
content frame), so the bottom rows spilled past the frame - visible as the guild list
running into the 'Click a character's AiL' footer. Set 18 rows for all list tabs (18x22=396),
17 for GuildMembers (it has the equipment footer).
2026-05-30 01:09:12 +02:00
florian.berthold f4f3de929b coa.28: fix login scan in 9 DataStore modules (the 'data not saved' root cause)
release / release (push) Successful in 5s
Quests, Achievements, Reputations, Pets, Stats, Skills, Crafts, Spells, Talents all had
the ghost-gated PLAYER_ALIVE scan (DEBUG 2025-07-21 leftover): they only scanned when the
player died and released spirit, so their data never populated on a normal login. Now
scan once per session at login (addon.coaScannedThisSession guard), matching the earlier
DataStore_Characters/_Inventory fix. This is why reputations/recipes/quests/pets/etc were
'not saved'.
2026-05-29 23:55:29 +02:00
florian.berthold ee3fec624d coa.27: Skills polish - tighter rank column, gold Name(Class) headers, spacer rows
release / release (push) Successful in 5s
Rank column pulled left (250->195), name cell narrowed. Headers now show class-colored
character name from the key (reliable) + (Class), with a blank spacer row between characters.
2026-05-29 23:52:35 +02:00
florian.berthold 863709e450 coa.26: fix Skills frame overlapping the menu (745->615 width)
release / release (push) Successful in 5s
Root cause of the 'all over the place' Skills layout: the Skills content frame was 745
wide (widened at coa.9 for extra columns) vs 615 for every other Summary view. Both
anchor TOPRIGHT, so the extra 130px pushed the Skills frame's LEFT edge over the nav menu
-> profession names rendered on top of the menu. Restored to 615 so the left edge clears
the menu like AccountSummary; the two-column name/rank list now sits in the content area.
2026-05-29 23:37:56 +02:00
florian.berthold 78e50e9f5c coa.25: clean two-column Skills layout
release / release (push) Successful in 5s
Skills vertical list now uses a proper two-column row: indented [icon] profession name
in the Name cell, rank/max color-coded in its own Level column to the right (was all
crammed into one text cell). Character headers span the row with name + (class).
2026-05-29 22:58:45 +02:00
22 changed files with 91 additions and 39 deletions
+1 -1
View File
@@ -338,7 +338,7 @@ function addon:OnEnable()
-- CoA: use a Lua constant, not GetAddOnMetadata — TOC metadata is cached at game launch -- CoA: use a Lua constant, not GetAddOnMetadata — TOC metadata is cached at game launch
-- and does NOT refresh on /reload, so the .toc version looked stale ("still .18"). A Lua -- and does NOT refresh on /reload, so the .toc version looked stale ("still .18"). A Lua
-- constant re-evaluates on every /reload, giving a truthful loaded-code version. Bump with the .toc. -- constant re-evaluates on every /reload, giving a truthful loaded-code version. Bump with the .toc.
AltoholicFrameName:SetText("Altoholic |cFFFFFFFF3.3.002b-coa.24|r") AltoholicFrameName:SetText("Altoholic |cFFFFFFFF3.3.002b-coa.30|r")
local realm = GetRealmName() local realm = GetRealmName()
local player = UnitName("player") local player = UnitName("player")
+1 -1
View File
@@ -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.24 ## Version: 3.3.002b-coa.30
## 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
+1 -1
View File
@@ -168,7 +168,7 @@ end
function ns:Update() function ns:Update()
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameSummary" local frame = "AltoholicFrameSummary"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -23,7 +23,7 @@ local ns = addon.Activity -- ns = namespace
local Characters = addon.Characters local Characters = addon.Characters
function ns:Update() function ns:Update()
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameActivity" local frame = "AltoholicFrameActivity"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -22,7 +22,7 @@ local ns = addon.BagUsage -- ns = namespace
local Characters = addon.Characters local Characters = addon.Characters
function ns:Update() function ns:Update()
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameBagUsage" local frame = "AltoholicFrameBagUsage"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -72,7 +72,7 @@ function ns:Update()
BuildView() BuildView()
end end
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameGuildBankTabs" local frame = "AltoholicFrameGuildBankTabs"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -285,7 +285,7 @@ function ns:Update()
BuildView() BuildView()
end end
local VisibleLines = 20 local VisibleLines = 17
local frame = "AltoholicFrameGuildMembers" local frame = "AltoholicFrameGuildMembers"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -221,7 +221,7 @@ function ns:Update()
BuildView() BuildView()
end end
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameGuildProfessions" local frame = "AltoholicFrameGuildProfessions"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -34,7 +34,7 @@ function ns:Update()
local character = addon.Tabs.Characters:GetCurrent() local character = addon.Tabs.Characters:GetCurrent()
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameQuests" local frame = "AltoholicFrameQuests"
local entry = frame.."Entry" local entry = frame.."Entry"
+1 -1
View File
@@ -218,7 +218,7 @@ end
function ns:Update() function ns:Update()
local currentProfession = addon.TradeSkills.CurrentProfession local currentProfession = addon.TradeSkills.CurrentProfession
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameRecipes" local frame = "AltoholicFrameRecipes"
local entry = frame.."Entry" local entry = frame.."Entry"
+26 -8
View File
@@ -30,7 +30,7 @@ local inset = 2
function ns:Update() function ns:Update()
local VisibleLines = 20 local VisibleLines = 18
local frame = "AltoholicFrameSkills" local frame = "AltoholicFrameSkills"
local entry = frame.."Entry" local entry = frame.."Entry"
local DS = DataStore local DS = DataStore
@@ -66,6 +66,7 @@ function ns:Update()
items[#items + 1] = { kind = "skill", viewLine = viewLine, character = character, items[#items + 1] = { kind = "skill", viewLine = viewLine, character = character,
spellID = 33388, name = (L and L["Riding"]) or "Riding", rank = riding, maxRank = 300 } spellID = 33388, name = (L and L["Riding"]) or "Riding", rank = riding, maxRank = 300 }
end end
items[#items + 1] = { kind = "spacer" } -- blank row between characters
end end
end end
@@ -76,27 +77,44 @@ function ns:Update()
local item = items[i + offset] local item = items[i + offset]
if item then if item then
_G[e.."Collapse"]:Hide() _G[e.."Collapse"]:Hide()
_G[e.."Level"]:SetText("")
_G[e.."Skill1NormalText"]:SetText("") _G[e.."Skill1NormalText"]:SetText("")
_G[e.."CookingNormalText"]:SetText("") _G[e.."CookingNormalText"]:SetText("")
_G[e.."FirstAidNormalText"]:SetText("") _G[e.."FirstAidNormalText"]:SetText("")
_G[e.."FishingNormalText"]:SetText("") _G[e.."FishingNormalText"]:SetText("")
_G[e.."RidingNormalText"]:SetText("") _G[e.."RidingNormalText"]:SetText("")
_G[e.."Name"]:SetWidth(680)
_G[e.."Name"]:SetPoint("TOPLEFT", 15, 0)
_G[e.."NameNormalText"]:SetWidth(680)
if item.kind == "header" then if item.kind == "spacer" then
-- blank separator row between characters
_G[e.."Name"]:SetPoint("TOPLEFT", 15, 0)
_G[e.."NameNormalText"]:SetText("")
_G[e.."Level"]:SetText("")
elseif item.kind == "header" then
-- character header: gold "Name (Class)" across the row, no rank column
_G[e.."Name"]:SetPoint("TOPLEFT", 12, 0)
_G[e.."Name"]:SetWidth(420)
_G[e.."NameNormalText"]:SetWidth(420)
local cname = Characters:GetInfo(item.viewLine) or "?" -- name from the key, always present (scanned char.name can be nil)
local locClass, engClass = DS:GetCharacterClass(item.character) local locClass, engClass = DS:GetCharacterClass(item.character)
local className = Altoholic:GetCoAClassName(engClass) or locClass or "" -- CoA: PROPHET->Venomancer, MONK->Templar, … local className = Altoholic:GetCoAClassName(engClass) or locClass or "" -- CoA: PROPHET->Venomancer, MONK->Templar, …
_G[e.."NameNormalText"]:SetText( (DS:GetColoredCharacterName(item.character) or "?") .. " " .. WHITE .. "(" .. className .. ")" ) local classColor = DS:GetClassColor(item.character) or WHITE
_G[e.."NameNormalText"]:SetText( classColor .. cname .. "|r " .. WHITE .. "(" .. className .. ")" )
_G[e.."Level"]:SetText("")
else else
-- profession row: [icon] name in the Name cell (indented), rank/max in its own column
local iconEsc = "" local iconEsc = ""
if item.spellID then if item.spellID then
iconEsc = addon:TextureToFontstring2(addon:GetSpellIcon(item.spellID), size, size, inset, inset, inset, inset) .. " " iconEsc = addon:TextureToFontstring2(addon:GetSpellIcon(item.spellID), size, size, inset, inset, inset, inset) .. " "
end end
_G[e.."Name"]:SetPoint("TOPLEFT", 34, 0)
_G[e.."Name"]:SetWidth(170)
_G[e.."NameNormalText"]:SetWidth(170)
_G[e.."NameNormalText"]:SetText( iconEsc .. WHITE .. item.name )
local cap = (item.maxRank > 0) and item.maxRank or 450 local cap = (item.maxRank > 0) and item.maxRank or 450
_G[e.."NameNormalText"]:SetText( " " .. iconEsc .. WHITE .. item.name .. " " .. ns:GetColor(item.rank, cap) .. item.rank .. "/" .. item.maxRank .. "|r" ) _G[e.."Level"]:SetPoint("TOPLEFT", 195, 0)
_G[e.."Level"]:SetWidth(120)
_G[e.."Level"]:SetJustifyH("LEFT")
_G[e.."Level"]:SetText( ns:GetColor(item.rank, cap) .. item.rank .. " / " .. item.maxRank )
end end
btn.coaItem = item btn.coaItem = item
btn:SetID(item.viewLine or 0) btn:SetID(item.viewLine or 0)
+2 -2
View File
@@ -34,7 +34,7 @@
<Button name="AltoSkillsTemplate" virtual="true"> <Button name="AltoSkillsTemplate" virtual="true">
<Size> <Size>
<AbsDimension x="745" y="22"/> <AbsDimension x="615" y="22"/>
</Size> </Size>
<Layers> <Layers>
<Layer level="BACKGROUND"> <Layer level="BACKGROUND">
@@ -194,7 +194,7 @@
<Frame name="AltoholicFrameSkills" parent="AltoholicTabSummary" hidden="true"> <Frame name="AltoholicFrameSkills" parent="AltoholicTabSummary" hidden="true">
<Size> <Size>
<AbsDimension x="745" y="414"/> <AbsDimension x="615" y="414"/>
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="TOPRIGHT"> <Anchor point="TOPRIGHT">
+35 -10
View File
@@ -243,19 +243,44 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
</Button> </Button>
<!-- CoA: a character can learn every profession. Lay the profession quick-icons out
as a wrapped 4-per-row grid in the open middle-left area (the taller window has room
below the Character dropdown). UpdateViewIcons fills/hides Prof1..12 dynamically. -->
<Button name="$parent_Prof1" inherits="AltoViewIconTemplate"> <Button name="$parent_Prof1" inherits="AltoViewIconTemplate">
<Anchors> <Anchors><Anchor point="TOPLEFT" relativeTo="AltoholicTabCharacters" relativePoint="TOPLEFT"><Offset x="30" y="-205" /></Anchor></Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_FirstAid" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button> </Button>
<Button name="$parent_Prof2" inherits="AltoViewIconTemplate"> <Button name="$parent_Prof2" inherits="AltoViewIconTemplate">
<Anchors> <Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof1" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof1" relativePoint="BOTTOMRIGHT" > </Button>
<Offset x="5" y="0" /> <Button name="$parent_Prof3" inherits="AltoViewIconTemplate">
</Anchor> <Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof2" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Anchors> </Button>
<Button name="$parent_Prof4" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof3" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof5" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parent_Prof1" relativePoint="BOTTOMLEFT"><Offset x="0" y="-5" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof6" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof5" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof7" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof6" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof8" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof7" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof9" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parent_Prof5" relativePoint="BOTTOMLEFT"><Offset x="0" y="-5" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof10" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof9" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof11" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof10" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button>
<Button name="$parent_Prof12" inherits="AltoViewIconTemplate">
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof11" relativePoint="BOTTOMRIGHT"><Offset x="5" y="0" /></Anchor></Anchors>
</Button> </Button>
<Button name="$parent_Sort1" inherits="AltoSortButtonTemplate" id="1"> <Button name="$parent_Sort1" inherits="AltoSortButtonTemplate" id="1">
@@ -235,7 +235,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Achievements.lua") -- DEBUG 2025 07 21 -- print("DataStore_Achievements.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanAllAchievements() ScanAllAchievements()
ScanProgress() ScanProgress()
+2 -1
View File
@@ -546,7 +546,8 @@ end
-- *** Event Handlers *** -- *** Event Handlers ***
local function OnPlayerAlive() local function OnPlayerAlive()
-- print("DataStore_Crafts.lua") -- DEBUG 2025 07 21 -- print("DataStore_Crafts.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanProfessionLinks() ScanProfessionLinks()
end end
+2 -1
View File
@@ -46,7 +46,8 @@ end
-- *** Event Handlers *** -- *** Event Handlers ***
local function OnPlayerAlive() local function OnPlayerAlive()
-- print("DataStore_Pets.lua") -- DEBUG 2025 07 21 -- print("DataStore_Pets.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanCompanions("CRITTER") ScanCompanions("CRITTER")
ScanCompanions("MOUNT") ScanCompanions("MOUNT")
+2 -1
View File
@@ -177,7 +177,8 @@ end
-- *** Event Handlers *** -- *** Event Handlers ***
local function OnPlayerAlive() local function OnPlayerAlive()
-- print("DataStore_Quests.lua") -- DEBUG 2025 07 21 -- print("DataStore_Quests.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanQuests() ScanQuests()
end end
@@ -177,7 +177,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Reputations.lua") -- DEBUG 2025 07 21 -- print("DataStore_Reputations.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanReputations() ScanReputations()
end end
+2 -1
View File
@@ -239,7 +239,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Skills.lua") -- DEBUG 2025 07 21 -- print("DataStore_Skills.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanSkills() ScanSkills()
end end
+2 -1
View File
@@ -105,7 +105,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Spells.lua") -- DEBUG 2025 07 21 -- print("DataStore_Spells.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanSpells() ScanSpells()
end end
+2 -1
View File
@@ -156,7 +156,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Stats.lua") -- DEBUG 2025 07 21 -- print("DataStore_Stats.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanStats() ScanStats()
end end
+2 -1
View File
@@ -419,7 +419,8 @@ end
-- *** EVENT HANDLERS *** -- *** EVENT HANDLERS ***
function addon:PLAYER_ALIVE() function addon:PLAYER_ALIVE()
-- print("DataStore_Talents.lua") -- DEBUG 2025 07 21 -- print("DataStore_Talents.lua") -- DEBUG 2025 07 21
if not UnitIsGhost("player") then return end -- only scan if player released spirit and went to graveyard if addon.coaScannedThisSession then return end -- CoA: scan once at login (was ghost-gated, so data never saved on a normal login - the cause of "data not saved")
addon.coaScannedThisSession = true
ScanTalents() ScanTalents()
ScanTalentReference() ScanTalentReference()