聊天重做前缓存

This commit is contained in:
rucky
2026-04-09 09:46:47 +08:00
parent 6e18269bfd
commit e915bbd74a
39 changed files with 8501 additions and 2308 deletions

View File

@@ -61,10 +61,11 @@ local currentFilter = "all"
local displayList = {}
local rowButtons = {}
local collapsedCats = {}
local isTradeskillTrainerCached = false -- Cache to avoid repeated API calls
local isTradeskillTrainerCached = false
local function HideBlizzardTrainer()
if not ClassTrainerFrame then return end
ClassTrainerFrame:SetScript("OnHide", function() end)
ClassTrainerFrame:UnregisterAllEvents()
if ClassTrainerFrame:IsVisible() then
if HideUIPanel then
pcall(HideUIPanel, ClassTrainerFrame)
@@ -161,123 +162,20 @@ end
local function GetVerifiedCategory(index)
local name, _, category = GetTrainerServiceInfo(index)
if not name then return nil end
-- "used" is always reliable - player already knows this skill
if category == "used" then
return "used"
if category == "available" or category == "unavailable" or category == "used" then
return category
end
-- "unavailable" from API should be trusted - it considers:
-- - Level requirements
-- - Skill rank prerequisites (e.g., need Fireball Rank 1 before Rank 2)
-- - Profession skill requirements
if category == "unavailable" then
return "unavailable"
end
-- For "available", do extra verification only for tradeskill trainers
-- Class trainers' "available" is already accurate
if category == "available" then
-- Additional check for tradeskill trainers (use cached value)
if isTradeskillTrainerCached then
local playerLevel = UnitLevel("player") or 1
-- Check level requirement
if GetTrainerServiceLevelReq then
local ok, levelReq = pcall(GetTrainerServiceLevelReq, index)
if ok and levelReq and levelReq > 0 and playerLevel < levelReq then
return "unavailable"
end
end
-- Check skill requirement
if GetTrainerServiceSkillReq then
local ok, skillName, skillRank, hasReq = pcall(GetTrainerServiceSkillReq, index)
if ok and skillName and skillName ~= "" and not hasReq then
return "unavailable"
end
end
end
return "available"
end
-- Fallback: unknown category, treat as unavailable
return category or "unavailable"
return "unavailable"
end
local scanTip = nil
local function GetServiceTooltipInfo(index)
if not scanTip then
scanTip = CreateFrame("GameTooltip", "SFramesTrainerScanTip", nil, "GameTooltipTemplate")
end
scanTip:SetOwner(WorldFrame, "ANCHOR_NONE")
scanTip:ClearLines()
local ok = pcall(scanTip.SetTrainerService, scanTip, index)
if not ok then return "", "" end
local infoLines = {}
local descLines = {}
local numLines = scanTip:NumLines()
local foundDesc = false
for i = 2, numLines do
local leftFS = _G["SFramesTrainerScanTipTextLeft" .. i]
local rightFS = _G["SFramesTrainerScanTipTextRight" .. i]
local leftText = leftFS and leftFS:GetText() or ""
local rightText = rightFS and rightFS:GetText() or ""
if leftText == "" and rightText == "" then
if not foundDesc and table.getn(infoLines) > 0 then
foundDesc = true
end
else
local line
if rightText ~= "" and leftText ~= "" then
line = leftText .. " " .. rightText
elseif leftText ~= "" then
line = leftText
else
line = rightText
end
local isYellow = leftFS and leftFS.GetTextColor and true
local r, g, b
if leftFS and leftFS.GetTextColor then
r, g, b = leftFS:GetTextColor()
end
local isWhiteOrYellow = r and (r > 0.9 and g > 0.75)
if not foundDesc and rightText ~= "" then
table.insert(infoLines, line)
elseif not foundDesc and not isWhiteOrYellow and string.len(leftText) < 30 then
table.insert(infoLines, line)
else
foundDesc = true
table.insert(descLines, line)
end
end
end
scanTip:Hide()
return table.concat(infoLines, "\n"), table.concat(descLines, "\n")
return "", ""
end
local function GetServiceQuality(index)
if not scanTip then
scanTip = CreateFrame("GameTooltip", "SFramesTrainerScanTip", nil, "GameTooltipTemplate")
end
scanTip:SetOwner(WorldFrame, "ANCHOR_NONE")
scanTip:ClearLines()
local ok = pcall(scanTip.SetTrainerService, scanTip, index)
if not ok then scanTip:Hide() return nil end
local firstLine = _G["SFramesTrainerScanTipTextLeft1"]
if not firstLine or not firstLine.GetTextColor then
scanTip:Hide()
return nil
end
local r, g, b = firstLine:GetTextColor()
scanTip:Hide()
return ColorToQuality(r, g, b)
return nil
end
--------------------------------------------------------------------------------
@@ -392,10 +290,7 @@ end
local qualityCache = {}
local function GetCachedServiceQuality(index)
if qualityCache[index] ~= nil then return qualityCache[index] end
local q = GetServiceQuality(index)
qualityCache[index] = q or false
return q
return nil
end
--------------------------------------------------------------------------------
@@ -604,22 +499,8 @@ local function CreateListRow(parent, idx)
self.icon:SetVertexColor(T.passive[1], T.passive[2], T.passive[3])
end
-- Skip quality scan for tradeskill trainers (performance optimization)
if not isTradeskillTrainerCached then
local quality = GetCachedServiceQuality(svc.index)
local qc = QUALITY_COLORS[quality]
if qc and quality and quality >= 2 then
self.qualGlow:SetVertexColor(qc[1], qc[2], qc[3])
self.qualGlow:Show()
self.iconFrame:SetBackdropBorderColor(qc[1], qc[2], qc[3], 1)
else
self.qualGlow:Hide()
self.iconFrame:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
end
else
self.qualGlow:Hide()
self.iconFrame:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
end
self.qualGlow:Hide()
self.iconFrame:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
local ok, cost = pcall(GetTrainerServiceCost, svc.index)
if ok and cost and cost > 0 then
@@ -838,13 +719,7 @@ local function UpdateDetail()
detail.icon:SetTexture(iconTex)
detail.iconFrame:Show()
local quality = GetServiceQuality(selectedIndex)
local qc = QUALITY_COLORS[quality]
if qc and quality and quality >= 2 then
detail.iconFrame:SetBackdropBorderColor(qc[1], qc[2], qc[3], 1)
else
detail.iconFrame:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
end
detail.iconFrame:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
detail.nameFS:SetText(name or "")
@@ -873,13 +748,10 @@ local function UpdateDetail()
end
detail.reqFS:SetText(table.concat(reqParts, " "))
local spellInfo, descText = GetServiceTooltipInfo(selectedIndex)
detail.infoFS:SetText(spellInfo)
detail.descFS:SetText(descText)
detail.descDivider:Show()
local textH = detail.descFS:GetHeight() or 40
detail.descScroll:GetScrollChild():SetHeight(math.max(1, textH))
detail.infoFS:SetText("")
detail.descFS:SetText("")
detail.descDivider:Hide()
detail.descScroll:GetScrollChild():SetHeight(1)
detail.descScroll:SetVerticalScroll(0)
local canTrain = (category == "available") and cost and (GetMoney() >= cost)
@@ -1342,6 +1214,7 @@ function TUI:Initialize()
local function CleanupBlizzardTrainer()
if not ClassTrainerFrame then return end
ClassTrainerFrame:SetScript("OnHide", function() end)
ClassTrainerFrame:UnregisterAllEvents()
if HideUIPanel then pcall(HideUIPanel, ClassTrainerFrame) end
if ClassTrainerFrame:IsVisible() then ClassTrainerFrame:Hide() end
ClassTrainerFrame:SetAlpha(0)
@@ -1361,6 +1234,7 @@ function TUI:Initialize()
if event == "TRAINER_SHOW" then
if ClassTrainerFrame then
ClassTrainerFrame:SetScript("OnHide", function() end)
ClassTrainerFrame:UnregisterAllEvents()
ClassTrainerFrame:SetAlpha(0)
ClassTrainerFrame:EnableMouse(false)
end