优化收藏系统插件

1、删除多余逻辑RegisterEvents
2、修正“坐骑收藏”、“小伙伴收藏”、“卡牌收藏”,新获得逻辑,现在新获得可以显示new图标以及更新文本颜色
This commit is contained in:
尚美 2025-06-12 22:42:26 +08:00
parent b6ce311d28
commit a694357f29
6 changed files with 416 additions and 222 deletions

View File

@ -30,3 +30,11 @@ SM_Collections.Config = {
FallbackToLocal = true, -- 服务端失败时回退到本地数据
Debug = true -- 调试模式
}
-- 新获得的收藏项目记录
SM_Collections.NewItems = {
mount = {}, -- 新获得的坐骑ID
companion = {}, -- 新获得的小伙伴ID
card = {}, -- 新获得的卡牌ID
item = {} -- 新获得的物品ID
}

View File

@ -485,32 +485,32 @@ SM_Collections.DataManager = {
return SM_Collections.LocalDataProvider
end
end,
-- 获取坐骑数据
GetMounts = function(self, callback)
self:GetProvider():GetMounts(callback)
end,
-- 获取小伙伴数据
GetCompanions = function(self, callback)
self:GetProvider():GetCompanions(callback)
end,
-- 获取卡牌数据
GetCards = function(self, callback)
self:GetProvider():GetCards(callback)
end,
-- 获取物品数据
GetItems = function(self, callback)
self:GetProvider():GetItems(callback)
end,
-- 获取特定物品的属性加成
GetAttributesForSpecificItem = function(self, itemId, itemType, callback)
self:GetProvider():GetAttributesForSpecificItem(itemId, itemType, callback)
end,
-- 更新坐骑状态
UpdateMountStatus = function(self, mountID, isObtained)
-- 更新本地数据
@ -522,7 +522,7 @@ SM_Collections.DataManager = {
end
end
end
-- 如果使用服务器数据,也更新服务器缓存
if SM_Collections.Config.UseServerData and SM_Collections.ServerDataProvider.cachedMounts then
for i, mount in ipairs(SM_Collections.ServerDataProvider.cachedMounts) do
@ -533,7 +533,7 @@ SM_Collections.DataManager = {
end
end
end,
-- 更新小伙伴状态
UpdateCompanionStatus = function(self, companionID, isObtained)
-- 更新本地数据
@ -545,7 +545,7 @@ SM_Collections.DataManager = {
end
end
end
-- 如果使用服务器数据,也更新服务器缓存
if SM_Collections.Config.UseServerData and SM_Collections.ServerDataProvider.cachedCompanions then
for i, companion in ipairs(SM_Collections.ServerDataProvider.cachedCompanions) do
@ -556,7 +556,7 @@ SM_Collections.DataManager = {
end
end
end,
-- 更新卡牌状态
UpdateCardStatus = function(self, cardID, isObtained)
-- 更新本地数据
@ -568,7 +568,7 @@ SM_Collections.DataManager = {
end
end
end
-- 如果使用服务器数据,也更新服务器缓存
if SM_Collections.Config.UseServerData and SM_Collections.ServerDataProvider.cachedCards then
for i, card in ipairs(SM_Collections.ServerDataProvider.cachedCards) do
@ -579,7 +579,7 @@ SM_Collections.DataManager = {
end
end
end,
-- 更新物品状态
UpdateItemStatus = function(self, itemID, isObtained)
-- 更新本地数据
@ -591,7 +591,7 @@ SM_Collections.DataManager = {
end
end
end
-- 如果使用服务器数据,也更新服务器缓存
if SM_Collections.Config.UseServerData and SM_Collections.ServerDataProvider.cachedItems then
for i, item in ipairs(SM_Collections.ServerDataProvider.cachedItems) do

View File

@ -9,7 +9,7 @@ SlashCmdList["SM_COLLECTIONS"] = function()
else
SM_Collections.MainFrame:Show()
if not SM_Collections.CurrentTab then
SM_Collections:ShowTab(1)
SM_Collections:ShowTab(1)
end
end
end
@ -17,9 +17,9 @@ end
-- 处理坐骑数据
function SM_Collections:HandleMountsData(msg)
local data = self:MessageSplit(msg, "|")
for i=1, math.min(20, #data) do
for i = 1, math.min(20, #data) do
end
local mounts = {}
for i = 1, #data, 4 do
if data[i] and data[i + 1] and data[i + 2] and data[i + 3] then
@ -36,10 +36,10 @@ function SM_Collections:HandleMountsData(msg)
local success, result = pcall(function()
return GetSpellInfo(mountID)
end)
if success and result then
spellName = result
_, _, spellIcon = GetSpellInfo(mountID) -- 再次调用获取图标
_, _, spellIcon = GetSpellInfo(mountID) -- 再次调用获取图标
else
spellName = nil
spellIcon = nil
@ -51,12 +51,12 @@ function SM_Collections:HandleMountsData(msg)
table.insert(mounts, {
id = mountID,
name = data[i + 1] or spellName or ("坐骑 #" .. mountID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
name = data[i + 1] or spellName or ("坐骑 #" .. mountID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
description = data[i + 2],
obtained = data[i + 3] == "1",
displayID = displayID, -- 存储正确的显示ID
spellName = spellName, -- 存储从GetSpellInfo获取的名称作为备用
icon = spellIcon -- 存储图标
icon = spellIcon -- 存储图标
})
end
end
@ -86,7 +86,7 @@ function SM_Collections:HandleAttributesData(msg)
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.attributes then
local response = {
success = true,
@ -111,7 +111,7 @@ function SM_Collections:HandleItemAttributesData(msg)
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.item_attributes then
local response = {
success = true,
@ -120,14 +120,14 @@ function SM_Collections:HandleItemAttributesData(msg)
self.pendingCallbacks.item_attributes(response)
self.pendingCallbacks.item_attributes = nil
else
-- print("没有找到物品属性回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
-- print("没有找到物品属性回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
end
end
-- 处理小伙伴数据
function SM_Collections:HandleCompanionsData(msg)
local data = self:MessageSplit(msg, "|")
local companions = {}
for i = 1, #data, 4 do
if data[i] and data[i + 1] and data[i + 2] and data[i + 3] then
@ -137,7 +137,7 @@ function SM_Collections:HandleCompanionsData(msg)
if SM_Collections.Companions and SM_Collections.Companions[companionID] then
displayID = SM_Collections.Companions[companionID].effectMiscValue
end
-- 尝试从游戏中获取技能信息,添加错误处理
local spellName, spellRank, spellIcon
if companionID and type(companionID) == "number" and companionID > 0 then
@ -145,32 +145,32 @@ function SM_Collections:HandleCompanionsData(msg)
local success, result = pcall(function()
return GetSpellInfo(companionID)
end)
if success and result then
spellName = result
_, _, spellIcon = GetSpellInfo(companionID) -- 再次调用获取图标
_, _, spellIcon = GetSpellInfo(companionID) -- 再次调用获取图标
else
spellName = nil
spellIcon = nil
end
else
-- print("无效的companionID:", companionID)
-- print("无效的companionID:", companionID)
spellName = nil
spellIcon = nil
end
table.insert(companions, {
id = companionID,
name = data[i + 1] or spellName or ("小伙伴 #" .. companionID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
name = data[i + 1] or spellName or ("小伙伴 #" .. companionID), -- 如果服务端名称为空尝试使用GetSpellInfo获取或使用默认值
description = data[i + 2],
obtained = data[i + 3] == "1",
displayID = displayID, -- 存储正确的显示ID
spellName = spellName, -- 存储从GetSpellInfo获取的名称作为备用
icon = spellIcon -- 存储图标
icon = spellIcon -- 存储图标
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.companions then
-- 创建假的response对象标记成功获取了数据
local response = {
@ -180,35 +180,35 @@ function SM_Collections:HandleCompanionsData(msg)
self.pendingCallbacks.companions(response)
self.pendingCallbacks.companions = nil
else
-- print("没有找到回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
-- print("没有找到回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
end
end
-- 处理卡牌数据
function SM_Collections:HandleCardsData(msg)
print("处理卡牌数据= ",msg)
print("处理卡牌数据= ", msg)
local data = self:MessageSplit(msg, "|")
local cards = {}
-- 检查数据格式,尝试修复不规则的数据
if #data >= 4 then
local i = 1
while i <= #data do
local id, name, description, obtained
-- 尝试解析ID必须是数字
id = tonumber(data[i])
if id then
-- 获取名称
name = data[i + 1] or ""
-- 获取描述,如果描述不存在,尝试使用下一个字段
description = data[i + 2] or ""
-- 获取获得状态,尝试查找"1"或"0"
local obtainedStr = data[i + 3] or "0"
obtained = (obtainedStr == "1")
-- 创建卡牌对象
table.insert(cards, {
id = id,
@ -216,11 +216,11 @@ function SM_Collections:HandleCardsData(msg)
description = description,
obtained = obtained
})
-- 输出调试信息
print("解析卡牌: ID=", id, "名称=", name, "已获得=", obtained and "" or "")
end
-- 移动到下一组数据
i = i + 4
end
@ -234,7 +234,7 @@ function SM_Collections:HandleCardsData(msg)
self.pendingCallbacks.cards(response)
self.pendingCallbacks.cards = nil
else
-- print("没有找到卡牌回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
-- print("没有找到卡牌回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
end
end
@ -252,7 +252,7 @@ function SM_Collections:HandleItemsData(msg)
})
end
end
if self.pendingCallbacks and self.pendingCallbacks.items then
local response = {
success = true,
@ -261,7 +261,7 @@ function SM_Collections:HandleItemsData(msg)
self.pendingCallbacks.items(response)
self.pendingCallbacks.items = nil
else
-- print("没有找到物品回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
-- print("没有找到物品回调函数", self.pendingCallbacks and "回调表存在" or "回调表不存在")
end
end
@ -270,111 +270,168 @@ function SM_Collections:MessageSplit(msg, delimiter)
local result = {}
local from = 1
local delim_from, delim_to = string.find(msg, delimiter, from)
while delim_from do
table.insert(result, string.sub(msg, from, delim_from - 1))
from = delim_to + 1
delim_from, delim_to = string.find(msg, delimiter, from)
end
table.insert(result, string.sub(msg, from))
return result
end
-- 注册事件处理函数
function SM_Collections:RegisterEvents()
-- 初始化回调表
self.pendingCallbacks = {}
-- 注册收藏相关事件
self:RegisterEvent("ADDON_LOADED", function(event, addonName)
if addonName == "SM_CollectionSystem" then
print("收藏系统插件加载完成")
self:InitializeAddon()
end
end)
-- 注册服务器消息处理
self:RegisterEvent("CHAT_MSG_ADDON", function(event, prefix, message, channel, sender)
print("prefix= ",prefix)
if prefix == "SM_S_COLLECTIONS_MOUNTS" then
self:HandleMountsData(message)
elseif prefix == "SM_S_COLLECTIONS_COMPANIONS" then
self:HandleCompanionsData(message)
elseif prefix == "SM_S_COLLECTIONS_CARDS" then
self:HandleCardsData(message)
elseif prefix == "SM_S_COLLECTIONS_ITEMS" then
self:HandleItemsData(message)
elseif prefix == "SM_S_COLLECTION_UPDATE" then
self:HandleCollectionUpdate(message)
elseif prefix == "SM_S_BONUS_APPLIED" then
-- 处理属性加成应用成功的消息
print("|cFF00FFFF属性加成已应用|r")
-- 播放音效提示
PlaySound("LEVELUPSOUND")
end
end)
-- 注册其他事件
self:RegisterEvent("PLAYER_ENTERING_WORLD", function()
print("玩家进入世界,初始化收藏系统")
-- 延迟一下,确保其他系统已经加载
C_Timer.After(2, function()
self:InitializeAddon()
end)
end)
-- 注册收藏界面相关事件
self:RegisterCollectionEvents()
end
-- 处理收藏状态更新
function SM_Collections:HandleCollectionUpdate(msg)
print("处理收藏状态更新: ", msg)
local data = self:MessageSplit(msg, "|")
print("#data: ", #data)
if #data >= 3 then
local itemType = data[1]
local itemID = tonumber(data[2])
local isObtained = (data[3] == "1")
print("解析收藏更新: 类型=", itemType, "ID=", itemID, "已获得=", isObtained and "" or "")
if itemID and itemType then
-- 更新本地数据
if itemType == "mount" then
self.DataManager:UpdateMountStatus(itemID, isObtained)
print("已更新坐骑状态: ID=", itemID, "已获得=", isObtained and "" or "")
-- 如果是新获得的坐骑记录到NewItems表中
if isObtained then
self.NewItems.mount[itemID] = true
print("记录新获得的坐骑: ID=", itemID)
end
elseif itemType == "companion" then
self.DataManager:UpdateCompanionStatus(itemID, isObtained)
print("已更新小伙伴状态: ID=", itemID, "已获得=", isObtained and "" or "")
-- 如果是新获得的小伙伴记录到NewItems表中
if isObtained then
self.NewItems.companion[itemID] = true
print("记录新获得的小伙伴: ID=", itemID)
end
elseif itemType == "card" then
self.DataManager:UpdateCardStatus(itemID, isObtained)
print("已更新卡牌状态: ID=", itemID, "已获得=", isObtained and "" or "")
-- 如果是新获得的卡牌记录到NewItems表中
if isObtained then
self.NewItems.card[itemID] = true
print("记录新获得的卡牌: ID=", itemID)
end
elseif itemType == "item" then
self.DataManager:UpdateItemStatus(itemID, isObtained)
print("已更新物品状态: ID=", itemID, "已获得=", isObtained and "" or "")
-- 如果是新获得的物品记录到NewItems表中
if isObtained then
self.NewItems.item[itemID] = true
print("记录新获得的物品: ID=", itemID)
end
end
print("MainFrame存在:", self.MainFrame and "" or "")
-- 检查当前是否显示了对应类型的面板
local isCurrentPanel = false
if self.MainFrame and self.MainFrame.tabID then
if (itemType == "mount" and self.MainFrame.tabID == 1) or
(itemType == "companion" and self.MainFrame.tabID == 2) or
(itemType == "card" and self.MainFrame.tabID == 3) or
(itemType == "item" and self.MainFrame.tabID == 4) then
isCurrentPanel = true
if self.MainFrame then
-- 如果tabID为nil尝试从CurrentPanel推断当前面板类型
local inferredTabID = nil
if not self.MainFrame.tabID and self.CurrentPanel then
-- 检查当前面板中的按钮数据类型
if self.CurrentPanel.scrollChild and self.CurrentPanel.scrollChild.buttons and #self.CurrentPanel.scrollChild.buttons > 0 then
local firstButton = self.CurrentPanel.scrollChild.buttons[1]
print("第一个按钮信息: ", firstButton and "存在" or "不存在")
if firstButton then
print("按钮itemType: ", firstButton.itemType or "nil")
print("按钮itemData: ", firstButton.itemData and "存在" or "不存在")
end
if firstButton and firstButton.itemType then
if firstButton.itemType == "mount" then
inferredTabID = 1
elseif firstButton.itemType == "companion" then
inferredTabID = 2
elseif firstButton.itemType == "card" then
inferredTabID = 3
elseif firstButton.itemType == "item" then
inferredTabID = 4
end
print("从当前面板推断tabID:", inferredTabID)
end
end
end
local effectiveTabID = self.MainFrame.tabID or inferredTabID
print("有效tabID:", effectiveTabID)
if effectiveTabID then
if (itemType == "mount" and effectiveTabID == 1) or
(itemType == "companion" and effectiveTabID == 2) or
(itemType == "card" and effectiveTabID == 3) or
(itemType == "item" and effectiveTabID == 4) then
isCurrentPanel = true
end
end
end
print("当前面板ID: ", self.MainFrame and self.MainFrame.tabID or "nil")
print("当前面板是否匹配: ", isCurrentPanel and "" or "")
-- 刷新UI
-- 无论当前面板是什么都尝试刷新UI
-- 如果不是当前面板RefreshCollectionStatus函数内部会自己处理
self:RefreshCollectionStatus(itemType, itemID, isObtained)
-- 如果是卡牌且当前显示的是卡牌面板,强制重新加载
if itemType == "card" and isCurrentPanel then
print("强制重新加载卡牌面板")
-- 延迟一帧执行,确保其他处理完成
C_Timer.After(0.1, function()
self:ShowCards()
-- 使用 3.3.5 支持的延迟执行方法
local cardReloadFrame = CreateFrame("Frame")
cardReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
SM_Collections:ShowCards()
end
end)
cardReloadFrame:Show()
end
-- 如果是卡牌且获得了新卡牌,强制重新加载卡牌面板
if itemType == "card" and isObtained and not isCurrentPanel then
print("获得新卡牌,强制重新加载卡牌数据")
-- 更新本地数据,但不切换面板
local cardDataReloadFrame = CreateFrame("Frame")
cardDataReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
-- 重新获取卡牌数据,但不显示
SM_Collections.DataManager:GetCards(function(cards)
print("卡牌数据已更新,共", #cards, "张卡牌")
end)
end
end)
cardDataReloadFrame:Show()
end
-- 如果是小伙伴且获得了新的小伙伴,强制重新加载小伙伴面板
if itemType == "companion" and isObtained then
print("强制重新加载小伙伴面板")
-- 使用 3.3.5 支持的延迟执行方法
local companionReloadFrame = CreateFrame("Frame")
companionReloadFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then
self:SetScript("OnUpdate", nil)
self:Hide()
if SM_Collections.MainFrame and SM_Collections.MainFrame.tabID == 2 then
SM_Collections:ShowCompanions()
end
end
end)
companionReloadFrame:Show()
end
end
else
@ -386,17 +443,22 @@ end
function SM_Collections_MessageEvent(self, event, prefix, msg, type, sender)
if event == 'CHAT_MSG_WHISPER' or event == 'CHAT_MSG_ADDON' then
if prefix == 'SM_S_COLLECTIONS_MOUNTS' then
SM_Collections:HandleMountsData(msg) -- 坐骑
SM_Collections:HandleMountsData(msg) -- 坐骑
elseif prefix == 'SM_S_COLLECTIONS_COMPANIONS' then
SM_Collections:HandleCompanionsData(msg) -- 小伙伴
SM_Collections:HandleCompanionsData(msg) -- 小伙伴
elseif prefix == 'SM_S_COLLECTIONS_CARDS' then
SM_Collections:HandleCardsData(msg) -- 卡牌
SM_Collections:HandleCardsData(msg) -- 卡牌
elseif prefix == 'SM_S_COLLECTIONS_ITEMS' then
SM_Collections:HandleItemsData(msg) -- 物品
SM_Collections:HandleItemsData(msg) -- 物品
elseif prefix == 'SM_S_COLLECTIONS_ATTRIBUTES' then
SM_Collections:HandleAttributesData(msg) -- 属性
SM_Collections:HandleAttributesData(msg) -- 属性
elseif prefix == 'SM_S_COLLECTIONS_ITEM_ATTRIBUTES' then
SM_Collections:HandleItemAttributesData(msg) -- 物品属性
elseif prefix == "SM_S_COLLECTION_UPDATE" then
print("SM_S_COLLECTION_UPDATE= ", msg)
SM_Collections:HandleCollectionUpdate(msg) --404行
end
end
end
@ -417,6 +479,11 @@ SM_Collections_EventFrame:SetScript('OnEvent', function(self, event, ...)
SM_Collections_MessageEvent(self, event, ...)
if not SM_Collections.MainFrame then
SM_Collections:CreateMainFrame()
-- 确保设置了默认的tabID
if SM_Collections.MainFrame then
SM_Collections.MainFrame.tabID = SM_Collections.MainFrame.tabID or 1
print("创建MainFrame并设置默认tabID:", SM_Collections.MainFrame.tabID)
end
SM_Collections.MainFrame:Hide()
end
elseif event == 'CHAT_MSG_WHISPER' then
@ -424,12 +491,12 @@ SM_Collections_EventFrame:SetScript('OnEvent', function(self, event, ...)
-- 检查消息格式,判断是否是我们的插件消息
local prefix, content = strsplit("\t", msg, 2)
if content and (prefix == "SM_S_COLLECTIONS_MOUNTS" or
prefix == "SM_S_COLLECTIONS_COMPANIONS" or
prefix == "SM_S_COLLECTIONS_CARDS" or
prefix == "SM_S_COLLECTIONS_ITEMS" or
prefix == "SM_S_COLLECTIONS_ATTRIBUTES" or
prefix == "SM_S_COLLECTIONS_ITEM_ATTRIBUTES") then
prefix == "SM_S_COLLECTIONS_COMPANIONS" or
prefix == "SM_S_COLLECTIONS_CARDS" or
prefix == "SM_S_COLLECTIONS_ITEMS" or
prefix == "SM_S_COLLECTIONS_ATTRIBUTES" or
prefix == "SM_S_COLLECTIONS_ITEM_ATTRIBUTES") then
SM_Collections_MessageEvent(self, "CHAT_MSG_WHISPER", prefix, content)
end
end
end)
end)

View File

@ -6,7 +6,7 @@
-- 在这里添加点击处理逻辑
function OnItemClick(button, itemData, itemType, panel)
print("点击了物品:", itemData.id, "类型:", itemType)
-- 设置按钮选中状态
if button then
-- 取消其他按钮的选中状态
@ -20,7 +20,7 @@ function OnItemClick(button, itemData, itemType, panel)
end
end
end
-- 设置当前按钮为选中状态
button.isSelected = true
if button.selectedTexture then
@ -28,7 +28,7 @@ function OnItemClick(button, itemData, itemType, panel)
end
print("设置按钮选中状态:", button.isSelected and "已选中" or "未选中")
end
-- 更新名称和描述
if SM_Collections.MainFrame and SM_Collections.MainFrame.RightSidePanel then
-- 获取显示名称(服务端名称或游戏内名称)
@ -46,7 +46,7 @@ function OnItemClick(button, itemData, itemType, panel)
spellName = nil
end
end
if spellName and spellName ~= "" then
displayName = spellName
else
@ -54,21 +54,21 @@ function OnItemClick(button, itemData, itemType, panel)
displayName = "ID: " .. itemData.id
end
end
-- 更新名称
if SM_Collections.MainFrame.RightSidePanel.MountNama then
SM_Collections.MainFrame.RightSidePanel.MountNama:SetText(displayName or "")
print("更新右侧面板名称为:", displayName)
SM_Collections.MainFrame.RightSidePanel.MountNama:Show()
end
-- 更新描述
if SM_Collections.MainFrame.RightSidePanel.introText then
SM_Collections.MainFrame.RightSidePanel.introText:SetText(itemData.description or "")
SM_Collections.MainFrame.RightSidePanel.introText:Show()
end
end
-- 更新模型
local creatureDisplayID = nil
-- 如果服务端已经提供了displayID优先使用它
@ -79,7 +79,7 @@ function OnItemClick(button, itemData, itemType, panel)
-- 否则从映射表中获取
creatureDisplayID = SM_Collections:GetCreatureDisplayID(itemData.id, itemType)
end
if panel and panel.model and creatureDisplayID and creatureDisplayID > 0 then
panel.model:Hide()
panel.model:SetPosition(0, 0, 0)
@ -88,15 +88,15 @@ function OnItemClick(button, itemData, itemType, panel)
panel.model:SetCreature(creatureDisplayID)
print("点击显示模型ID = " .. creatureDisplayID)
else
print("无法显示模型: ",
panel and "面板存在" or "面板不存在",
panel and panel.model and "模型存在" or "模型不存在",
creatureDisplayID and creatureDisplayID > 0 and "有效的显示ID" or "无效的显示ID")
print("无法显示模型: ",
panel and "面板存在" or "面板不存在",
panel and panel.model and "模型存在" or "模型不存在",
creatureDisplayID and creatureDisplayID > 0 and "有效的显示ID" or "无效的显示ID")
end
-- 更新右侧面板的属性加成
SM_Collections:UpdateRightPanel(itemData, itemType)
-- 添加类型图标和文本
if panel then
SM_Collections:UpdateTypeIcon(panel, itemData, itemType)
@ -310,13 +310,13 @@ function SM_Collections:CreateSplitPanel(parent, data, itemType)
-- 创建列表项
self:CreateListItems(scrollChild, data, itemType, model, nameText, descText)
-- 设置初始选中项:优先选择已获得的物品,如果没有则选择第一个
if scrollChild.obtainedButtons and #scrollChild.obtainedButtons > 0 then
-- 随机选择一个已获得的物品
local randomIndex = math.random(1, #scrollChild.obtainedButtons)
local selectedButton = scrollChild.obtainedButtons[randomIndex]
-- 手动触发点击事件
if selectedButton and selectedButton.itemData then
OnItemClick(selectedButton, selectedButton.itemData, itemType, panel)
@ -324,13 +324,13 @@ function SM_Collections:CreateSplitPanel(parent, data, itemType)
elseif scrollChild.buttons and #scrollChild.buttons > 0 then
-- 如果没有已获得的物品,选择第一个
local firstButton = scrollChild.buttons[1]
-- 手动触发点击事件
if firstButton and firstButton.itemData then
OnItemClick(firstButton, firstButton.itemData, itemType, panel)
end
end
-- 绑定当前panel便于切换标签时只隐藏panel不隐藏模型区
if self.CurrentPanel then
self.CurrentPanel:Hide()
@ -347,18 +347,18 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
if itemType == "card" then
buttonW = 200
end
-- 存储所有按钮的引用,以便后续选中操作
local buttons = {}
local obtainedButtons = {}
for i, item in ipairs(data) do
local button = CreateFrame("Button", "Collectionsbutton" .. i, parent)
button:SetSize(buttonW, buttonHeight)
button:SetPoint("TOPLEFT", 30, -(i - 1) * (buttonHeight + spacing))
button:SetNormalTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\liebiaoditu_kuang_A")
button:SetHighlightTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\liebiaoditu_kuang_B")
-- 添加选中状态纹理
local selectedTexture = button:CreateTexture(nil, "OVERLAY")
selectedTexture:SetAllPoints(button)
@ -367,17 +367,38 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
selectedTexture:SetVertexColor(1, 1, 0, 0.5) -- 金黄色高亮
selectedTexture:Hide()
button.selectedTexture = selectedTexture
-- 存储物品数据和选中状态
button.itemData = item
button.isSelected = false
button.itemType = itemType -- 添加itemType属性用于推断面板类型
-- 添加"NEW"标记,如果这个项目是新获得的
if item.obtained and self.NewItems and self.NewItems[itemType] and self.NewItems[itemType][item.id] then
local newTexture = button:CreateTexture(nil, "OVERLAY")
newTexture:SetSize(32, 28)
newTexture:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, -5)
newTexture:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\New_Icon")
button.newTexture = newTexture
-- 在鼠标悬停时隐藏"NEW"标记
button:HookScript("OnEnter", function(self)
if self.newTexture then
self.newTexture:Hide()
-- 从NewItems表中移除
if SM_Collections.NewItems and SM_Collections.NewItems[itemType] then
SM_Collections.NewItems[itemType][item.id] = nil
end
end
end)
end
local ButtonIcon = nil
if itemType == "mount" or itemType == "companion" then
ButtonIcon = CreateFrame("Button", "CollectionsButtonIcon" .. i, button)
ButtonIcon:SetSize(iconSize, iconSize)
ButtonIcon:SetPoint("RIGHT", button, "LEFT", 0, 0)
-- 安全地调用GetSpellInfo
local name, rank, icon
if item.id and type(item.id) == "number" and item.id > 0 then
@ -386,13 +407,13 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
end)
if success and result then
name = result
_, _, icon = GetSpellInfo(item.id) -- 再次调用获取图标
_, _, icon = GetSpellInfo(item.id) -- 再次调用获取图标
else
name = nil
icon = nil
end
end
if icon then
ButtonIcon:SetNormalTexture(icon)
ButtonIcon:SetHighlightTexture(icon)
@ -427,7 +448,7 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
else
text:SetPoint("LEFT", 10, 0)
end
-- 名称显示优先级:服务端名称 > GetSpellInfo名称 > 默认名称
local displayName = item.name
if not displayName or displayName == "" then
@ -443,7 +464,7 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
spellName = nil
end
end
if spellName and spellName ~= "" then
displayName = spellName
else
@ -451,11 +472,14 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
displayName = "ID: " .. item.id
end
end
--print("列表项显示名称:", displayName, "原始名称:", item.name)
text:SetText(displayName)
text:SetTextColor(item.obtained and 1 or 0.5, item.obtained and 1 or 0.5, item.obtained and 1 or 0.5)
-- 保存文本对象的引用,以便后续更新
button.text = text
-- 选中处理函数
local function selectButton(btn)
-- 取消其他按钮的选中状态
@ -465,20 +489,20 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
otherBtn.selectedTexture:Hide()
end
end
-- 设置当前按钮为选中状态
btn.isSelected = true
btn.selectedTexture:Show()
-- 更新模型和信息
local panel = self.CurrentPanel
OnItemClick(btn, btn.itemData, itemType, panel)
end
button:SetScript("OnClick", function()
selectButton(button)
end)
-- 在鼠标悬停时在工具提示中显示获得状态
button:SetScript("OnEnter", function()
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
@ -494,16 +518,16 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
end)
button:Show()
-- 添加到按钮列表
table.insert(buttons, button)
-- 如果是已获得的物品,添加到已获得列表
if item.obtained then
table.insert(obtainedButtons, button)
end
end
-- 设置初始选中项:优先选择已获得的物品,如果没有则选择第一个
if #obtainedButtons > 0 then
-- 随机选择一个已获得的物品
@ -511,7 +535,7 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
local selectedButton = obtainedButtons[randomIndex]
selectedButton.isSelected = true
selectedButton.selectedTexture:Show()
-- 更新模型和信息
local panel = self.CurrentPanel
OnItemClick(selectedButton, selectedButton.itemData, itemType, panel)
@ -520,15 +544,15 @@ function SM_Collections:CreateListItems(parent, data, itemType, model, nameText,
local firstButton = buttons[1]
firstButton.isSelected = true
firstButton.selectedTexture:Show()
-- 更新模型和信息
local panel = self.CurrentPanel
OnItemClick(firstButton, firstButton.itemData, itemType, panel)
end
local totalHeight = #data * (buttonHeight + spacing)
parent:SetHeight(math.max(totalHeight, 1))
-- 保存按钮引用到面板中,以便后续访问
parent.buttons = buttons
parent.obtainedButtons = obtainedButtons
@ -540,8 +564,8 @@ function SM_Collections:UpdateRightPanel(selectedItem, itemType)
return
end
local rightPanel = self.MainFrame.RightSidePanel
-- print("UpdateRightPanel: 更新右侧面板物品ID:", selectedItem.id, "类型:", itemType)
-- print("UpdateRightPanel: 更新右侧面板物品ID:", selectedItem.id, "类型:", itemType)
-- 更新坐骑名称
if rightPanel.MountNama then
@ -549,15 +573,15 @@ function SM_Collections:UpdateRightPanel(selectedItem, itemType)
local displayName = selectedItem.name
if not displayName or displayName == "" then
local spellName = GetSpellInfo(selectedItem.id)
displayName = spellName or "ID: "..selectedItem.id
displayName = spellName or "ID: " .. selectedItem.id
end
-- print("UpdateRightPanel: 设置名称为:", displayName)
-- print("UpdateRightPanel: 设置名称为:", displayName)
rightPanel.MountNama:SetText(displayName or "")
rightPanel.MountNama:Show()
-- 检查文本框的各种属性
-- print("名称文本框状态: 可见=", rightPanel.MountNama:IsVisible(),
-- print("名称文本框状态: 可见=", rightPanel.MountNama:IsVisible(),
-- "层级=", rightPanel.MountNama:GetDrawLayer(),
-- "宽高=", rightPanel.MountNama:GetWidth(), rightPanel.MountNama:GetHeight(),
-- "位置=", rightPanel.MountNama:GetPoint())
@ -591,7 +615,7 @@ function SM_Collections:UpdateAttributesForItem(item, parentFrame, itemType)
text:Hide()
end
end
self:GetAttributesForItem(item, function(attributes)
if #attributes == 0 then
parentFrame:Hide()
@ -612,20 +636,20 @@ function SM_Collections:UpdateAttributesForItem(item, parentFrame, itemType)
nameText:SetPoint("CENTER", 0, 0)
nameText:SetFont("Fonts\\ZYKai_T.ttf", 10, "MONOCHROME")
nameText:SetText(AttributeName)
-- 根据物品是否获得设置文本颜色
if item.obtained then
nameText:SetTextColor(1, 1, 1) -- 已获得:白色
nameText:SetTextColor(1, 1, 1) -- 已获得:白色
else
nameText:SetTextColor(0.5, 0.5, 0.5) -- 未获得:灰色
end
local valueText = button:CreateFontString(nil, "OVERLAY")
valueText:SetPoint("RIGHT", -5, 0)
valueText:SetFont("Fonts\\ZYKai_T.ttf", 10, "MONOCHROME")
local formattedValue = isPositive and ("+ " .. AttributeValue) or ("- " .. AttributeValue)
valueText:SetText(formattedValue)
-- 根据物品是否获得设置属性值颜色
if item.obtained then
-- 已获得:根据属性是正面还是负面设置颜色
@ -634,7 +658,7 @@ function SM_Collections:UpdateAttributesForItem(item, parentFrame, itemType)
-- 未获得:灰色
valueText:SetTextColor(0.5, 0.5, 0.5)
end
button:Show()
end
end, itemType)
@ -694,11 +718,11 @@ function SM_Collections:UpdateTypeIcon(panel, item, itemType)
-- 卡牌类型判断
local cardType = "普通"
local icon = "Interface\\ICONS\\INV_Misc_Book_07"
-- 1. 首先检查item.cardType如果服务器提供了类型信息优先使用
if item.cardType then
cardType = item.cardType
-- 根据cardType设置对应的图标
if cardType == "精英" then
icon = "Interface\\ICONS\\Ability_Warrior_ChallengingShout"
@ -707,29 +731,29 @@ function SM_Collections:UpdateTypeIcon(panel, item, itemType)
elseif cardType == "世界BOSS" then
icon = "Interface\\ICONS\\Ability_Creature_Cursed_05"
end
-- 2. 如果没有cardType我们可以尝试从名称或描述中推断
-- 2. 如果没有cardType我们可以尝试从名称或描述中推断
else
-- 检查名称或描述中是否包含关键词
local name = item.name or ""
local desc = item.description or ""
local combinedText = name .. " " .. desc
-- 转换为小写以便不区分大小写匹配
combinedText = string.lower(combinedText)
-- 检查关键词
if string.find(combinedText, "首领") or
string.find(combinedText, "boss") or
string.find(combinedText, "世界boss") or
string.find(combinedText, "团队boss") then
string.find(combinedText, "boss") or
string.find(combinedText, "世界boss") or
string.find(combinedText, "团队boss") then
cardType = "世界BOSS"
icon = "Interface\\ICONS\\Ability_Creature_Cursed_05"
elseif string.find(combinedText, "稀有") or
string.find(combinedText, "rare") then
string.find(combinedText, "rare") then
cardType = "稀有"
icon = "Interface\\ICONS\\INV_Misc_Gem_Pearl_05"
elseif string.find(combinedText, "精英") or
string.find(combinedText, "elite") then
string.find(combinedText, "elite") then
cardType = "精英"
icon = "Interface\\ICONS\\Ability_Warrior_ChallengingShout"
end
@ -751,91 +775,177 @@ function SM_Collections:CreateTypeIcon(panel)
local typeIcon = CreateFrame("Frame", nil, panel.model)
typeIcon:SetSize(40, 40)
typeIcon:SetPoint("TOPRIGHT", panel.model, "TOPRIGHT", -10, -10)
-- 创建外框纹理
local border = typeIcon:CreateTexture(nil, "OVERLAY")
border:SetSize(38, 38)
border:SetPoint("CENTER", typeIcon, "CENTER", 0, 0)
border:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\Cir_Overlay")
typeIcon.border = border
-- 创建图标
local icon = typeIcon:CreateTexture(nil, "BACKGROUND")
icon:SetSize(30, 30)
icon:SetPoint("CENTER", typeIcon, "CENTER", 0, 0)
typeIcon.icon = icon
-- 创建文本
local typeText = typeIcon:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
typeText:SetPoint("BOTTOM", icon, "BOTTOM", 0, -15)
typeText:SetTextColor(1, 1, 1)
typeIcon.typeText = typeText
panel.typeIcon = typeIcon
end
return panel.typeIcon
end
-- 刷新收藏状态
function SM_Collections:RefreshCollectionStatus(itemType, itemID, isObtained)
print("刷新收藏状态: 类型=", itemType, "ID=", itemID, "已获得=", isObtained and "" or "")
-- 如果当前没有显示面板,不需要刷新
if not self.CurrentPanel or not self.CurrentPanel.scrollChild then
print("当前没有显示面板,跳过刷新")
return
end
local buttons = self.CurrentPanel.scrollChild.buttons
if not buttons then
print("没有找到按钮列表,跳过刷新")
return
end
-- 检查当前是否显示了对应类型的面板
local isCorrectPanel = false
if self.MainFrame and self.MainFrame.tabID then
if (itemType == "mount" and self.MainFrame.tabID == 1) or
(itemType == "companion" and self.MainFrame.tabID == 2) or
(itemType == "card" and self.MainFrame.tabID == 3) or
(itemType == "item" and self.MainFrame.tabID == 4) then
isCorrectPanel = true
-- 尝试从当前面板的按钮数据推断面板类型
local inferredPanelType = nil
if #buttons > 0 and buttons[1].itemData then
-- 检查第一个按钮的数据类型
local firstButtonData = buttons[1].itemData
-- 可以检查buttons[1].itemType如果存在的话
if buttons[1].itemType then
inferredPanelType = buttons[1].itemType
print("从按钮推断面板类型: ", inferredPanelType)
end
end
-- 如果是小伙伴类型,特殊处理
if itemType == "companion" then
-- 检查是否有任何按钮的ID匹配
for _, button in ipairs(buttons) do
if button.itemData and button.itemData.id == itemID then
isCorrectPanel = true
print("小伙伴特殊处理: 找到匹配按钮,强制设置面板类型正确")
break
end
end
end
-- 如果是卡牌类型,也进行特殊处理
if itemType == "card" then
-- 检查是否有任何按钮的ID匹配
for _, button in ipairs(buttons) do
if button.itemData and button.itemData.id == itemID then
isCorrectPanel = true
print("卡牌特殊处理: 找到匹配按钮,强制设置面板类型正确")
break
end
end
end
-- 如果MainFrame.tabID存在使用它否则尝试使用推断的面板类型
if not isCorrectPanel and self.MainFrame and self.MainFrame.tabID then
if (itemType == "mount" and self.MainFrame.tabID == 1) or
(itemType == "companion" and self.MainFrame.tabID == 2) or
(itemType == "card" and self.MainFrame.tabID == 3) or
(itemType == "item" and self.MainFrame.tabID == 4) then
isCorrectPanel = true
end
elseif not isCorrectPanel and inferredPanelType and itemType == inferredPanelType then
-- 如果推断出的面板类型与更新的项目类型匹配
isCorrectPanel = true
print("通过推断确定当前面板类型:", inferredPanelType)
elseif not isCorrectPanel then
-- 尝试直接检查按钮数据是否包含要更新的项目ID
for _, button in ipairs(buttons) do
if button.itemData and button.itemData.id == itemID then
isCorrectPanel = true
print("通过按钮ID匹配确定面板类型正确")
break
end
end
end
if not isCorrectPanel then
print("当前面板类型不匹配跳过UI刷新")
return
end
print("开始查找匹配按钮,共有", #buttons, "个按钮")
-- 查找对应的按钮并更新状态
local updatedButton = nil
local buttonFound = false
for i, button in ipairs(buttons) do
if button.itemData and button.itemData.id == itemID then
buttonFound = true
print("找到匹配按钮: 索引=", i, "原状态=", button.itemData.obtained and "已获得" or "未获得")
-- 更新获取状态
button.itemData.obtained = isObtained
-- 更新文本颜色
local text = button:GetRegions()
if text and text:GetObjectType() == "FontString" then
text:SetTextColor(isObtained and 1 or 0.5, isObtained and 1 or 0.5, isObtained and 1 or 0.5)
print("已更新按钮文本颜色")
if button.text then
-- 使用保存的文本对象引用
button.text:SetTextColor(isObtained and 1 or 0.5, isObtained and 1 or 0.5, isObtained and 1 or 0.5)
print("已更新按钮文本颜色(使用保存的引用)")
else
-- 尝试获取文本对象
local text = button:GetRegions()
if text and text:GetObjectType() == "FontString" then
text:SetTextColor(isObtained and 1 or 0.5, isObtained and 1 or 0.5, isObtained and 1 or 0.5)
print("已更新按钮文本颜色使用GetRegions")
else
print("无法找到按钮文本对象")
end
end
-- 如果是新获得的项目,添加"NEW"标记
if isObtained and self.NewItems and self.NewItems[itemType] and self.NewItems[itemType][itemID] then
-- 检查是否已经有NEW标记
if not button.newTexture then
local newTexture = button:CreateTexture(nil, "OVERLAY")
newTexture:SetSize(32, 28)
newTexture:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, -5)
newTexture:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\New_Icon")
button.newTexture = newTexture
-- 在鼠标悬停时隐藏"NEW"标记
button:HookScript("OnEnter", function(self)
if self.newTexture then
self.newTexture:Hide()
-- 从NewItems表中移除
if SM_Collections.NewItems and SM_Collections.NewItems[itemType] then
SM_Collections.NewItems[itemType][itemID] = nil
end
end
end)
else
-- 如果已经有NEW标记确保它是可见的
button.newTexture:Show()
end
end
-- 如果是当前选中的按钮,更新右侧面板
if button.isSelected then
updatedButton = button
print("这是当前选中的按钮,将更新右侧面板")
end
-- 更新已获得按钮列表
local obtainedButtons = self.CurrentPanel.scrollChild.obtainedButtons or {}
if isObtained then
@ -862,45 +972,46 @@ function SM_Collections:RefreshCollectionStatus(itemType, itemID, isObtained)
end
end
self.CurrentPanel.scrollChild.obtainedButtons = obtainedButtons
-- 重新排序按钮
self:ResortCollectionButtons(self.CurrentPanel.scrollChild, itemType)
break
end
end
if not buttonFound then
print("未找到匹配按钮ID=", itemID)
end
-- 如果更新的是当前选中的项目,刷新右侧面板
if updatedButton then
local panel = self.CurrentPanel
print("手动触发点击事件更新右侧面板")
OnItemClick(updatedButton, updatedButton.itemData, itemType, panel)
end
-- 通知玩家
if isObtained then
local typeName = itemType == "mount" and "坐骑" or itemType == "companion" and "小伙伴" or itemType == "card" and "卡牌" or "物品"
local typeName = itemType == "mount" and "坐骑" or itemType == "companion" and "小伙伴" or itemType == "card" and "卡牌" or
"物品"
local itemName = ""
-- 尝试获取物品名称
if updatedButton and updatedButton.itemData then
itemName = updatedButton.itemData.name or ""
end
-- 显示通知
if itemName and itemName ~= "" then
print("|cFF00FF00新收藏解锁:|r " .. typeName .. " - " .. itemName)
else
print("|cFF00FF00新收藏解锁:|r " .. typeName .. " (ID: " .. itemID .. ")")
end
-- 播放获得音效
PlaySound("UI_EpicLootWon")
-- 应用属性加成 - 请求服务器重新应用属性
SendAddonMessage("SM_C_APPLY_BONUS", itemType .. "|" .. itemID, "WHISPER", UnitName("player"))
end
@ -911,9 +1022,9 @@ function SM_Collections:ResortCollectionButtons(scrollChild, itemType)
if not scrollChild or not scrollChild.buttons then
return
end
local buttons = scrollChild.buttons
-- 按照已获得状态排序
table.sort(buttons, function(a, b)
if a.itemData.obtained and not b.itemData.obtained then
@ -925,21 +1036,29 @@ function SM_Collections:ResortCollectionButtons(scrollChild, itemType)
return a.itemData.id < b.itemData.id
end
end)
-- 重新设置位置
local buttonHeight = 40
local spacing = 2
for i, button in ipairs(buttons) do
button:ClearAllPoints()
button:SetPoint("TOPLEFT", 30, -(i - 1) * (buttonHeight + spacing))
-- 根据不同类型设置不同的位置
if itemType == "card" then
-- 卡牌类型使用特殊的位置设置
button:SetPoint("TOPLEFT", 0, -(i - 1) * (buttonHeight + spacing))
else
-- 其他类型使用标准位置设置
button:SetPoint("TOPLEFT", 30, -(i - 1) * (buttonHeight + spacing))
end
end
print("已重新排序按钮,共", #buttons, "个按钮")
end
-- 注册事件处理
function SM_Collections:RegisterCollectionEvents()
print("注册事件处理")
-- 监听收藏状态更新事件
self:RegisterEvent("ADDON_MESSAGE_PREFIX_SM_S_COLLECTION_UPDATE", function(prefix, message)
local data = self:MessageSplit(message, "|")
@ -947,7 +1066,7 @@ function SM_Collections:RegisterCollectionEvents()
local itemType = data[1]
local itemID = tonumber(data[2])
local isObtained = (data[3] == "1")
if itemID and itemType then
self:RefreshCollectionStatus(itemType, itemID, isObtained)
end

BIN
Textures/New_Icon.blp Normal file

Binary file not shown.

Binary file not shown.