完成焦点等开发

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

183
Core.lua
View File

@@ -47,12 +47,31 @@ SFrames.eventFrame = CreateFrame("Frame", "SFramesEventFrame", UIParent)
SFrames.events = {}
function SFrames:GetIncomingHeals(unit)
-- Resolve pet unitIds: if "target" points to a pet in our group, use the
-- concrete petN / partypetN id so heal-prediction libraries can match it.
local resolvedUnit = unit
if unit == "target" or unit == "targettarget" then
if UnitExists(unit) and UnitPlayerControlled(unit) and not UnitIsPlayer(unit) then
-- It's a player-controlled non-player unit (pet). Find the real unitId.
if UnitIsUnit(unit, "pet") then
resolvedUnit = "pet"
else
for i = 1, 4 do
if UnitIsUnit(unit, "partypet" .. i) then
resolvedUnit = "partypet" .. i
break
end
end
end
end
end
-- Source 1: ShaguTweaks libpredict
if ShaguTweaks and ShaguTweaks.libpredict and ShaguTweaks.libpredict.UnitGetIncomingHeals then
local lp = ShaguTweaks.libpredict
if lp.UnitGetIncomingHealsBreakdown then
local ok, total, mine, others = pcall(function()
return lp:UnitGetIncomingHealsBreakdown(unit, UnitName("player"))
return lp:UnitGetIncomingHealsBreakdown(resolvedUnit, UnitName("player"))
end)
if ok then
return math.max(0, tonumber(total) or 0),
@@ -60,7 +79,7 @@ function SFrames:GetIncomingHeals(unit)
math.max(0, tonumber(others) or 0)
end
end
local ok, amount = pcall(function() return lp:UnitGetIncomingHeals(unit) end)
local ok, amount = pcall(function() return lp:UnitGetIncomingHeals(resolvedUnit) end)
if ok then
amount = math.max(0, tonumber(amount) or 0)
return amount, 0, amount
@@ -70,7 +89,7 @@ function SFrames:GetIncomingHeals(unit)
if AceLibrary and AceLibrary.HasInstance and AceLibrary:HasInstance("HealComm-1.0") then
local ok, HC = pcall(function() return AceLibrary("HealComm-1.0") end)
if ok and HC and HC.getHeal then
local name = UnitName(unit)
local name = UnitName(resolvedUnit)
if name then
local total = HC:getHeal(name) or 0
total = math.max(0, tonumber(total) or 0)
@@ -124,8 +143,127 @@ end
-- Addon Loaded Initializer
SFrames:RegisterEvent("PLAYER_LOGIN", function()
SFrames:Initialize()
SFrames:SaveCharProfile()
end)
SFrames:RegisterEvent("PLAYER_LOGOUT", function()
SFrames:SaveCharProfile()
end)
function SFrames:GetCharKey()
local name = UnitName("player") or "Unknown"
local realm = GetRealmName and GetRealmName() or "Unknown"
return realm, name
end
function SFrames:SaveCharProfile()
if not SFramesDB then return end
if not SFramesGlobalDB then SFramesGlobalDB = {} end
if not SFramesGlobalDB.CharProfiles then SFramesGlobalDB.CharProfiles = {} end
local realm, name = self:GetCharKey()
if not SFramesGlobalDB.CharProfiles[realm] then SFramesGlobalDB.CharProfiles[realm] = {} end
local snapshot = {}
for k, v in pairs(SFramesDB) do
snapshot[k] = v
end
snapshot._savedAt = time and time() or 0
snapshot._class = select and select(2, UnitClass("player")) or "UNKNOWN"
if UnitClass then
local _, classEn = UnitClass("player")
snapshot._class = classEn or "UNKNOWN"
end
snapshot._level = UnitLevel and UnitLevel("player") or 0
-- Nanami-QT
if QuickToolboxDB then
snapshot._qtDB = QuickToolboxDB
end
if QuickToolboxSharedDB then
snapshot._qtSharedDB = QuickToolboxSharedDB
end
-- Nanami-Plates
if NanamiPlatesDB then
snapshot._platesDB = NanamiPlatesDB
end
-- Nanami-DPS
if NanamiDPS_DB then
snapshot._dpsDB = NanamiDPS_DB
end
SFramesGlobalDB.CharProfiles[realm][name] = snapshot
end
function SFrames:GetAllCharProfiles()
if not SFramesGlobalDB or not SFramesGlobalDB.CharProfiles then return {} end
local list = {}
for realm, chars in pairs(SFramesGlobalDB.CharProfiles) do
for charName, data in pairs(chars) do
table.insert(list, {
realm = realm,
name = charName,
class = data._class or "UNKNOWN",
level = data._level or 0,
savedAt = data._savedAt or 0,
data = data,
})
end
end
return list
end
function SFrames:ApplyCharProfile(profileData)
if not profileData or type(profileData) ~= "table" then return false end
for k, v in pairs(profileData) do
if k ~= "_savedAt" and k ~= "_class" and k ~= "_level" and k ~= "Positions"
and k ~= "_qtDB" and k ~= "_qtSharedDB" and k ~= "_platesDB" and k ~= "_dpsDB" then
SFramesDB[k] = v
end
end
-- Nanami-QT
if profileData._qtDB and type(profileData._qtDB) == "table" then
if not QuickToolboxDB then QuickToolboxDB = {} end
for k, v in pairs(profileData._qtDB) do
QuickToolboxDB[k] = v
end
end
if profileData._qtSharedDB and type(profileData._qtSharedDB) == "table" then
if not QuickToolboxSharedDB then QuickToolboxSharedDB = {} end
for k, v in pairs(profileData._qtSharedDB) do
QuickToolboxSharedDB[k] = v
end
end
-- Nanami-Plates
if profileData._platesDB and type(profileData._platesDB) == "table" then
if not NanamiPlatesDB then NanamiPlatesDB = {} end
for k, v in pairs(profileData._platesDB) do
NanamiPlatesDB[k] = v
end
end
-- Nanami-DPS
if profileData._dpsDB and type(profileData._dpsDB) == "table" then
if not NanamiDPS_DB then NanamiDPS_DB = {} end
for k, v in pairs(profileData._dpsDB) do
NanamiDPS_DB[k] = v
end
end
return true
end
function SFrames:DeleteCharProfile(realm, name)
if not SFramesGlobalDB or not SFramesGlobalDB.CharProfiles then return end
if SFramesGlobalDB.CharProfiles[realm] then
SFramesGlobalDB.CharProfiles[realm][name] = nil
end
end
function SFrames:SafeInit(name, initFn)
local ok, err = pcall(initFn)
if not ok then
@@ -208,7 +346,6 @@ function SFrames:DoFullInitialize()
deferFrame:SetScript("OnUpdate", function()
if idx > table.getn(deferred) then
this:SetScript("OnUpdate", nil)
SFrames:Print("所有模块加载完成 =^_^=")
return
end
local batchEnd = idx + batchSize - 1
@@ -421,6 +558,35 @@ function SFrames:InitSlashCommands()
else
SFrames:Print("StatSummary module unavailable.")
end
elseif cmd == "iteminfo" or cmd == "ii" then
-- 打印鼠标悬停物品或指定itemID的GetItemInfo全部返回值
local itemId = tonumber(args)
local link
if itemId and itemId > 0 then
link = "item:" .. itemId .. ":0:0:0:0:0:0:0"
else
local ttName = GameTooltip:GetName()
local left1 = ttName and _G[ttName .. "TextLeft1"]
local name = left1 and left1:GetText()
if name and name ~= "" and GetItemLinkByName then
link = GetItemLinkByName(name)
end
if not link then
SFrames:Print("用法: /nui iteminfo <itemID> 或悬停物品后输入 /nui iteminfo")
return
end
end
-- 打印所有返回值(不预设数量,逐个检查)
local results = { GetItemInfo(link) }
SFrames:Print("|cff88ccff=== GetItemInfo 结果 ===|r")
SFrames:Print(" link: " .. tostring(link))
SFrames:Print(" 返回值数量: " .. table.getn(results))
for i = 1, table.getn(results) do
SFrames:Print(" [" .. i .. "] " .. tostring(results[i]))
end
if table.getn(results) == 0 then
SFrames:Print(" |cffff4444(无返回值,物品可能不在本地缓存中)|r")
end
elseif cmd == "afk" then
if SFrames.AFKScreen and SFrames.AFKScreen.Toggle then
SFrames.AFKScreen:Toggle()
@@ -567,11 +733,13 @@ function SFrames:InitSlashCommands()
DEFAULT_CHAT_FRAME:AddMessage(" |cffffd100" .. name .. "|r (用户自定义)")
end
end
elseif cmd == "profile" then
if SFrames.ConfigUI and SFrames.ConfigUI.Build then SFrames.ConfigUI:Build("profile") end
elseif cmd == "config" or cmd == "" then
if SFrames.ConfigUI and SFrames.ConfigUI.Build then SFrames.ConfigUI:Build("ui") end
else
local hex = SFrames.Theme and SFrames.Theme:GetAccentHex() or "ffffb3d9"
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r Commands: /nui, /nui ui, /nui bags, /nui chat, /nui layout, /nui unlock, /nui lock, /nui test, /nui partyh, /nui partyv, /nui focushelp, /nui mapreveal, /nui mapscan, /nui stats, /nui afk, /nui pin, /nui bind, /nui keybinds")
DEFAULT_CHAT_FRAME:AddMessage("|c" .. hex .. "[Nanami-UI]|r Commands: /nui, /nui ui, /nui bags, /nui chat, /nui layout, /nui unlock, /nui lock, /nui test, /nui partyh, /nui partyv, /nui focushelp, /nui mapreveal, /nui mapscan, /nui stats, /nui afk, /nui pin, /nui bind, /nui keybinds, /nui profile")
end
end
end
@@ -633,6 +801,11 @@ function SFrames:HideBlizzardFrames()
TargetFrame:Hide()
TargetFrame.Show = function() end
end
-- 禁用原版目标框体右键菜单
if TargetFrameDropDown then
TargetFrameDropDown:Hide()
TargetFrameDropDown.initialize = function() end
end
if ComboFrame then
ComboFrame:UnregisterAllEvents()
ComboFrame:Hide()