mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-22 15:46:59 +00:00
904 lines
29 KiB
Lua
904 lines
29 KiB
Lua
if type(MTH_HUNTERBOOK_TABS) ~= "table" then MTH_HUNTERBOOK_TABS = {} end
|
|
|
|
MTH_HUNTERBOOK_TABS.petabilities = {
|
|
headerLabel = "Pet Abilities",
|
|
columnLabels = { "Ability Name", "Ranks", "Families" },
|
|
columnLayout = {
|
|
{ x = 8, width = 160, align = "LEFT" },
|
|
{ x = 170, width = 52, align = "LEFT" },
|
|
{ x = 224, width = 328, align = "LEFT" },
|
|
},
|
|
}
|
|
|
|
MTH_HUNTERBOOK_TABS.abilities = {
|
|
headerLabel = "Pet Abilities",
|
|
columnLabels = { "Ability", "Lvl", "Family", "Beast", "Rare" },
|
|
columnLayout = {
|
|
{ x = 8, width = 112, align = "LEFT" },
|
|
{ x = 120, width = 40, align = "LEFT" },
|
|
{ x = 160, width = 78, align = "LEFT" },
|
|
{ x = 238, width = 142, align = "LEFT" },
|
|
{ x = 380, width = 38, align = "LEFT" },
|
|
},
|
|
}
|
|
|
|
function MTH_BOOK_AbilitySort(a, b)
|
|
if a.ability ~= b.ability then return a.ability < b.ability end
|
|
if a.level ~= b.level then return a.level < b.level end
|
|
if a.name ~= b.name then return a.name < b.name end
|
|
return a.beastId < b.beastId
|
|
end
|
|
|
|
function MTH_BOOK_PetAbilitySort(a, b)
|
|
local aa = MTH_BOOK_SafeLower(a and a.ability)
|
|
local ab = MTH_BOOK_SafeLower(b and b.ability)
|
|
if aa ~= ab then return aa < ab end
|
|
local ra = tonumber(a and a.rankCount) or 0
|
|
local rb = tonumber(b and b.rankCount) or 0
|
|
if ra ~= rb then return ra > rb end
|
|
local fa = tonumber(a and a.familyCount) or 0
|
|
local fb = tonumber(b and b.familyCount) or 0
|
|
if fa ~= fb then return fa > fb end
|
|
return tostring(a and a.familyList or "") < tostring(b and b.familyList or "")
|
|
end
|
|
|
|
function MTH_BOOK_GetSpellRowsForAbility(abilityName)
|
|
if not abilityName or abilityName == "" then return 0 end
|
|
if not (MTH_DS_PetSpells and MTH_DS_PetSpells.byAbility) then return 0 end
|
|
local row = MTH_DS_PetSpells.byAbility[abilityName]
|
|
if not row or not row.spells then return 0 end
|
|
return table.getn(row.spells)
|
|
end
|
|
|
|
function MTH_BOOK_GetSpellCoverageForAbility(abilityName)
|
|
local coverage = {
|
|
ability = abilityName,
|
|
icon = nil,
|
|
spellRows = 0,
|
|
hasBeastLearned = false,
|
|
hasTrainerLearned = false,
|
|
rankCount = 0,
|
|
minRank = nil,
|
|
maxRank = nil,
|
|
minTrainLevel = nil,
|
|
maxTrainLevel = nil,
|
|
}
|
|
|
|
if not abilityName or abilityName == "" then return coverage end
|
|
if not (MTH_DS_PetSpells and MTH_DS_PetSpells.byAbility) then return coverage end
|
|
|
|
local row = MTH_DS_PetSpells.byAbility[abilityName]
|
|
if not row or not row.spells then return coverage end
|
|
|
|
local rankMap = {}
|
|
local hasPositiveRank = false
|
|
for i = 1, table.getn(row.spells) do
|
|
local spell = row.spells[i]
|
|
if spell then
|
|
local rankNumber = tonumber(spell.rankNumber)
|
|
if rankNumber and rankNumber > 0 then
|
|
hasPositiveRank = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
coverage.spellRows = 0
|
|
for i = 1, table.getn(row.spells) do
|
|
local spell = row.spells[i]
|
|
if spell then
|
|
local rankNumber = tonumber(spell.rankNumber)
|
|
if hasPositiveRank and ((not rankNumber) or rankNumber <= 0) then
|
|
-- Ignore legacy/unranked rows when proper ranked variants exist.
|
|
else
|
|
coverage.spellRows = coverage.spellRows + 1
|
|
local learnMethod = MTH_BOOK_SafeLower(spell.learnMethod)
|
|
if learnMethod == "trainer" then
|
|
coverage.hasTrainerLearned = true
|
|
else
|
|
coverage.hasBeastLearned = true
|
|
end
|
|
if not coverage.icon and spell.icon and spell.icon ~= "" then
|
|
coverage.icon = spell.icon
|
|
end
|
|
if rankNumber and rankNumber > 0 then
|
|
rankMap[rankNumber] = true
|
|
if not coverage.minRank or rankNumber < coverage.minRank then coverage.minRank = rankNumber end
|
|
if not coverage.maxRank or rankNumber > coverage.maxRank then coverage.maxRank = rankNumber end
|
|
end
|
|
|
|
local trainLevel = tonumber(spell.trainLevel)
|
|
if trainLevel then
|
|
if not coverage.minTrainLevel or trainLevel < coverage.minTrainLevel then coverage.minTrainLevel = trainLevel end
|
|
if not coverage.maxTrainLevel or trainLevel > coverage.maxTrainLevel then coverage.maxTrainLevel = trainLevel end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for _ in pairs(rankMap) do
|
|
coverage.rankCount = coverage.rankCount + 1
|
|
end
|
|
if coverage.rankCount == 0 and coverage.spellRows > 0 then
|
|
coverage.rankCount = 1
|
|
end
|
|
|
|
return coverage
|
|
end
|
|
|
|
function MTH_BOOK_GetKnownSpellMap()
|
|
if not MTH_CharSavedVariables then return nil end
|
|
if not MTH_CharSavedVariables.petTraining then return nil end
|
|
local petTraining = MTH_CharSavedVariables.petTraining
|
|
if petTraining.hunterKnownMap and petTraining.spellMap then
|
|
for token, isKnown in pairs(petTraining.hunterKnownMap) do
|
|
if isKnown == true then
|
|
local _, _, baseToken = string.find(tostring(token), "^(.-)#%d+$")
|
|
if baseToken and baseToken ~= "" then
|
|
local baseRow = petTraining.spellMap[baseToken]
|
|
if baseRow and ((tonumber(baseRow.rankNumber) or 0) <= 0) then
|
|
baseRow.isKnown = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return MTH_CharSavedVariables.petTraining.spellMap
|
|
end
|
|
|
|
function MTH_BOOK_GetKnownRankCountForAbility(abilityName)
|
|
local spellMap = MTH_BOOK_GetKnownSpellMap()
|
|
if not spellMap or not abilityName or abilityName == "" then return 0 end
|
|
|
|
local abilityLower = MTH_BOOK_SafeLower(abilityName)
|
|
if abilityLower == "" then return 0 end
|
|
|
|
local knownRanks = {}
|
|
for _, row in pairs(spellMap) do
|
|
if row and row.name and (row.isKnown ~= false) then
|
|
if MTH_BOOK_SafeLower(row.name) == abilityLower then
|
|
local rankNumber = tonumber(row.rankNumber) or 0
|
|
knownRanks[rankNumber] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
local count = 0
|
|
for _ in pairs(knownRanks) do
|
|
count = count + 1
|
|
end
|
|
return count
|
|
end
|
|
|
|
function MTH_BOOK_IsKnownRankForAbility(abilityName, rankNumber)
|
|
local spellMap = MTH_BOOK_GetKnownSpellMap()
|
|
if not spellMap then return false end
|
|
if not abilityName or abilityName == "" then return false end
|
|
local rankValue = tonumber(rankNumber)
|
|
|
|
local abilityLower = MTH_BOOK_SafeLower(abilityName)
|
|
for _, row in pairs(spellMap) do
|
|
if row and row.name and (row.isKnown ~= false) then
|
|
if MTH_BOOK_SafeLower(row.name) == abilityLower then
|
|
local rowRank = tonumber(row.rankNumber)
|
|
if rankValue and rankValue > 0 then
|
|
if rowRank == rankValue then
|
|
return true
|
|
end
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function MTH_BOOK_BuildPetAbilitiesRows(ignoreSearch)
|
|
local spellRows = {}
|
|
|
|
if MTH_DS_PetSpells and MTH_DS_PetSpells.byAbility then
|
|
for abilityName in pairs(MTH_DS_PetSpells.byAbility) do
|
|
local ability = tostring(abilityName or "")
|
|
if ability ~= "" then
|
|
local key = MTH_BOOK_SafeLower(ability)
|
|
if key ~= "" then
|
|
spellRows[key] = {
|
|
ability = ability,
|
|
familiesMap = {},
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ensureRow(abilityName)
|
|
local ability = tostring(abilityName or "")
|
|
if ability == "" then return nil end
|
|
local key = MTH_BOOK_SafeLower(ability)
|
|
if key == "" then return nil end
|
|
return spellRows[key], key
|
|
end
|
|
|
|
if MTH_DS_Families then
|
|
for familyName, row in pairs(MTH_DS_Families) do
|
|
if familyName and familyName ~= "" and row and row.abilities then
|
|
for i = 1, table.getn(row.abilities) do
|
|
local ability = row.abilities[i]
|
|
local spellRow = ensureRow(ability)
|
|
if spellRow then
|
|
spellRow.familiesMap[familyName] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if MTH_DS_Beasts then
|
|
for _, beast in pairs(MTH_DS_Beasts) do
|
|
if beast and beast.family and beast.family ~= "" then
|
|
local tokens = MTH_BOOK_SplitAbilities(beast.abilities)
|
|
for i = 1, table.getn(tokens) do
|
|
local _, abilityName = MTH_BOOK_ParseAbilityToken(tokens[i])
|
|
local spellRow = ensureRow(abilityName)
|
|
if spellRow then
|
|
spellRow.familiesMap[beast.family] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local results = {}
|
|
for _, row in pairs(spellRows) do
|
|
local coverage = MTH_BOOK_GetSpellCoverageForAbility(row.ability)
|
|
local families = {}
|
|
for familyName in pairs(row.familiesMap or {}) do
|
|
table.insert(families, familyName)
|
|
end
|
|
table.sort(families, function(a, b)
|
|
return MTH_BOOK_SafeLower(a) < MTH_BOOK_SafeLower(b)
|
|
end)
|
|
|
|
local rankCount = tonumber(coverage.rankCount) or 0
|
|
local knownRankCount = MTH_BOOK_GetKnownRankCountForAbility(row.ability)
|
|
local minRank = coverage.minRank
|
|
local maxRank = coverage.maxRank
|
|
local minTrainLevel = coverage.minTrainLevel
|
|
local maxTrainLevel = coverage.maxTrainLevel
|
|
if MTH_BOOK_STATE.petOnlyMyLevel then
|
|
knownRankCount, rankCount, minRank, maxRank, minTrainLevel, maxTrainLevel = MTH_BOOK_GetScopedRankSummary(row.ability)
|
|
end
|
|
if knownRankCount > rankCount then knownRankCount = rankCount end
|
|
local rankText = tostring(knownRankCount) .. "/" .. tostring(rankCount)
|
|
|
|
local sourceFilter = tostring(MTH_BOOK_STATE.petLearnSource or "all")
|
|
local sourceMatch = true
|
|
if sourceFilter == "beast" then
|
|
sourceMatch = coverage.hasBeastLearned and true or false
|
|
elseif sourceFilter == "trainer" then
|
|
sourceMatch = coverage.hasTrainerLearned and true or false
|
|
end
|
|
|
|
local familyList = table.concat(families, ", ")
|
|
local searchable = MTH_BOOK_SafeLower(tostring(row.ability or "") .. " " .. familyList)
|
|
if sourceMatch and rankCount > 0 and (ignoreSearch or MTH_BOOK_STATE.search == "" or string.find(searchable, MTH_BOOK_STATE.search, 1, true) ~= nil) then
|
|
table.insert(results, {
|
|
ability = row.ability,
|
|
icon = coverage.icon,
|
|
knownRankCount = knownRankCount,
|
|
rankCount = rankCount,
|
|
rankText = rankText,
|
|
families = families,
|
|
familyCount = table.getn(families),
|
|
familyList = familyList,
|
|
spellRows = coverage.spellRows or 0,
|
|
minRank = minRank,
|
|
maxRank = maxRank,
|
|
minTrainLevel = minTrainLevel,
|
|
maxTrainLevel = maxTrainLevel,
|
|
hasBeastLearned = coverage.hasBeastLearned,
|
|
hasTrainerLearned = coverage.hasTrainerLearned,
|
|
})
|
|
end
|
|
end
|
|
|
|
table.sort(results, MTH_BOOK_PetAbilitySort)
|
|
return results
|
|
end
|
|
|
|
function MTH_BOOK_BuildPetAbilityRankRows(entry)
|
|
local rows = {}
|
|
if not entry or not entry.ability then return rows end
|
|
if not (MTH_DS_PetSpells and MTH_DS_PetSpells.byAbility) then return rows end
|
|
|
|
local spellBucket = MTH_DS_PetSpells.byAbility[entry.ability]
|
|
if not spellBucket or not spellBucket.spells then return rows end
|
|
|
|
local hasPositiveRank = false
|
|
for i = 1, table.getn(spellBucket.spells) do
|
|
local spell = spellBucket.spells[i]
|
|
if spell then
|
|
local rankNumber = tonumber(spell.rankNumber)
|
|
if rankNumber and rankNumber > 0 then
|
|
hasPositiveRank = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
for i = 1, table.getn(spellBucket.spells) do
|
|
local spell = spellBucket.spells[i]
|
|
if spell then
|
|
local rankNumber = tonumber(spell.rankNumber)
|
|
if not rankNumber and spell.rank then
|
|
local _, _, parsed = string.find(tostring(spell.rank), "(%d+)")
|
|
rankNumber = tonumber(parsed)
|
|
end
|
|
if hasPositiveRank and ((not rankNumber) or rankNumber <= 0) then
|
|
-- Ignore legacy/unranked rows when proper ranked variants exist.
|
|
elseif MTH_BOOK_IsSpellInLevelScope(tonumber(spell.trainLevel)) then
|
|
table.insert(rows, {
|
|
id = spell.id,
|
|
ability = entry.ability,
|
|
icon = spell.icon or spell.iconName or spell.texture or spell.iconTexture or entry.icon,
|
|
rankNumber = rankNumber,
|
|
isKnown = MTH_BOOK_IsKnownRankForAbility(entry.ability, rankNumber),
|
|
trainLevel = tonumber(spell.trainLevel),
|
|
description = spell.description,
|
|
cost = spell.cost,
|
|
castTime = spell.castTime,
|
|
range = spell.range,
|
|
school = spell.school,
|
|
effects = spell.effects,
|
|
sourceUrl = spell.sourceUrl,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
table.sort(rows, function(a, b)
|
|
local ra = a.rankNumber or 0
|
|
local rb = b.rankNumber or 0
|
|
if ra ~= rb then return ra < rb end
|
|
local la = a.trainLevel or 0
|
|
local lb = b.trainLevel or 0
|
|
if la ~= lb then return la < lb end
|
|
return (tonumber(a.id) or 0) < (tonumber(b.id) or 0)
|
|
end)
|
|
|
|
return rows
|
|
end
|
|
|
|
function MTH_BOOK_GetRankLabel(rankNumber, includePrefix)
|
|
local rankValue = tonumber(rankNumber)
|
|
if rankValue and rankValue > 0 then
|
|
if includePrefix then
|
|
return "Rank " .. tostring(rankValue)
|
|
end
|
|
return tostring(rankValue)
|
|
end
|
|
if includePrefix then
|
|
return "Unranked"
|
|
end
|
|
return "None"
|
|
end
|
|
|
|
function MTH_BOOKTAB_EnsurePetAbilitiesUI(listParent, detailParent)
|
|
if MTH_BOOK_STATE.petUI then return end
|
|
if not listParent or not detailParent then return end
|
|
|
|
local ui = {}
|
|
|
|
ui.leftPane = CreateFrame("Frame", nil, listParent)
|
|
ui.leftPane:SetPoint("TOPLEFT", listParent, "TOPLEFT", 4, -4)
|
|
ui.leftPane:SetWidth(162)
|
|
ui.leftPane:SetHeight(346)
|
|
|
|
ui.rightPane = CreateFrame("Frame", nil, listParent)
|
|
ui.rightPane:SetPoint("TOPLEFT", ui.leftPane, "TOPRIGHT", 8, 0)
|
|
ui.rightPane:SetWidth(390)
|
|
ui.rightPane:SetHeight(346)
|
|
|
|
ui.vSplit = listParent:CreateTexture(nil, "BORDER")
|
|
ui.vSplit:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
ui.vSplit:SetVertexColor(0.30, 0.30, 0.30, 0.60)
|
|
ui.vSplit:SetPoint("TOPLEFT", ui.leftPane, "TOPRIGHT", 4, -2)
|
|
ui.vSplit:SetPoint("BOTTOMLEFT", ui.leftPane, "BOTTOMRIGHT", 4, 2)
|
|
ui.vSplit:SetWidth(1)
|
|
|
|
ui.leftHeaderAbility = ui.leftPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.leftHeaderAbility:SetPoint("TOPLEFT", ui.leftPane, "TOPLEFT", 24, -6)
|
|
ui.leftHeaderAbility:SetWidth(102)
|
|
ui.leftHeaderAbility:SetJustifyH("LEFT")
|
|
ui.leftHeaderAbility:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.leftHeaderAbility:SetText("Ability")
|
|
|
|
ui.leftHeaderRank = ui.leftPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.leftHeaderRank:SetPoint("TOPLEFT", ui.leftPane, "TOPLEFT", 126, -6)
|
|
ui.leftHeaderRank:SetWidth(28)
|
|
ui.leftHeaderRank:SetJustifyH("LEFT")
|
|
ui.leftHeaderRank:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.leftHeaderRank:SetText("K/T")
|
|
|
|
ui.rightHeaderRank = ui.rightPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.rightHeaderRank:SetPoint("TOPLEFT", ui.rightPane, "TOPLEFT", 2, -6)
|
|
ui.rightHeaderRank:SetWidth(36)
|
|
ui.rightHeaderRank:SetJustifyH("LEFT")
|
|
ui.rightHeaderRank:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.rightHeaderRank:SetText("Rank")
|
|
|
|
ui.rightHeaderLevel = ui.rightPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.rightHeaderKnown = ui.rightPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.rightHeaderKnown:SetPoint("TOPLEFT", ui.rightPane, "TOPLEFT", 34, -6)
|
|
ui.rightHeaderKnown:SetWidth(22)
|
|
ui.rightHeaderKnown:SetJustifyH("LEFT")
|
|
ui.rightHeaderKnown:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.rightHeaderKnown:SetText("K?")
|
|
|
|
ui.rightHeaderLevel:SetPoint("TOPLEFT", ui.rightPane, "TOPLEFT", 58, -6)
|
|
ui.rightHeaderLevel:SetWidth(40)
|
|
ui.rightHeaderLevel:SetJustifyH("LEFT")
|
|
ui.rightHeaderLevel:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.rightHeaderLevel:SetText("Lvl")
|
|
|
|
ui.rightHeaderDesc = ui.rightPane:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.rightHeaderDesc:SetPoint("TOPLEFT", ui.rightPane, "TOPLEFT", 98, -6)
|
|
ui.rightHeaderDesc:SetWidth(286)
|
|
ui.rightHeaderDesc:SetJustifyH("LEFT")
|
|
ui.rightHeaderDesc:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.rightHeaderDesc:SetText("Description")
|
|
|
|
ui.leftRowsVisible = 20
|
|
|
|
ui.leftScroll = CreateFrame("Slider", "MTH_BOOK_PetLeftScroll", ui.leftPane, "UIPanelScrollBarTemplate")
|
|
ui.leftScroll:SetPoint("TOPRIGHT", ui.leftPane, "TOPRIGHT", -2, -22)
|
|
ui.leftScroll:SetPoint("BOTTOMRIGHT", ui.leftPane, "BOTTOMRIGHT", -2, 20)
|
|
ui.leftScroll:SetWidth(16)
|
|
if not getglobal("MTH_BOOK_PetLeftScrollScrollFrame") then
|
|
local leftScrollShim = CreateFrame("ScrollFrame", "MTH_BOOK_PetLeftScrollScrollFrame", ui.leftPane)
|
|
leftScrollShim:SetPoint("TOPLEFT", ui.leftPane, "TOPLEFT", 0, 0)
|
|
leftScrollShim:SetWidth(1)
|
|
leftScrollShim:SetHeight(1)
|
|
leftScrollShim:Hide()
|
|
end
|
|
ui.leftScroll:SetScript("OnValueChanged", function()
|
|
local val = this:GetValue() or 0
|
|
val = math.floor(val + 0.5)
|
|
if val ~= MTH_BOOK_STATE.petLeftOffset then
|
|
MTH_BOOK_STATE.petLeftOffset = val
|
|
MTH_BOOK_UpdatePetAbilitiesLists()
|
|
end
|
|
end)
|
|
ui.leftScroll:SetMinMaxValues(0, 0)
|
|
ui.leftScroll:SetValueStep(1)
|
|
ui.leftScroll:SetValue(0)
|
|
|
|
ui.leftPane:EnableMouseWheel(true)
|
|
ui.leftPane:SetScript("OnMouseWheel", function()
|
|
local delta = arg1 or 0
|
|
if delta == 0 then return end
|
|
local current = tonumber(MTH_BOOK_STATE.petLeftOffset or 0) or 0
|
|
if delta < 0 then
|
|
current = current + 1
|
|
else
|
|
current = current - 1
|
|
end
|
|
if current < 0 then current = 0 end
|
|
local maxOffset = 0
|
|
if MTH_BOOK_STATE.results then
|
|
maxOffset = math.max(0, table.getn(MTH_BOOK_STATE.results) - table.getn(ui.leftButtons or {}))
|
|
end
|
|
if current > maxOffset then current = maxOffset end
|
|
MTH_BOOK_STATE.petLeftOffset = current
|
|
if ui.leftScroll then
|
|
ui.leftScroll:SetValue(current)
|
|
end
|
|
MTH_BOOK_UpdatePetAbilitiesLists()
|
|
end)
|
|
|
|
ui.leftButtons = {}
|
|
local leftY = -24
|
|
for i = 1, ui.leftRowsVisible do
|
|
local btn = CreateFrame("Button", nil, ui.leftPane)
|
|
btn:SetPoint("TOPLEFT", ui.leftPane, "TOPLEFT", 0, leftY)
|
|
btn:SetWidth(144)
|
|
btn:SetHeight(19)
|
|
btn.entry = nil
|
|
|
|
btn.selected = btn:CreateTexture(nil, "BACKGROUND")
|
|
btn.selected:SetAllPoints(btn)
|
|
btn.selected:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
btn.selected:SetVertexColor(0.18, 0.35, 0.55, 0.35)
|
|
btn.selected:Hide()
|
|
|
|
local hl = btn:CreateTexture(nil, "HIGHLIGHT")
|
|
hl:SetAllPoints(btn)
|
|
hl:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
hl:SetBlendMode("ADD")
|
|
hl:SetAlpha(0.30)
|
|
|
|
btn.ability = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
|
btn.ability:SetPoint("LEFT", btn, "LEFT", 24, 0)
|
|
btn.ability:SetWidth(100)
|
|
btn.ability:SetJustifyH("LEFT")
|
|
|
|
btn.rank = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
|
btn.rank:SetPoint("LEFT", btn, "LEFT", 126, 0)
|
|
btn.rank:SetWidth(26)
|
|
btn.rank:SetJustifyH("LEFT")
|
|
|
|
btn.icon = btn:CreateTexture(nil, "ARTWORK")
|
|
btn.icon:SetPoint("LEFT", btn, "LEFT", 2, 0)
|
|
btn.icon:SetWidth(16)
|
|
btn.icon:SetHeight(16)
|
|
|
|
btn:SetScript("OnClick", function()
|
|
if not this.entry then return end
|
|
MTH_BOOK_STATE.selectedEntry = this.entry
|
|
MTH_BOOK_STATE.selectedPetRankEntry = nil
|
|
MTH_BOOK_STATE.petRankRows = MTH_BOOK_BuildPetAbilityRankRows(this.entry)
|
|
MTH_BOOK_UpdateResults()
|
|
end)
|
|
btn:SetScript("OnEnter", function()
|
|
if this and this.entry then
|
|
MTH_BOOK_ShowBaselineTooltip(this, this.entry)
|
|
end
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
MTH_BOOK_HideSpellTooltip()
|
|
end)
|
|
|
|
ui.leftButtons[i] = btn
|
|
leftY = leftY - 20
|
|
end
|
|
|
|
local footerParent = listParent:GetParent() or listParent
|
|
ui.recapText = footerParent:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.recapText:SetPoint("TOPLEFT", footerParent, "TOPLEFT", 20, -530)
|
|
ui.recapText:SetWidth(190)
|
|
ui.recapText:SetJustifyH("LEFT")
|
|
ui.recapText:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.recapText:SetText("Abilities 0 | Known 0/0")
|
|
|
|
ui.progressBackdrop = CreateFrame("Frame", nil, footerParent)
|
|
ui.progressBackdrop:SetPoint("LEFT", ui.recapText, "RIGHT", 8, 0)
|
|
ui.progressBackdrop:SetWidth(320)
|
|
ui.progressBackdrop:SetHeight(14)
|
|
ui.progressBackdrop:SetFrameLevel(footerParent:GetFrameLevel() + 3)
|
|
ui.progressBackdrop:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true,
|
|
tileSize = 8,
|
|
edgeSize = 8,
|
|
insets = { left = 2, right = 2, top = 2, bottom = 2 },
|
|
})
|
|
ui.progressBackdrop:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
|
|
ui.progressBackdrop:SetBackdropBorderColor(0.24, 0.24, 0.24, 0.90)
|
|
|
|
ui.progressBar = CreateFrame("StatusBar", nil, ui.progressBackdrop)
|
|
ui.progressBar:SetPoint("TOPLEFT", ui.progressBackdrop, "TOPLEFT", 2, -2)
|
|
ui.progressBar:SetPoint("BOTTOMRIGHT", ui.progressBackdrop, "BOTTOMRIGHT", -2, 2)
|
|
ui.progressBar:SetStatusBarTexture("Interface\\Buttons\\WHITE8X8")
|
|
ui.progressBar:SetStatusBarColor(0.18, 0.75, 0.22, 0.9)
|
|
ui.progressBar:SetMinMaxValues(0, 1)
|
|
ui.progressBar:SetValue(0)
|
|
|
|
ui.progressText = ui.progressBackdrop:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
ui.progressText:SetPoint("CENTER", ui.progressBackdrop, "CENTER", 0, 0)
|
|
ui.progressText:SetTextColor(1.00, 1.00, 1.00)
|
|
ui.progressText:SetText("0%")
|
|
|
|
ui.rightButtons = {}
|
|
local rightRowsVisible = 10
|
|
local rightRowHeight = 36
|
|
local rightRowStep = 37
|
|
local rightY = -24
|
|
for i = 1, rightRowsVisible do
|
|
local btn = CreateFrame("Button", nil, ui.rightPane)
|
|
btn:SetPoint("TOPLEFT", ui.rightPane, "TOPLEFT", 0, rightY)
|
|
btn:SetWidth(388)
|
|
btn:SetHeight(rightRowHeight)
|
|
btn.entry = nil
|
|
|
|
btn.selected = btn:CreateTexture(nil, "BACKGROUND")
|
|
btn.selected:SetAllPoints(btn)
|
|
btn.selected:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
btn.selected:SetVertexColor(0.18, 0.35, 0.55, 0.35)
|
|
btn.selected:Hide()
|
|
|
|
local hl = btn:CreateTexture(nil, "HIGHLIGHT")
|
|
hl:SetAllPoints(btn)
|
|
hl:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
hl:SetBlendMode("ADD")
|
|
hl:SetAlpha(0.28)
|
|
|
|
btn.rank = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
|
btn.rank:SetPoint("LEFT", btn, "LEFT", 2, 1)
|
|
btn.rank:SetWidth(30)
|
|
btn.rank:SetJustifyH("LEFT")
|
|
|
|
btn.knownIcon = btn:CreateTexture(nil, "ARTWORK")
|
|
btn.knownIcon:SetPoint("LEFT", btn, "LEFT", 38, 1)
|
|
btn.knownIcon:SetWidth(12)
|
|
btn.knownIcon:SetHeight(12)
|
|
btn.knownIcon:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
btn.knownIcon:SetVertexColor(0.18, 0.90, 0.18, 1.00)
|
|
btn.knownIcon:Hide()
|
|
|
|
btn.level = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
|
btn.level:SetPoint("LEFT", btn, "LEFT", 58, 1)
|
|
btn.level:SetWidth(40)
|
|
btn.level:SetJustifyH("LEFT")
|
|
|
|
btn.desc = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
|
btn.desc:SetPoint("LEFT", btn, "LEFT", 98, 1)
|
|
btn.desc:SetWidth(286)
|
|
btn.desc:SetJustifyH("LEFT")
|
|
|
|
btn:SetScript("OnClick", function()
|
|
if not this.entry then return end
|
|
MTH_BOOK_STATE.selectedPetRankEntry = this.entry
|
|
MTH_BOOK_UpdateDetail()
|
|
MTH_BOOK_UpdateResults()
|
|
end)
|
|
btn:SetScript("OnEnter", function()
|
|
if this and this.entry then
|
|
MTH_BOOK_ShowRankTooltip(this, this.entry)
|
|
end
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
MTH_BOOK_HideSpellTooltip()
|
|
end)
|
|
|
|
ui.rightButtons[i] = btn
|
|
rightY = rightY - rightRowStep
|
|
end
|
|
|
|
ui.detailTitleTop = detailParent:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.detailTitleTop:SetPoint("TOPLEFT", detailParent, "TOPLEFT", 8, -8)
|
|
ui.detailTitleTop:SetWidth(120)
|
|
ui.detailTitleTop:SetJustifyH("LEFT")
|
|
ui.detailTitleTop:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.detailTitleTop:SetText("Spell baseline")
|
|
|
|
ui.detailTop = CreateFrame("EditBox", nil, detailParent)
|
|
ui.detailTop:SetMultiLine(true)
|
|
ui.detailTop:SetAutoFocus(false)
|
|
ui.detailTop:SetPoint("TOPLEFT", ui.detailTitleTop, "BOTTOMLEFT", 0, -4)
|
|
ui.detailTop:SetWidth(120)
|
|
ui.detailTop:SetHeight(132)
|
|
|
|
ui.detailTopIcon = detailParent:CreateTexture(nil, "ARTWORK")
|
|
ui.detailTopIcon:SetPoint("TOPRIGHT", ui.detailTop, "TOPRIGHT", -4, -4)
|
|
ui.detailTopIcon:SetWidth(16)
|
|
ui.detailTopIcon:SetHeight(16)
|
|
ui.detailTopIcon:Hide()
|
|
|
|
ui.detailTitleBottom = detailParent:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
|
|
ui.detailTitleBottom:SetPoint("TOPLEFT", ui.detailTop, "BOTTOMLEFT", 0, -8)
|
|
ui.detailTitleBottom:SetWidth(120)
|
|
ui.detailTitleBottom:SetJustifyH("LEFT")
|
|
ui.detailTitleBottom:SetTextColor(1.00, 0.82, 0.00)
|
|
ui.detailTitleBottom:SetText("Current Rank")
|
|
|
|
ui.detailBottom = CreateFrame("EditBox", nil, detailParent)
|
|
ui.detailBottom:SetMultiLine(true)
|
|
ui.detailBottom:SetAutoFocus(false)
|
|
ui.detailBottom:SetPoint("TOPLEFT", ui.detailTitleBottom, "BOTTOMLEFT", 0, -4)
|
|
ui.detailBottom:SetWidth(120)
|
|
ui.detailBottom:SetHeight(116)
|
|
|
|
MTH_BOOK_ConfigureReadOnlyEditBox(ui.detailTop)
|
|
MTH_BOOK_ConfigureReadOnlyEditBox(ui.detailBottom)
|
|
if ui.detailTop.SetTextColor then ui.detailTop:SetTextColor(1.00, 1.00, 1.00) end
|
|
if ui.detailBottom.SetTextColor then ui.detailBottom:SetTextColor(1.00, 1.00, 1.00) end
|
|
|
|
MTH_BOOK_STATE.petUI = ui
|
|
end
|
|
|
|
function MTH_BOOKTAB_SetPetAbilitiesUIVisible(visible)
|
|
local ui = MTH_BOOK_STATE.petUI
|
|
if not ui then return end
|
|
|
|
local detail = getglobal("MTH_BOOK_DetailBackdropDetailText")
|
|
if detail then
|
|
if visible then detail:Hide() else detail:Show() end
|
|
end
|
|
|
|
local widgets = {
|
|
ui.leftPane,
|
|
ui.leftScroll,
|
|
ui.rightPane,
|
|
ui.vSplit,
|
|
ui.leftHeaderAbility,
|
|
ui.leftHeaderRank,
|
|
ui.rightHeaderRank,
|
|
ui.rightHeaderKnown,
|
|
ui.rightHeaderLevel,
|
|
ui.rightHeaderDesc,
|
|
ui.recapText,
|
|
ui.progressBackdrop,
|
|
ui.detailTop,
|
|
ui.detailBottom,
|
|
ui.detailTitleTop,
|
|
ui.detailTitleBottom,
|
|
}
|
|
|
|
for i = 1, table.getn(widgets) do
|
|
local widget = widgets[i]
|
|
if widget and widget.Show and widget.Hide then
|
|
if visible then widget:Show() else widget:Hide() end
|
|
end
|
|
end
|
|
|
|
if ui.detailTopIcon and not visible then
|
|
ui.detailTopIcon:Hide()
|
|
end
|
|
|
|
if not visible then
|
|
MTH_BOOK_HideSpellTooltip()
|
|
end
|
|
end
|
|
|
|
function MTH_BOOKTAB_UpdatePetAbilitiesLists()
|
|
local ui = MTH_BOOK_STATE.petUI
|
|
if not ui then return end
|
|
|
|
local resultCount = table.getn(MTH_BOOK_STATE.results)
|
|
local visibleRows = table.getn(ui.leftButtons)
|
|
local maxOffset = math.max(0, resultCount - visibleRows)
|
|
if MTH_BOOK_STATE.petLeftOffset < 0 then MTH_BOOK_STATE.petLeftOffset = 0 end
|
|
if MTH_BOOK_STATE.petLeftOffset > maxOffset then MTH_BOOK_STATE.petLeftOffset = maxOffset end
|
|
if ui.leftScroll then
|
|
ui.leftScroll:SetMinMaxValues(0, maxOffset)
|
|
ui.leftScroll:SetValueStep(1)
|
|
ui.leftScroll:SetValue(MTH_BOOK_STATE.petLeftOffset)
|
|
local upButton = getglobal("MTH_BOOK_PetLeftScrollScrollUpButton")
|
|
local downButton = getglobal("MTH_BOOK_PetLeftScrollScrollDownButton")
|
|
if upButton then
|
|
if MTH_BOOK_STATE.petLeftOffset > 0 then
|
|
upButton:EnableMouse(true)
|
|
upButton:SetAlpha(1)
|
|
else
|
|
upButton:EnableMouse(false)
|
|
upButton:SetAlpha(0.35)
|
|
end
|
|
end
|
|
if downButton then
|
|
if MTH_BOOK_STATE.petLeftOffset < maxOffset then
|
|
downButton:EnableMouse(true)
|
|
downButton:SetAlpha(1)
|
|
else
|
|
downButton:EnableMouse(false)
|
|
downButton:SetAlpha(0.35)
|
|
end
|
|
end
|
|
if maxOffset > 0 then
|
|
ui.leftScroll:SetAlpha(1)
|
|
ui.leftScroll:Show()
|
|
else
|
|
ui.leftScroll:SetAlpha(1)
|
|
ui.leftScroll:Hide()
|
|
end
|
|
end
|
|
|
|
local startIndex = MTH_BOOK_STATE.petLeftOffset + 1
|
|
for i = 1, visibleRows do
|
|
local btn = ui.leftButtons[i]
|
|
if btn then
|
|
local rowIndex = startIndex + i - 1
|
|
local entry = MTH_BOOK_STATE.results[rowIndex]
|
|
btn.entry = entry
|
|
if entry then
|
|
if btn.icon then
|
|
if entry.icon and entry.icon ~= "" then
|
|
if string.find(entry.icon, "\\", 1, true) then
|
|
btn.icon:SetTexture(entry.icon)
|
|
else
|
|
btn.icon:SetTexture("Interface\\Icons\\" .. tostring(entry.icon))
|
|
end
|
|
btn.icon:Show()
|
|
else
|
|
btn.icon:Hide()
|
|
end
|
|
end
|
|
btn.ability:SetText(tostring(entry.ability or "?"))
|
|
btn.rank:SetText(tostring(entry.rankText or ""))
|
|
btn.ability:SetTextColor(0.92, 0.92, 0.92)
|
|
btn.rank:SetTextColor(0.92, 0.92, 0.92)
|
|
if btn.icon then btn.icon:SetVertexColor(1, 1, 1, 1) end
|
|
if MTH_BOOK_STATE.selectedEntry and MTH_BOOK_STATE.selectedEntry.ability == entry.ability then
|
|
btn.selected:Show()
|
|
else
|
|
btn.selected:Hide()
|
|
end
|
|
btn:Show()
|
|
else
|
|
if btn.icon then btn.icon:Hide() end
|
|
btn.ability:SetText("")
|
|
btn.rank:SetText("")
|
|
btn.selected:Hide()
|
|
btn:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
local totalKnown = 0
|
|
local totalRanks = 0
|
|
for i = 1, resultCount do
|
|
local entry = MTH_BOOK_STATE.results[i]
|
|
if entry then
|
|
totalKnown = totalKnown + (tonumber(entry.knownRankCount) or 0)
|
|
totalRanks = totalRanks + (tonumber(entry.rankCount) or 0)
|
|
end
|
|
end
|
|
if ui.recapText then
|
|
ui.recapText:SetText("Abilities " .. tostring(resultCount) .. " | Known " .. tostring(totalKnown) .. "/" .. tostring(totalRanks))
|
|
end
|
|
if ui.progressBar then
|
|
ui.progressBar:SetMinMaxValues(0, math.max(1, totalRanks))
|
|
ui.progressBar:SetValue(totalKnown)
|
|
end
|
|
if ui.progressText then
|
|
local pct = 0
|
|
if totalRanks > 0 then
|
|
pct = math.floor((totalKnown / totalRanks) * 100 + 0.5)
|
|
end
|
|
ui.progressText:SetText(tostring(pct) .. "%")
|
|
end
|
|
|
|
if MTH_BOOK_STATE.selectedEntry then
|
|
local keep = false
|
|
for i = 1, table.getn(MTH_BOOK_STATE.results) do
|
|
local row = MTH_BOOK_STATE.results[i]
|
|
if row and row.ability == MTH_BOOK_STATE.selectedEntry.ability then
|
|
MTH_BOOK_STATE.selectedEntry = row
|
|
keep = true
|
|
break
|
|
end
|
|
end
|
|
if not keep then
|
|
MTH_BOOK_STATE.selectedEntry = nil
|
|
MTH_BOOK_STATE.selectedPetRankEntry = nil
|
|
end
|
|
end
|
|
|
|
MTH_BOOK_STATE.petRankRows = MTH_BOOK_BuildPetAbilityRankRows(MTH_BOOK_STATE.selectedEntry)
|
|
|
|
for i = 1, table.getn(ui.rightButtons) do
|
|
local btn = ui.rightButtons[i]
|
|
if btn then
|
|
local entry = MTH_BOOK_STATE.petRankRows[i]
|
|
btn.entry = entry
|
|
if entry then
|
|
btn.rank:SetText(MTH_BOOK_GetRankLabel(entry.rankNumber, false))
|
|
if btn.knownIcon then
|
|
if entry.isKnown then
|
|
btn.knownIcon:Show()
|
|
else
|
|
btn.knownIcon:Hide()
|
|
end
|
|
end
|
|
btn.level:SetText(entry.trainLevel and tostring(entry.trainLevel) or "-")
|
|
btn.desc:SetText(tostring(entry.description or "-"))
|
|
if MTH_BOOK_STATE.selectedPetRankEntry and MTH_BOOK_STATE.selectedPetRankEntry.id == entry.id then
|
|
btn.selected:Show()
|
|
else
|
|
btn.selected:Hide()
|
|
end
|
|
btn:Show()
|
|
else
|
|
btn.rank:SetText("")
|
|
if btn.knownIcon then btn.knownIcon:Hide() end
|
|
btn.level:SetText("")
|
|
btn.desc:SetText("")
|
|
btn.selected:Hide()
|
|
btn:Hide()
|
|
end
|
|
end
|
|
end
|
|
end
|