完成焦点等开发

This commit is contained in:
rucky
2026-03-31 18:03:23 +08:00
parent c7dd0f4848
commit 6e18269bfd
34 changed files with 6803 additions and 542 deletions

View File

@@ -54,7 +54,7 @@ L.LIST_ROW_W = L.LEFT_W - L.SIDE_PAD * 2 - L.SCROLLBAR_W - 4
local S = {
MainFrame = nil,
selectedIndex = nil,
currentFilter = "all",
currentFilter = "available",
displayList = {},
rowButtons = {},
collapsedCats = {},
@@ -67,9 +67,17 @@ local scanTip = nil
function BTUI.GetCraftExtendedInfo(index)
local name, rank, skillType, v4, _, tpCost, reqLevel = GetCraftInfo(index)
local canLearn = (tonumber(reqLevel) or 0) > 0
tpCost = tonumber(tpCost) or 0
return name, rank, skillType, canLearn, tpCost
local canLearn = false
local isLearned = false
if skillType ~= "header" then
if skillType == "used" then
isLearned = true
else
canLearn = (tonumber(reqLevel) or 0) > 0
end
end
return name, rank, skillType, canLearn, tpCost, isLearned
end
function BTUI.GetSkillTooltipLines(index)
@@ -356,7 +364,11 @@ function BTUI.CreateListRow(parent, idx)
self.rankFS:Hide()
end
if skill.canLearn then
if skill.isLearned then
self.nameFS:SetTextColor(T.learned[1], T.learned[2], T.learned[3])
self.icon:SetVertexColor(0.5, 0.5, 0.5)
self.tpFS:Hide()
elseif skill.canLearn then
self.nameFS:SetTextColor(T.available[1], T.available[2], T.available[3])
self.icon:SetVertexColor(1, 1, 1)
local tp = skill.tpCost or 0
@@ -373,8 +385,8 @@ function BTUI.CreateListRow(parent, idx)
self.tpFS:Hide()
end
else
self.nameFS:SetTextColor(T.learned[1], T.learned[2], T.learned[3])
self.icon:SetVertexColor(0.5, 0.5, 0.5)
self.nameFS:SetTextColor(T.unavailable[1], T.unavailable[2], T.unavailable[3])
self.icon:SetVertexColor(0.6, 0.3, 0.3)
self.tpFS:Hide()
end
end
@@ -392,17 +404,47 @@ end
--------------------------------------------------------------------------------
-- Logic
--------------------------------------------------------------------------------
-- Strip rank suffix to get base skill name (e.g. "自然抗性 2" -> "自然抗性")
function BTUI.GetBaseSkillName(name)
if not name then return "" end
-- Remove trailing " Rank X" / " X" patterns (both EN and CN)
local base = string.gsub(name, "%s+%d+$", "")
base = string.gsub(base, "%s+[Rr]ank%s+%d+$", "")
return base
end
-- Build a lookup: baseName -> highest tpCost among learned ranks
function BTUI.BuildLearnedCostMap()
local map = {} -- baseName -> highest learned tpCost
local numCrafts = GetNumCrafts and GetNumCrafts() or 0
for i = 1, numCrafts do
local name, rank, skillType, canLearn, tpCost, isLearned = BTUI.GetCraftExtendedInfo(i)
if name and skillType ~= "header" and isLearned then
local base = BTUI.GetBaseSkillName(name)
local cost = tpCost or 0
if not map[base] or cost > map[base] then
map[base] = cost
end
end
end
return map
end
function BTUI.BuildDisplayList()
S.displayList = {}
local numCrafts = GetNumCrafts and GetNumCrafts() or 0
if numCrafts == 0 then return end
-- Pre-compute learned cost for each base skill name
local learnedCostMap = BTUI.BuildLearnedCostMap()
local currentCat = nil
local catSkills = {}
local catOrder = {}
for i = 1, numCrafts do
local name, rank, skillType, canLearn, tpCost = BTUI.GetCraftExtendedInfo(i)
local name, rank, skillType, canLearn, tpCost, isLearned = BTUI.GetCraftExtendedInfo(i)
if name then
if skillType == "header" then
currentCat = name
@@ -418,11 +460,18 @@ function BTUI.BuildDisplayList()
table.insert(catOrder, currentCat)
end
end
-- Calculate effective (incremental) TP cost
local effectiveCost = tpCost or 0
if not isLearned and effectiveCost > 0 then
local base = BTUI.GetBaseSkillName(name)
local prevCost = learnedCostMap[base] or 0
effectiveCost = math.max(0, effectiveCost - prevCost)
end
local show = true
if S.currentFilter == "available" then
show = canLearn
elseif S.currentFilter == "used" then
show = (not canLearn)
show = isLearned
end
if show then
table.insert(catSkills[currentCat], {
@@ -430,7 +479,8 @@ function BTUI.BuildDisplayList()
name = name,
rank = rank or "",
canLearn = canLearn,
tpCost = tpCost,
tpCost = effectiveCost,
isLearned = isLearned,
})
end
end
@@ -524,16 +574,18 @@ function BTUI.UpdateDetail()
return
end
local name, rank, skillType, canLearn, tpCost = BTUI.GetCraftExtendedInfo(S.selectedIndex)
local name, rank, skillType, canLearn, tpCost, isLearned = BTUI.GetCraftExtendedInfo(S.selectedIndex)
local iconTex = GetCraftIcon and GetCraftIcon(S.selectedIndex)
detail.icon:SetTexture(iconTex); detail.iconFrame:Show()
detail.nameFS:SetText(name or "")
if canLearn then
if isLearned then
detail.nameFS:SetTextColor(T.learned[1], T.learned[2], T.learned[3])
elseif canLearn then
detail.nameFS:SetTextColor(T.available[1], T.available[2], T.available[3])
else
detail.nameFS:SetTextColor(T.learned[1], T.learned[2], T.learned[3])
detail.nameFS:SetTextColor(T.unavailable[1], T.unavailable[2], T.unavailable[3])
end
if rank and rank ~= "" then
@@ -554,10 +606,23 @@ function BTUI.UpdateDetail()
detail.descScroll:GetScrollChild():SetHeight(math.max(1, descH))
detail.descScroll:SetVerticalScroll(0)
if tpCost > 0 then
if isLearned then
detail.costFS:SetText("|cff808080已学会|r")
elseif tpCost > 0 then
-- Calculate effective (incremental) cost
local effectiveCost = tpCost
local base = BTUI.GetBaseSkillName(name)
local learnedMap = BTUI.BuildLearnedCostMap()
local prevCost = learnedMap[base] or 0
effectiveCost = math.max(0, tpCost - prevCost)
local remaining = BTUI.GetRemainingTP()
local costColor = remaining >= tpCost and "|cff40ff40" or "|cffff4040"
detail.costFS:SetText("训练点数: " .. costColor .. tpCost .. "|r (剩余: " .. remaining .. ")")
local costColor = remaining >= effectiveCost and "|cff40ff40" or "|cffff4040"
if prevCost > 0 then
detail.costFS:SetText("训练点数: " .. costColor .. effectiveCost .. "|r (总" .. tpCost .. " - 已学" .. prevCost .. ") 剩余: " .. remaining)
else
detail.costFS:SetText("训练点数: " .. costColor .. effectiveCost .. "|r (剩余: " .. remaining .. ")")
end
elseif canLearn then
detail.costFS:SetText("训练点数: |cff40ff40免费|r")
else
@@ -706,13 +771,8 @@ function BTUI:Initialize()
fb:SetPoint("TOPLEFT", MF, "TOPLEFT", L.SIDE_PAD, -(L.HEADER_H + 4))
fb:SetWidth(L.LEFT_W - L.SIDE_PAD * 2); fb:SetHeight(22)
local fAll = BTUI.CreateFilterBtn(fb, "全部", 52)
fAll:SetPoint("LEFT", fb, "LEFT", 0, 0)
fAll:SetScript("OnClick", function() S.currentFilter = "all"; BTUI.FullUpdate() end)
MF.filterAll = fAll
local fAvail = BTUI.CreateFilterBtn(fb, "可学", 52)
fAvail:SetPoint("LEFT", fAll, "RIGHT", 3, 0)
fAvail:SetPoint("LEFT", fb, "LEFT", 0, 0)
fAvail:SetScript("OnClick", function() S.currentFilter = "available"; BTUI.FullUpdate() end)
MF.filterAvail = fAvail
@@ -721,11 +781,16 @@ function BTUI:Initialize()
fUsed:SetScript("OnClick", function() S.currentFilter = "used"; BTUI.FullUpdate() end)
MF.filterUsed = fUsed
local fAll = BTUI.CreateFilterBtn(fb, "全部", 52)
fAll:SetPoint("LEFT", fUsed, "RIGHT", 3, 0)
fAll:SetScript("OnClick", function() S.currentFilter = "all"; BTUI.FullUpdate() end)
MF.filterAll = fAll
-- List scroll area
local listTop = L.HEADER_H + L.FILTER_H + 8
local ls = CreateFrame("ScrollFrame", "SFramesBTListScroll", MF)
ls:SetPoint("TOPLEFT", MF, "TOPLEFT", L.SIDE_PAD, -listTop)
ls:SetPoint("BOTTOMRIGHT", MF, "BOTTOMLEFT", L.SIDE_PAD + L.LIST_ROW_W, 6)
ls:SetPoint("BOTTOMRIGHT", MF, "BOTTOMLEFT", L.SIDE_PAD + L.LIST_ROW_W, L.BOTTOM_H + 4)
local lc = CreateFrame("Frame", "SFramesBTListContent", ls)
lc:SetWidth(L.LIST_ROW_W); lc:SetHeight(1)
@@ -807,10 +872,18 @@ function BTUI:Initialize()
function BTUI.UpdateScrollbar()
if not MF.sbThumb or not MF.sbTrack then return end
local scrollMax = BTUI.GetScrollMax()
if scrollMax <= 0 then MF.sbThumb:Hide(); return end
if scrollMax <= 0 then
MF.sbThumb:Hide()
if ls:GetVerticalScroll() > 0 then ls:SetVerticalScroll(0) end
return
end
MF.sbThumb:Show()
local trackH = MF.sbTrack:GetHeight()
local curScroll = ls:GetVerticalScroll()
if curScroll > scrollMax then
curScroll = scrollMax
ls:SetVerticalScroll(scrollMax)
end
local ratio = curScroll / scrollMax
ratio = math.max(0, math.min(1, ratio))
local thumbH = math.max(20, trackH * (trackH / (trackH + scrollMax)))
@@ -1016,7 +1089,7 @@ function BTUI:Initialize()
CraftFrame:SetScript("OnHide", function() end)
CraftFrame:SetAlpha(0); CraftFrame:EnableMouse(false)
end
S.selectedIndex = nil; S.currentFilter = "all"; S.collapsedCats = {}
S.selectedIndex = nil; S.currentFilter = "available"; S.collapsedCats = {}
local petName = UnitName("pet") or ""
if petName ~= "" then
MF.titleFS:SetText("训练野兽 - " .. petName)