修改优化等

This commit is contained in:
rucky
2026-03-18 02:01:36 +08:00
parent 2a55dd6dad
commit 923a1f9ce2
15 changed files with 1578 additions and 371 deletions

View File

@@ -438,6 +438,36 @@ function SFrames.Player:Initialize()
self:ShowTrainerReminder(arg1)
end
end)
SFrames:RegisterEvent("TRAINER_SHOW", function()
SFrames.Player.trainerScannedThisVisit = nil
SFrames.Player.trainerShowPending = true
SFrames.Player.trainerRetryCount = 0
if not SFrames.Player.trainerRetryFrame then
SFrames.Player.trainerRetryFrame = CreateFrame("Frame")
end
SFrames.Player.trainerRetryFrame:SetScript("OnUpdate", function()
if not this.elapsed then this.elapsed = 0 end
this.elapsed = this.elapsed + arg1
if this.elapsed < 0.3 then return end
this.elapsed = 0
if SFrames.Player.trainerScannedThisVisit then
this:SetScript("OnUpdate", nil)
return
end
SFrames.Player.trainerRetryCount = (SFrames.Player.trainerRetryCount or 0) + 1
if SFrames.Player.trainerRetryCount > 10 then
SFrames.Player:ScanTrainer()
this:SetScript("OnUpdate", nil)
return
end
SFrames.Player:ScanTrainer()
end)
end)
SFrames:RegisterEvent("TRAINER_UPDATE", function()
if not SFrames.Player.trainerScannedThisVisit then
SFrames.Player:ScanTrainer()
end
end)
SFrames:RegisterEvent("PARTY_MEMBERS_CHANGED", function() self:UpdateLeaderIcon() end)
SFrames:RegisterEvent("PARTY_LEADER_CHANGED", function() self:UpdateLeaderIcon() end)
SFrames:RegisterEvent("RAID_TARGET_UPDATE", function() self:UpdateRaidIcon() end)
@@ -458,11 +488,13 @@ function SFrames.Player:Initialize()
end
function SFrames.Player:HasSpellInBook(spellName)
local baseName = string.gsub(spellName, " 等级 %d+$", "")
baseName = string.gsub(baseName, " %d+级$", "")
local i = 1
while true do
local name = GetSpellName(i, BOOKTYPE_SPELL)
if not name then return false end
if name == spellName then return true end
if name == spellName or name == baseName then return true end
i = i + 1
end
end
@@ -483,6 +515,167 @@ function SFrames.Player:GetSpellIcon(skillDisplayName)
return nil
end
function SFrames.Player:ParseTrainerTooltipLevel(serviceIndex)
if not self.trainerScanTip then
local tt = CreateFrame("GameTooltip", "NanamiTrainerScanTip", nil, "GameTooltipTemplate")
tt:SetOwner(UIParent, "ANCHOR_NONE")
self.trainerScanTip = tt
end
local tt = self.trainerScanTip
tt:ClearLines()
if not tt.SetTrainerService then return nil end
tt:SetTrainerService(serviceIndex)
for j = 2, tt:NumLines() do
local textObj = getglobal("NanamiTrainerScanTipTextLeft" .. j)
if textObj then
local text = textObj:GetText()
if text then
local _, _, lvl = string.find(text, "需要等级%s*(%d+)")
if not lvl then
_, _, lvl = string.find(text, "Requires Level (%d+)")
end
if lvl then return tonumber(lvl) end
end
end
end
return nil
end
function SFrames.Player:FindSkillLevelInStaticData(classEn, skillName)
local staticData = SFrames.ClassSkillData and SFrames.ClassSkillData[classEn]
if not staticData then return nil end
local baseName = string.gsub(skillName, " %d+级$", "")
baseName = string.gsub(baseName, "(等级 %d+$", "")
baseName = string.gsub(baseName, "%s+$", "")
for level, skills in pairs(staticData) do
for _, s in ipairs(skills) do
local sBase = string.gsub(s, " %d+级$", "")
sBase = string.gsub(sBase, "(等级 %d+$", "")
sBase = string.gsub(sBase, "%s+$", "")
if baseName == sBase or skillName == s then
return level
end
end
end
local talentData = SFrames.TalentTrainerSkills and SFrames.TalentTrainerSkills[classEn]
if talentData then
for level, entries in pairs(talentData) do
for _, entry in ipairs(entries) do
local tBase = string.gsub(entry[1], " %d+级$", "")
if baseName == tBase or skillName == entry[1] then
return level
end
end
end
end
return nil
end
function SFrames.Player:ScanTrainer()
if self.scanningTrainer then return end
self.scanningTrainer = true
local hex = SFrames.Theme and SFrames.Theme:GetAccentHex() or "ffffb3d9"
if not GetNumTrainerServices then
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r |cffff6666训练师扫描失败: GetNumTrainerServices 不存在|r")
self.scanningTrainer = nil
return
end
if IsTradeskillTrainer and IsTradeskillTrainer() then
self.scanningTrainer = nil
return
end
local _, classEn = UnitClass("player")
if not classEn or not SFramesDB then self.scanningTrainer = nil return end
local cache = {}
local numServices = GetNumTrainerServices()
if not numServices or numServices == 0 then
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r |cffff6666训练师扫描: 未检测到技能列表 (0项),将在数据加载后重试|r")
self.scanningTrainer = nil
return
end
local hasLevelAPI = (GetTrainerServiceLevelReq ~= nil)
local noLevelCount = 0
local totalAdded = 0
local iconMissCount = 0
for i = 1, numServices do
local name, subText, serviceType = GetTrainerServiceInfo(i)
if name and subText and subText ~= "" then
local icon = GetTrainerServiceIcon and GetTrainerServiceIcon(i)
if (not icon or icon == "") and ClassTrainerFrame then
local skillButton = getglobal("ClassTrainerSkill" .. i)
if skillButton then
local iconTex = getglobal("ClassTrainerSkill" .. i .. "Icon")
if iconTex and iconTex.GetTexture then
icon = iconTex:GetTexture()
end
end
end
if not icon or icon == "" then
iconMissCount = iconMissCount + 1
end
local reqLevel
if hasLevelAPI then
reqLevel = GetTrainerServiceLevelReq(i)
end
if not reqLevel or reqLevel == 0 then
reqLevel = self:ParseTrainerTooltipLevel(i)
end
if not reqLevel or reqLevel == 0 then
local lookupName = name .. " " .. subText
reqLevel = self:FindSkillLevelInStaticData(classEn, lookupName)
if not reqLevel then
reqLevel = self:FindSkillLevelInStaticData(classEn, name)
end
end
if not reqLevel or reqLevel == 0 then
noLevelCount = noLevelCount + 1
end
if reqLevel and reqLevel > 0 then
local displayName = name .. " " .. subText
if not cache[reqLevel] then
cache[reqLevel] = {}
end
table.insert(cache[reqLevel], {
name = displayName,
icon = icon or "",
})
totalAdded = totalAdded + 1
end
end
end
if not SFramesDB.trainerCache then
SFramesDB.trainerCache = {}
end
SFramesDB.trainerCache[classEn] = cache
self.trainerScannedThisVisit = true
local levelCount = 0
for _ in pairs(cache) do levelCount = levelCount + 1 end
local iconOk = totalAdded - iconMissCount
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r 已从训练师更新技能数据(" .. levelCount .. " 个等级," .. totalAdded .. " 项技能," .. iconOk .. " 个图标)")
if noLevelCount > 0 then
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r |cffff9900有 " .. noLevelCount .. " 项技能无法确定等级要求,已跳过|r")
end
if iconMissCount > 0 then
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r |cffff9900有 " .. iconMissCount .. " 项技能未获取到图标|r")
end
self.scanningTrainer = nil
end
function SFrames.Player:ShowTrainerReminder(newLevel)
local _, classEn = UnitClass("player")
local classNames = {
@@ -507,25 +700,49 @@ function SFrames.Player:ShowTrainerReminder(newLevel)
local allSkills = {}
local allIcons = {}
local talentSkills = {}
local usedCache = false
local baseSkills = SFrames.ClassSkillData and SFrames.ClassSkillData[classEn] and SFrames.ClassSkillData[classEn][newLevel]
if baseSkills then
for _, s in ipairs(baseSkills) do
table.insert(allSkills, s)
table.insert(allIcons, self:GetSpellIcon(s) or fallbackIcon)
local classCache = SFramesDB and SFramesDB.trainerCache and SFramesDB.trainerCache[classEn]
if classCache then
local lowLevel = newLevel - 1
if lowLevel < 1 then lowLevel = 1 end
for lv = lowLevel, newLevel do
if classCache[lv] then
usedCache = true
for _, entry in ipairs(classCache[lv]) do
if not self:HasSpellInBook(entry.name) then
table.insert(allSkills, entry.name)
local ico = entry.icon
if not ico or ico == "" then
ico = self:GetSpellIcon(entry.name) or fallbackIcon
end
table.insert(allIcons, ico)
end
end
end
end
end
local talentData = SFrames.TalentTrainerSkills and SFrames.TalentTrainerSkills[classEn] and SFrames.TalentTrainerSkills[classEn][newLevel]
local talentSkills = {}
if talentData then
for _, entry in ipairs(talentData) do
local displayName = entry[1]
local requiredSpell = entry[2]
if self:HasSpellInBook(requiredSpell) then
table.insert(allSkills, displayName)
table.insert(allIcons, self:GetSpellIcon(displayName) or fallbackIcon)
table.insert(talentSkills, displayName)
if not usedCache then
local baseSkills = SFrames.ClassSkillData and SFrames.ClassSkillData[classEn] and SFrames.ClassSkillData[classEn][newLevel]
if baseSkills then
for _, s in ipairs(baseSkills) do
table.insert(allSkills, s)
table.insert(allIcons, self:GetSpellIcon(s) or fallbackIcon)
end
end
local talentData = SFrames.TalentTrainerSkills and SFrames.TalentTrainerSkills[classEn] and SFrames.TalentTrainerSkills[classEn][newLevel]
if talentData then
for _, entry in ipairs(talentData) do
local displayName = entry[1]
local requiredSpell = entry[2]
if self:HasSpellInBook(requiredSpell) then
table.insert(allSkills, displayName)
table.insert(allIcons, self:GetSpellIcon(displayName) or fallbackIcon)
table.insert(talentSkills, displayName)
end
end
end
end
@@ -533,6 +750,11 @@ function SFrames.Player:ShowTrainerReminder(newLevel)
local mountQuest = SFrames.ClassMountQuests and SFrames.ClassMountQuests[classEn] and SFrames.ClassMountQuests[classEn][newLevel]
local skillCount = table.getn(allSkills)
if skillCount == 0 and not mountQuest then
return
end
local hex = SFrames.Theme and SFrames.Theme:GetAccentHex() or "ffffb3d9"
SFrames:Print(string.format("已达到 %d 级!你的%s训练师有新技能可以学习。", newLevel, className))
@@ -551,7 +773,7 @@ function SFrames.Player:ShowTrainerReminder(newLevel)
end
end
end
if table.getn(talentSkills) > 0 then
if not usedCache and table.getn(talentSkills) > 0 then
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r |cff00ff00(天赋)|r " .. table.concat(talentSkills, ", "))
end
if mountQuest then
@@ -648,6 +870,7 @@ function SFrames.Player:ShowTrainerReminder(newLevel)
end
local iconCount = 0
for i = 1, skillCount do
if iconCount >= 13 then break end
iconCount = iconCount + 1
@@ -662,28 +885,32 @@ function SFrames.Player:ShowTrainerReminder(newLevel)
fr.skillBorders[iconCount]:Show()
end
if iconCount > 0 then
fr:SetHeight(106)
else
fr:SetHeight(72)
end
fr.title:SetText(string.format("已达到 |cffffffff%d|r 级 — %s训练师有新技能", newLevel, className))
if skillCount > 0 or mountQuest then
local countText = ""
local preview = ""
if skillCount > 0 then
countText = skillCount .. " 项技能"
preview = "|cffffd100" .. allSkills[1] .. "|r"
if skillCount > 1 then preview = preview .. ", |cffffd100" .. allSkills[2] .. "|r" end
if skillCount > 2 then preview = preview .. ", |cffffd100" .. allSkills[3] .. "|r" end
if skillCount > 3 then preview = preview .. "" .. skillCount .. "" end
end
if mountQuest then
if countText ~= "" then countText = countText .. " + " end
countText = countText .. mountQuest
if preview ~= "" then preview = preview .. " | " end
preview = preview .. "|cffffff00" .. mountQuest .. "|r"
end
fr.subtitle:SetText(countText)
fr.subtitle:SetText(preview)
fr.detail:SetText("详见聊天窗口")
else
fr.subtitle:SetText("")
fr.detail:SetText("前往职业训练师查看可学习的技能")
end
if iconCount > 0 then
fr:SetHeight(106)
else
fr:SetHeight(80)
end
fr:Show()
fr:SetAlpha(0)