Compare commits

..

6 Commits

Author SHA1 Message Date
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
florian.berthold 14dd30e9a9 coa.24: revert char-view profession grid to clean 2-slot original
release / release (push) Successful in 4s
The relocated Prof1-8 block (coa.20) was jumbled below the dropdowns in the narrow
char-view panel. Restored Prof1/Prof2 in the original bottom row (Cooking/First Aid/Prof1/Prof2);
removed Prof3-8. Full profession list stays on the Skills tab. No crash (loop stops at Prof2).
2026-05-29 22:50:04 +02:00
florian.berthold 996a11dd0a coa.23: correct CoA class names (PROPHET->Venomancer etc.) + fix Skills rank/max
release / release (push) Successful in 5s
- CoA renamed classes but UnitClass returns old tokens; added a token->name map
  (CoAClassColors.lua, from coa-omen) applied in the Skills header + the shared
  AddCharacterTooltipHeader/SetCharacterRowNameLevel helpers (fixes class names everywhere).
- Skills vertical list now shows rank/max (precompute carries maxRank; was showing /0).
2026-05-29 22:27:53 +02:00
florian.berthold d1616b4354 coa.22: Skills view as a vertical list (character header + one row per profession)
release / release (push) Successful in 6s
Rewrote the Skills tab from the cramped multi-column per-character grid to a vertical
list: each character is a header row, followed by one row per known primary profession
(incl Woodcutting/Woodworking) + secondary skills (Cooking/First Aid/Fishing) + Riding,
icon + name + rank/max, top to bottom. Simplified the column headers to match.
2026-05-29 22:04:19 +02:00
florian.berthold 3663d44cd4 coa.21: title from Lua constant (updates on /reload, unlike cached TOC metadata)
release / release (push) Successful in 5s
GetAddOnMetadata Version is cached at game launch and not refreshed by /reload, so the
title showed a stale version after reloads ('still .18'). Use a Lua constant that
re-evaluates each /reload as a truthful loaded-code indicator.
2026-05-29 20:42:03 +02:00
8 changed files with 138 additions and 449 deletions
+10 -4
View File
@@ -335,8 +335,10 @@ function addon:OnEnable()
-- CoA: just "Altoholic <version>" in the title bar (Exiles branding + author credit live in the .toc). -- CoA: just "Altoholic <version>" in the title bar (Exiles branding + author credit live in the .toc).
-- Read the live .toc Version so it tracks each -coa.N release without editing this string. -- Read the live .toc Version so it tracks each -coa.N release without editing this string.
local titleVersion = GetAddOnMetadata(addonName, "Version") or addon.Version -- CoA: use a Lua constant, not GetAddOnMetadata — TOC metadata is cached at game launch
AltoholicFrameName:SetText("Altoholic |cFFFFFFFF".. titleVersion .."|r") -- 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.
AltoholicFrameName:SetText("Altoholic |cFFFFFFFF3.3.002b-coa.26|r")
local realm = GetRealmName() local realm = GetRealmName()
local player = UnitName("player") local player = UnitName("player")
@@ -606,13 +608,17 @@ end
-- Fresh alts have partial per-module data, so every field is guarded here once -- Fresh alts have partial per-module data, so every field is guarded here once
-- instead of being copy-pasted (and missed) across the frames. -- instead of being copy-pasted (and missed) across the frames.
function Altoholic:AddCharacterTooltipHeader(character) function Altoholic:AddCharacterTooltipHeader(character)
local locClass, engClass = DS:GetCharacterClass(character)
local className = Altoholic:GetCoAClassName(engClass) or locClass or "" -- CoA: current class name (PROPHET->Venomancer, …)
AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character) or "?", DS:GetColoredCharacterFaction(character) or "") AltoTooltip:AddDoubleLine(DS:GetColoredCharacterName(character) or "?", DS:GetColoredCharacterFaction(character) or "")
AltoTooltip:AddLine(format("%s %s |r%s %s", L["Level"], 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) GREEN..(DS:GetCharacterLevel(character) or 0), DS:GetCharacterRace(character) or "", className), 1, 1, 1)
end end
function Altoholic:SetCharacterRowNameLevel(entry, i, icon, character) function Altoholic:SetCharacterRowNameLevel(entry, i, icon, character)
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", DS:GetCharacterClass(character) or "")) local locClass, engClass = DS:GetCharacterClass(character)
local className = Altoholic:GetCoAClassName(engClass) or locClass or "" -- CoA: current class name
_G[entry..i.."NameNormalText"]:SetText(icon .. format("%s (%s)", DS:GetColoredCharacterName(character) or "?", className))
_G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0)) _G[entry..i.."Level"]:SetText(GREEN .. (DS:GetCharacterLevel(character) or 0))
end end
+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.20 ## Version: 3.3.002b-coa.26
## 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
View File
@@ -98,6 +98,7 @@ local function AddRealm(AccountName, RealmName)
professions[#professions + 1] = { professions[#professions + 1] = {
name = p.name, name = p.name,
rank = p.rank or 0, rank = p.rank or 0,
maxRank = p.maxRank or 0, -- CoA: needed for the "rank/max" display in the vertical Skills list
spellID = DataStore:GetProfessionSpellID(p.name), spellID = DataStore:GetProfessionSpellID(p.name),
} }
end end
+20
View File
@@ -115,3 +115,23 @@ function Alto:GetCoAClassIcon(token)
if not tc then return end if not tc then return end
return COA_CLASS_ICON_TEXTURE, tc[1], tc[2], tc[3], tc[4] return COA_CLASS_ICON_TEXTURE, tc[1], tc[2], tc[3], tc[4]
end end
-- CoA renamed its classes, but UnitClass()/DataStore still return the OLD tokens
-- (PROPHET, MONK, …). Map them to the current display names. Source: coa-omen/README-CoA.md.
-- Tokens not listed here keep their normal localized name (returns nil).
local COA_CLASS_NAMES = {
HERO = "Hero", BARBARIAN = "Barbarian", WITCHDOCTOR = "Witch Doctor",
DEMONHUNTER = "Felsworn", WITCHHUNTER = "Witch Hunter", STORMBRINGER = "Stormbringer",
FLESHWARDEN = "Knight of Xoroth", GUARDIAN = "Guardian", MONK = "Templar",
SONOFARUGAL = "Bloodmage", RANGER = "Ranger", CHRONOMANCER = "Chronomancer",
NECROMANCER = "Necromancer", PYROMANCER = "Pyromancer", CULTIST = "Cultist",
STARCALLER = "Starcaller", SUNCLERIC = "Sun Cleric", TINKER = "Tinker",
PROPHET = "Venomancer", REAPER = "Reaper", WILDWALKER = "Primalist",
SPIRITMAGE = "Runemaster",
}
-- Current CoA display name for a class token, or nil if unmapped (caller falls back).
function Alto:GetCoAClassName(token)
if type(token) ~= "string" then return end
return COA_CLASS_NAMES[token]
end
+97 -382
View File
@@ -28,408 +28,122 @@ local Characters = addon.Characters
local size = 22 local size = 22
local inset = 2 local inset = 2
function ns:Update() function ns:Update()
local VisibleLines = 20 local VisibleLines = 20
local frame = "AltoholicFrameSkills" local frame = "AltoholicFrameSkills"
local entry = frame.."Entry" local entry = frame.."Entry"
local DS = DataStore local DS = DataStore
local offset = FauxScrollFrame_GetOffset( _G[ frame.."ScrollFrame" ] ); -- CoA: vertical list. For each visible character a header row, then one row per known
local DisplayedCount = 0 -- profession / secondary skill (icon + name + rank/max), top to bottom (like the other detail views).
local VisibleCount = 0 local SECONDARY = { 2550, 3273, 7733 } -- Cooking, First Aid, Fishing (spell id -> icon + GetSpellInfo name)
local DrawRealm local items = {}
local i=1 for _, viewLine in pairs(Characters:GetView()) do
if Characters:GetLineType(viewLine) == INFO_CHARACTER_LINE then
for _, line in pairs(Characters:GetView()) do local character = DS:GetCharacter( Characters:GetInfo(viewLine) )
local lineType = Characters:GetLineType(line) items[#items + 1] = { kind = "header", viewLine = viewLine, character = character }
if (offset > 0) or (DisplayedCount >= VisibleLines) then -- if the line will not be visible local profs = Characters:GetField(viewLine, "professions")
if lineType == INFO_REALM_LINE then -- then keep track of counters if profs then
if Characters:GetField(line, "isCollapsed") == false then for _, p in ipairs(profs) do
DrawRealm = true items[#items + 1] = { kind = "skill", viewLine = viewLine, character = character,
else spellID = p.spellID, name = p.name, rank = p.rank or 0, maxRank = p.maxRank or 0 }
DrawRealm = false
end end
VisibleCount = VisibleCount + 1
offset = offset - 1 -- no further control, nevermind if it goes negative
elseif DrawRealm then
VisibleCount = VisibleCount + 1
offset = offset - 1 -- no further control, nevermind if it goes negative
end end
else -- line will be displayed for _, sid in ipairs(SECONDARY) do
if lineType == INFO_REALM_LINE then local sName = GetSpellInfo(sid)
local _, realm, account = Characters:GetInfo(line) if sName then
local cur, max = DS:GetSkillInfo(character, sName)
if Characters:GetField(line, "isCollapsed") == false then if cur and cur > 0 then
_G[ entry..i.."Collapse" ]:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up"); items[#items + 1] = { kind = "skill", viewLine = viewLine, character = character,
DrawRealm = true spellID = sid, name = sName, rank = cur, maxRank = max or 0 }
else end
_G[ entry..i.."Collapse" ]:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
DrawRealm = false
end end
_G[entry..i.."Collapse"]:Show() end
_G[entry..i.."Name"]:SetWidth(300) local riding = Characters:GetField(viewLine, "riding") or 0
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 25, 0) if riding > 0 then
_G[entry..i.."NameNormalText"]:SetWidth(300) items[#items + 1] = { kind = "skill", viewLine = viewLine, character = character,
if account == "Default" then -- saved as default, display as localized. spellID = 33388, name = (L and L["Riding"]) or "Riding", rank = riding, maxRank = 300 }
_G[entry..i.."NameNormalText"]:SetText(format("%s (%s".. L["Account"]..": %s%s|r)", realm, WHITE, GREEN, L["Default"]))
else
local last = addon:GetLastAccountSharingInfo(realm, account)
_G[entry..i.."NameNormalText"]:SetText(format("%s (%s".. L["Account"]..": %s%s %s%s|r)", realm, WHITE, GREEN, account, YELLOW, last or ""))
end
_G[entry..i.."Level"]:SetText("")
_G[entry..i.."Skill1NormalText"]:SetText("")
_G[entry..i.."CookingNormalText"]:SetText("")
_G[entry..i.."FirstAidNormalText"]:SetText("")
_G[entry..i.."FishingNormalText"]:SetText("")
_G[entry..i.."RidingNormalText"]:SetText("")
_G[ entry..i ]:SetID(line)
_G[ entry..i ]:Show()
i = i + 1
VisibleCount = VisibleCount + 1
DisplayedCount = DisplayedCount + 1
elseif DrawRealm then
if (lineType == INFO_CHARACTER_LINE) then
local character = DS:GetCharacter( Characters:GetInfo(line) )
local icon
if DS:GetCharacterFaction(character) == "Alliance" then
-- icon = addon:TextureToFontstring(ICON_FACTION_ALLIANCE, size, size) .. " "
icon = addon:TextureToFontstring2(ICON_FACTION_ALLIANCE, size, size, inset, inset, inset, inset) .. " "
else
-- icon = addon:TextureToFontstring(ICON_FACTION_HORDE, size, size) .. " "
icon = addon:TextureToFontstring2(ICON_FACTION_HORDE, size, size, inset, inset, inset, inset) .. " "
end
_G[entry..i.."Collapse"]:Hide()
_G[entry..i.."Name"]:SetWidth(170)
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 10, 0)
_G[entry..i.."NameNormalText"]:SetWidth(170)
addon:SetCharacterRowNameLevel(entry, i, icon, character)
-- CoA: render ALL primary professions the character knows into the
-- single wide Professions cell, as a row of icon+rank segments.
-- The list is precomputed in Characters.lua (field "professions")
-- and may be empty (unscanned char) -> cell renders blank. Every
-- value is guarded with "or 0" before GetColor/concat.
local professions = Characters:GetField(line, "professions")
local profText = ""
if professions then
for idx, p in ipairs(professions) do
if idx > 6 then profText = profText .. YELLOW .. "+" .. (#professions - 6) .. "|r"; break end -- CoA: cap inline profs so the strip fits its 325px cell
local rank = p.rank or 0
local profIcon = ""
if p.spellID then
profIcon = addon:TextureToFontstring2(addon:GetSpellIcon(p.spellID), size, size, inset, inset, inset, inset) .. " "
end
profText = profText .. profIcon .. ns:GetColor(rank) .. rank .. "|r "
end
end
_G[entry..i.."Skill1NormalText"]:SetText(profText)
local field
-- cooking
-- icon = addon:TextureToFontstring(addon:GetSpellIcon(2550), size, size) .. " "
icon = addon:TextureToFontstring2(addon:GetSpellIcon(2550), size, size, inset, inset, inset, inset) .. " "
field = Characters:GetField(line, "cooking") or 0
_G[entry..i.."CookingNormalText"]:SetText(icon .. ns:GetColor(field) .. field)
-- first aid
-- icon = addon:TextureToFontstring(addon:GetSpellIcon(3273), size, size) .. " "
icon = addon:TextureToFontstring2(addon:GetSpellIcon(3273), size, size, inset, inset, inset, inset) .. " "
field = Characters:GetField(line, "firstaid") or 0
_G[entry..i.."FirstAidNormalText"]:SetText(icon .. ns:GetColor(field) .. field)
-- fishing
-- icon = addon:TextureToFontstring(addon:GetSpellIcon(7733), size, size) .. " "
icon = addon:TextureToFontstring2(addon:GetSpellIcon(7733), size, size, inset, inset, inset, inset) .. " "
field = Characters:GetField(line, "fishing") or 0
_G[entry..i.."FishingNormalText"]:SetText(icon .. ns:GetColor(field) .. field)
-- riding
field = Characters:GetField(line, "riding") or 0
if field >= 300 then
-- icon = addon:TextureToFontstring("Interface\\Icons\\Ability_Mount_Gryphon_01", size, size) .. " "
icon = addon:TextureToFontstring2("Interface\\Icons\\ability_mount_drake_bronze", size, size, inset, inset, inset, inset)
for _,spId in pairs({63956, 63963, 60024, 72808, 72807, 63796, 40192, 69395, 60021, 59976, 64927, 67336, 65439, 49193, 71810, 44317, 44744, 58615, 37015, 3363, 32345}) do
-- IsPetKnown(character, companionType, spellID)
if DS:IsPetKnown(character, "MOUNT", spId) then
icon = addon:TextureToFontstring2("Interface\\Icons\\inv_misc_enggizmos_03", size, size, inset, inset, inset, inset)
break
end
end
elseif field >= 225 then
icon = addon:TextureToFontstring2("Interface\\Icons\\ability_mount_goldengryphon", size, size, inset, inset, inset, inset)
elseif field >= 150 then
icon = addon:TextureToFontstring2("Interface\\Icons\\ability_mount_charger", size, size, inset, inset, inset, inset)
elseif field >= 75 then
icon = addon:TextureToFontstring2("Interface\\Icons\\spell_nature_swiftness", size, size, inset, inset, inset, inset)
else
icon = addon:TextureToFontstring2("Interface\\Icons\\inv_boots_03", size, size, inset, inset, inset, inset)
end
if DS:IsSpellKnown(character, 54197) then -- KNOWS [Cold Weather Flying]
-- Interface\Icons\Spell_Frost_FrostShock
-- icon = addon:TextureToFontstring(addon:GetSpellIcon(54197), size, size) .. " "
-- TextureToFontstringHalfSquare(name, side, inset, isRight)
-- icon = addon:TextureToFontstringHalfSquare(addon:GetSpellIcon(54197), size, inset, true) .. " "
-- icon = icon .. addon:TextureToFontstringHalfSquare(addon:GetSpellIcon(54197), size, inset, 0.7, 1.0) .. " "
-- TextureToFontstringCut(name, heightOrig, widthOrig, insetLeft, insetRight, insetTop, insetBottom)
-- local sTemp = size+2*inset
-- icon = icon .. addon:TextureToFontstringCut(addon:GetSpellIcon(54197), sTemp, sTemp, floor(0.7*sTemp), floor(0.1*sTemp), inset, inset) .. " "
icon = addon:TextureToFontstring(addon:GetSpellIcon(54197), size, size) .. " " .. icon .. " "
else -- DOES NOT KNOW [Cold Weather Flying]
icon = format("|T%s:%s:%s:0:0:%s:%s:%s:%s:%s:%s|t", addon:GetSpellIcon(54197), size, size, size, size, 0, 0, 0, 0) .. " " .. icon .. " "
end
_G[entry..i.."RidingNormalText"]:SetText(icon .. ns:GetColor(field, 300) .. field)
elseif (lineType == INFO_TOTAL_LINE) then
_G[entry..i.."Collapse"]:Hide()
_G[entry..i.."Name"]:SetWidth(200)
_G[entry..i.."Name"]:SetPoint("TOPLEFT", 15, 0)
_G[entry..i.."NameNormalText"]:SetWidth(200)
_G[entry..i.."NameNormalText"]:SetText(L["Totals"])
_G[entry..i.."Level"]:SetText(Characters:GetField(line, "level"))
_G[entry..i.."Skill1NormalText"]:SetText("")
_G[entry..i.."CookingNormalText"]:SetText("")
_G[entry..i.."FirstAidNormalText"]:SetText("")
_G[entry..i.."FishingNormalText"]:SetText("")
_G[entry..i.."RidingNormalText"]:SetText("")
end
_G[ entry..i ]:SetID(line)
_G[ entry..i ]:Show()
i = i + 1
VisibleCount = VisibleCount + 1
DisplayedCount = DisplayedCount + 1
end end
end end
end end
while i <= VisibleLines do
_G[ entry..i ]:SetID(0)
_G[ entry..i ]:Hide()
i = i + 1
end
FauxScrollFrame_Update( _G[ frame.."ScrollFrame" ], VisibleCount, VisibleLines, 18); local offset = FauxScrollFrame_GetOffset( _G[ frame.."ScrollFrame" ] )
end for i = 1, VisibleLines do
local e = entry..i
local btn = _G[e]
local item = items[i + offset]
if item then
_G[e.."Collapse"]:Hide()
_G[e.."Skill1NormalText"]:SetText("")
_G[e.."CookingNormalText"]:SetText("")
_G[e.."FirstAidNormalText"]:SetText("")
_G[e.."FishingNormalText"]:SetText("")
_G[e.."RidingNormalText"]:SetText("")
if item.kind == "header" then
-- character header: colored name + (class) across the row, no rank column
_G[e.."Name"]:SetPoint("TOPLEFT", 15, 0)
_G[e.."Name"]:SetWidth(420)
_G[e.."NameNormalText"]:SetWidth(420)
local locClass, engClass = DS:GetCharacterClass(item.character)
local className = Altoholic:GetCoAClassName(engClass) or locClass or "" -- CoA: PROPHET->Venomancer, MONK->Templar, …
_G[e.."NameNormalText"]:SetText( (DS:GetColoredCharacterName(item.character) or "?") .. " " .. WHITE .. "(" .. className .. ")" )
_G[e.."Level"]:SetText("")
else
-- profession row: [icon] name in the Name cell (indented), rank/max in its own column
local iconEsc = ""
if item.spellID then
iconEsc = addon:TextureToFontstring2(addon:GetSpellIcon(item.spellID), size, size, inset, inset, inset, inset) .. " "
end
_G[e.."Name"]:SetPoint("TOPLEFT", 38, 0)
_G[e.."Name"]:SetWidth(200)
_G[e.."NameNormalText"]:SetWidth(200)
_G[e.."NameNormalText"]:SetText( iconEsc .. WHITE .. item.name )
local cap = (item.maxRank > 0) and item.maxRank or 450
_G[e.."Level"]:SetPoint("TOPLEFT", 250, 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
btn.coaItem = item
btn:SetID(item.viewLine or 0)
btn:Show()
else
btn.coaItem = nil
btn:SetID(0)
btn:Hide()
end
end
FauxScrollFrame_Update( _G[ frame.."ScrollFrame" ], #items, VisibleLines, 18 )
end
function ns:OnEnter(frame) function ns:OnEnter(frame)
local line = frame:GetParent():GetID() local item = frame:GetParent() and frame:GetParent().coaItem
local lineType = Characters:GetLineType(line) if not item or item.kind ~= "skill" then return end
if lineType ~= INFO_CHARACTER_LINE then AltoTooltip:ClearLines()
return AltoTooltip:SetOwner(frame, "ANCHOR_RIGHT")
end AltoTooltip:AddLine(WHITE .. item.name, 1, 1, 1)
local cap = (item.maxRank > 0) and item.maxRank or 450
local id = frame:GetID() AltoTooltip:AddLine( ns:GetColor(item.rank, cap) .. item.rank .. " / " .. item.maxRank, 1, 1, 1 )
local skillName, rank, suggestion AltoTooltip:Show()
local DS = DataStore
local character = DS:GetCharacter(Characters:GetInfo(line))
-- CoA: id 1 is now the combined "Professions" cell -> list every known primary
-- profession with rank/max and recipe counts in a single tooltip.
if id == 1 then
local professions = Characters:GetField(line, "professions")
AltoTooltip:ClearLines()
AltoTooltip:SetOwner(frame, "ANCHOR_RIGHT")
AltoTooltip:AddLine(L["Professions"] or "Professions", 1, 1, 1)
if not professions or #professions == 0 then
AltoTooltip:AddLine(L["No data"])
AltoTooltip:Show()
return
end
for _, p in ipairs(professions) do
local pName = p.name
local curRank, maxRank = DS:GetSkillInfo(character, pName)
curRank, maxRank = curRank or 0, maxRank or 0
local rankText = ns:GetColor(curRank) .. curRank .. "/" .. maxRank
local recipeText = ""
local prof = DS:GetProfession(character, pName)
if prof and DS:GetNumCraftLines(prof) > 0 then
local orange, yellow, green, grey = DS:GetNumRecipesByColor(prof)
recipeText = WHITE .. " (" .. (orange + yellow + green + grey) .. " " .. TRADESKILL_SERVICE_LEARN .. ")"
end
-- localized display name where possible
local displayName = pName
local spellID = DS:GetProfessionSpellID(pName)
if spellID then
displayName = GetSpellInfo(spellID) or pName
end
AltoTooltip:AddDoubleLine(WHITE .. displayName, rankText .. recipeText)
end
AltoTooltip:Show()
return
end
if id == 3 then
skillName = GetSpellInfo(2550) -- cooking
elseif id == 4 then
skillName = GetSpellInfo(3273) -- First Aid
elseif id == 5 then
skillName = GetSpellInfo(24303) -- Fishing
elseif id == 6 then
skillName = L["Riding"]
end
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)
if (id >= 3) and (id <= 6) then
if id == 6 then -- riding
rank = ns:GetColor(curRank, 300) .. curRank .. "/" .. maxRank
else
rank = ns:GetColor(curRank) .. curRank .. "/" .. maxRank
end
suggestion = addon:GetSuggestion(skillName, curRank)
elseif id == 7 then -- class
local _, class = DS:GetCharacterClass(character)
if class ~= "ROGUE" then
return
end
skillName = L["Rogue Proficiencies"]
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
suggestion = addon:GetSuggestion(L["Lockpicking"], curLock)
end
AltoTooltip:ClearLines();
AltoTooltip:SetOwner(frame, "ANCHOR_RIGHT");
AltoTooltip:AddLine(skillName,1,1,1);
AltoTooltip:AddLine(GREEN..rank,1,1,1);
if (id == 3) or (id == 4) then -- crafting secondary skills (Cooking, First Aid); skips fishing/riding
if skillName ~= GetSpellInfo(13614) and skillName ~= GetSpellInfo(8613) then -- no display for herbalism & skinning
AltoTooltip:AddLine(" ");
if not profession then
AltoTooltip:AddLine(L["No data"]);
AltoTooltip:Show();
return
end
if DS:GetNumCraftLines(profession) == 0 then
AltoTooltip:AddLine(L["No data"].. ": 0 " .. TRADESKILL_SERVICE_LEARN,1,1,1);
else
local orange, yellow, green, grey = DS:GetNumRecipesByColor(profession)
AltoTooltip:AddLine(orange+yellow+green+grey .. " " .. TRADESKILL_SERVICE_LEARN,1,1,1);
AltoTooltip:AddLine(format(WHITE .. "%d " .. RECIPE_GREEN .. "Green|r /"
.. WHITE .. " %d " .. YELLOW .. "Yellow|r /"
.. WHITE .. " %d " .. RECIPE_ORANGE .. "Orange",
green, yellow, orange))
end
end
end
local skillCap = 450
if id == 6 then
skillCap = 300
end
AltoTooltip:AddLine(" ");
AltoTooltip:AddLine(RECIPE_GREY .. L["Grey"] .. "|r " .. L["up to"] .. " " .. (floor(skillCap*0.25)-1),1,1,1);
AltoTooltip:AddLine(RED .. RED_GEM .. "|r " .. L["up to"] .. " " .. (floor(skillCap*0.50)-1),1,1,1);
AltoTooltip:AddLine(ORANGE .. BI["Orange"] .. "|r " .. L["up to"] .. " " .. (floor(skillCap*0.75)-1),1,1,1);
AltoTooltip:AddLine(YELLOW .. YELLOW_GEM .. "|r " .. L["up to"] .. " " .. (skillCap-1),1,1,1);
AltoTooltip:AddLine(GREEN .. BI["Green"] .. "|r " .. L["at"] .. " "..skillCap.." " .. L["and above"],1,1,1);
if suggestion then
AltoTooltip:AddLine(" ",1,1,1);
AltoTooltip:AddLine(L["Suggestion"] .. ": ",1,1,1);
AltoTooltip:AddLine(TEAL .. suggestion,1,1,1);
end
-- parse profession cooldowns
if id ~= 7 and profession then
DS:ClearExpiredCooldowns(profession)
local numCooldows = DS:GetNumActiveCooldowns(profession)
if numCooldows == 0 then
AltoTooltip:AddLine(" ",1,1,1);
AltoTooltip:AddLine(L["All cooldowns are up"],1,1,1);
else
AltoTooltip:AddLine(" ",1,1,1);
for i = 1, numCooldows do
local craftName, expiresIn = DS:GetCraftCooldownInfo(profession, i)
AltoTooltip:AddDoubleLine(craftName, addon:GetTimeString(expiresIn));
end
end
end
AltoTooltip:Show();
end end
local VIEW_MOUNTS = 8
function ns:OnClick(frame, button) function ns:OnClick(frame, button)
local line = frame:GetParent():GetID() -- CoA: clicking a profession row opens that character's profession recipe list, if available.
local lineType = Characters:GetLineType(line) local item = frame:GetParent() and frame:GetParent().coaItem
if lineType ~= INFO_CHARACTER_LINE then if not item or item.kind ~= "skill" or not item.character then return end
return if addon.Tabs and addon.Tabs.Characters and addon.Tabs.Characters.ViewCharInfo then
end local name, realm, account = Characters:GetInfo(item.viewLine)
addon:SetCurrentCharacter(name, realm, account)
local id = frame:GetID() addon.Tabs.Characters:SetCurrent(name, realm, account)
if id == 5 then return end -- fishing ? do nothing addon.Tabs:OnClick(2)
addon:SetCurrentCharacter( Characters:GetInfo(line) )
local skillName
if id == 1 then
-- CoA: id 1 is the combined Professions cell. A single click can't pick one
-- of several professions, so default to the first known primary profession
-- (opens its recipes / supplies its trade link on shift-click).
local professions = Characters:GetField(line, "professions")
if professions and professions[1] then
skillName = professions[1].name
end
elseif id == 3 then
skillName = GetSpellInfo(2550) -- cooking
elseif id == 4 then
skillName = GetSpellInfo(3273) -- First Aid
end
local DS = DataStore
local character = DS:GetCharacter(Characters:GetInfo(line))
local profession = DS:GetProfession(character, skillName)
if skillName then
if not profession or DS:GetNumCraftLines(profession) == 0 then -- if profession hasn't been scanned (or scan failed), exit
return
end
end
local charName, realm, account = addon:GetCurrentCharacter()
local chat = ChatEdit_GetLastActiveWindow()
if chat:IsShown() and IsShiftKeyDown() and realm == GetRealmName() and id ~= 6 then
-- if shift-click, then display the profession link and exit
local link = profession.FullLink
if link and link:match("trade:") then
chat:Insert(link);
end
return
end
addon.Tabs.Characters:SetCurrent(charName, realm, account)
addon.Tabs:OnClick(2)
if id == 6 then
addon.Tabs.Characters:ViewCharInfo(VIEW_MOUNTS)
else
addon.Tabs.Characters:ViewRecipes(skillName)
end end
end end
local skillColors = { RECIPE_GREY, RED, ORANGE, YELLOW, GREEN } local skillColors = { RECIPE_GREY, RED, ORANGE, YELLOW, GREEN }
function ns:GetColor(rank, skillCap) function ns:GetColor(rank, skillCap)
@@ -443,3 +157,4 @@ function ns:GetColor(rank, skillCap)
if index > #skillColors then index = #skillColors end if index > #skillColors then index = #skillColors end
return skillColors[index] return skillColors[index]
end end
+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">
+2 -46
View File
@@ -245,8 +245,8 @@
</Button> </Button>
<Button name="$parent_Prof1" inherits="AltoViewIconTemplate"> <Button name="$parent_Prof1" inherits="AltoViewIconTemplate">
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="AltoholicTabCharacters" relativePoint="TOPLEFT" > <Anchor point="BOTTOMLEFT" relativeTo="$parent_FirstAid" relativePoint="BOTTOMRIGHT" >
<Offset x="30" y="-235" /> <Offset x="5" y="0" />
</Anchor> </Anchor>
</Anchors> </Anchors>
</Button> </Button>
@@ -257,50 +257,6 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
</Button> </Button>
<!-- CoA: characters can know many more than 2 primary professions. Extra slots;
UpdateViewIcons fills/hides them dynamically and stops at the last one. -->
<Button name="$parent_Prof3" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof2" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Prof4" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof3" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Prof5" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent_Prof1" relativePoint="BOTTOMLEFT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Prof6" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof5" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Prof7" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof6" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Prof8" inherits="AltoViewIconTemplate" hidden="true">
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parent_Prof7" relativePoint="BOTTOMRIGHT" >
<Offset x="5" y="0" />
</Anchor>
</Anchors>
</Button>
<Button name="$parent_Sort1" inherits="AltoSortButtonTemplate" id="1"> <Button name="$parent_Sort1" inherits="AltoSortButtonTemplate" id="1">
<Size> <Size>
+5 -14
View File
@@ -158,20 +158,11 @@ function ns:SetMode(mode)
Columns:Add(L["free"], 50, function(self) addon.Characters:Sort(self, "GetNumFreeBankSlots") end) Columns:Add(L["free"], 50, function(self) addon.Characters:Sort(self, "GetNumFreeBankSlots") end)
elseif currentMode == 3 then elseif currentMode == 3 then
Columns:Add(NAME, 100, function(self) addon.Characters:Sort(self, "GetCharacterName") end) -- CoA: the Skills view is now a vertical list (character header, then one row per
Columns:Add(LEVEL, 60, function(self) addon.Characters:Sort(self, "GetCharacterLevel") end) -- known profession/secondary skill, top to bottom). A single wide column header
-- CoA: a character can know ALL professions at once, so the old fixed -- replaces the old per-skill columns, which no longer match the layout.
-- Prof. 1 / Prof. 2 columns are replaced by one wide "Professions" column Columns:Add((L["Character"] or "Character") .. " / " .. (L["Professions"] or "Professions"), 460, function(self) addon.Characters:Sort(self, "GetCharacterName") end)
-- that lists every known primary profession (incl. the customs Woodcutting Columns:Add((SKILL or "Skill"), 220, function(self) addon.Characters:Sort(self, "GetCharacterName") end)
-- and Woodworking). Width matches the widened Skill1 cell in Skills.xml.
Columns:Add(L["Professions"] or "Professions", 325, function(self) addon.Characters:Sort(self, "GetCharacterName") end)
title = GetSpellInfo(2550) -- cooking
Columns:Add(title, 65, function(self) addon.Characters:Sort(self, "GetCookingRank") end)
title = GetSpellInfo(3273) -- First Aid
Columns:Add(title, 65, function(self) addon.Characters:Sort(self, "GetFirstAidRank") end)
title = GetSpellInfo(24303) -- Fishing
Columns:Add(title, 65, function(self) addon.Characters:Sort(self, "GetFishingRank") end)
Columns:Add(L["Riding"], 65, function(self) addon.Characters:Sort(self, "GetRidingRank") end)
elseif currentMode == 4 then elseif currentMode == 4 then
Columns:Add(NAME, 100, function(self) addon.Characters:Sort(self, "GetCharacterName") end) Columns:Add(NAME, 100, function(self) addon.Characters:Sort(self, "GetCharacterName") end)