功能多文件分块化处理第一版
This commit is contained in:
parent
49e1df3164
commit
b882530620
File diff suppressed because it is too large
Load Diff
@ -6,5 +6,10 @@
|
||||
|
||||
################################
|
||||
#SM_CollectionSystem.xml
|
||||
CreatureDisplay.lua
|
||||
SM_CollectionSystem.lua
|
||||
SM_CollectionSystem.lua
|
||||
SM_DataProvider.lua
|
||||
SM_UI_MainFrame.lua
|
||||
SM_UI_SplitPanel.lua
|
||||
SM_Utils.lua
|
||||
SM_Events.lua
|
||||
CreatureDisplay.lua
|
||||
348
SM_DataProvider.lua
Normal file
348
SM_DataProvider.lua
Normal file
@ -0,0 +1,348 @@
|
||||
-- SM_DataProvider.lua
|
||||
|
||||
-- 数据提供者基类
|
||||
SM_Collections.DataProvider = {}
|
||||
function SM_Collections.DataProvider:new()
|
||||
local obj = {}
|
||||
setmetatable(obj, self)
|
||||
self.__index = self
|
||||
return obj
|
||||
end
|
||||
function SM_Collections.DataProvider:GetMounts(callback) error("GetMounts must be implemented by subclass") end
|
||||
function SM_Collections.DataProvider:GetCompanions(callback) error("GetCompanions must be implemented by subclass") end
|
||||
function SM_Collections.DataProvider:GetCards(callback) error("GetCards must be implemented by subclass") end
|
||||
function SM_Collections.DataProvider:GetItems(callback) error("GetItems must be implemented by subclass") end
|
||||
function SM_Collections.DataProvider:GetAttributes(callback) error("GetAttributes must be implemented by subclass") end
|
||||
function SM_Collections.DataProvider:GetAttributesForSpecificItem(itemId, itemType, callback) error("GetAttributesForSpecificItem must be implemented by subclass") end
|
||||
|
||||
-- 本地数据提供者
|
||||
SM_Collections.LocalDataProvider = SM_Collections.DataProvider:new()
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetMounts(callback)
|
||||
local mounts = {
|
||||
{ id = 458, name = "棕色马", description = "暴风城卫兵的最爱", obtained = true },
|
||||
{ id = 459, name = "灰狼", description = "喜欢在雾中狩猎的狼", obtained = true },
|
||||
{ id = 468, name = "白色骏马", description = "强大不屈的白色骏马", obtained = false },
|
||||
{ id = 470, name = "黑色骏马", description = "据说SI:7夜间任务的首选", obtained = true },
|
||||
{ id = 578, name = "黑狼", description = "嚎叫声能传播数英里", obtained = false },
|
||||
{ id = 468, name = "白色骏马", description = "强大不屈的白色骏马", obtained = false },
|
||||
{ id = 470, name = "黑色骏马", description = "据说SI:7夜间任务的首选", obtained = true },
|
||||
{ id = 578, name = "黑狼", description = "嚎叫声能传播数英里", obtained = false },
|
||||
{ id = 458, name = "棕色马", description = "暴风城卫兵的最爱", obtained = true },
|
||||
{ id = 458, name = "棕色马", description = "暴风城卫兵的最爱", obtained = true },
|
||||
{ id = 459, name = "灰狼", description = "喜欢在雾中狩猎的狼", obtained = true },
|
||||
{ id = 468, name = "白色骏马", description = "强大不屈的白色骏马", obtained = false },
|
||||
{ id = 470, name = "黑色骏马", description = "据说SI:7夜间任务的首选", obtained = true },
|
||||
{ id = 578, name = "黑狼", description = "嚎叫声能传播数英里", obtained = false },
|
||||
{ id = 468, name = "白色骏马", description = "强大不屈的白色骏马", obtained = false },
|
||||
{ id = 470, name = "黑色骏马", description = "据说SI:7夜间任务的首选", obtained = true },
|
||||
{ id = 578, name = "黑狼", description = "嚎叫声能传播数英里", obtained = false },
|
||||
{ id = 458, name = "棕色马", description = "暴风城卫兵的最爱", obtained = true },
|
||||
}
|
||||
if SM_Collections.Config.Debug then
|
||||
print("LocalDataProvider: 返回", #mounts, "个坐骑")
|
||||
end
|
||||
callback(mounts)
|
||||
end
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetCompanions(callback)
|
||||
local companions = {
|
||||
{ id = 62508, name = "丹莫罗熊宝宝", description = "一只可爱的小猫", obtained = true },
|
||||
{ id = 28871, name = "仲夏之魂", description = "一只忠诚的小狗", obtained = false },
|
||||
{ id = 13548, name = "农场小鸡", description = "一只活泼的兔子", obtained = true },
|
||||
{ id = 23811, name = "冬天爷爷的小助手", description = "一只会唱歌的鸟", obtained = false },
|
||||
}
|
||||
callback(companions)
|
||||
end
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetCards(callback)
|
||||
local cards = {
|
||||
{ id = 11502, name = "拉格纳罗斯", description = "火焰之王", obtained = true },
|
||||
{ id = 24248, name = "巫妖王阿尔萨斯", description = "亡灵天灾的领袖", obtained = false },
|
||||
{ id = 19299, name = "死亡耳语者", description = "毁灭者", obtained = true },
|
||||
{ id = 32588, name = "伊利丹·怒风", description = "背叛者", obtained = false },
|
||||
}
|
||||
callback(cards)
|
||||
end
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetItems(callback)
|
||||
local items = {
|
||||
{ id = 33138, name = "秘法刀石", icon = "Interface\\Icons\\INV_Sword_04", obtained = true },
|
||||
{ id = 33129, name = "菲纳特的爆竹", icon = "Interface\\Icons\\INV_Shield_05", obtained = false },
|
||||
{ id = 33132, name = "精致焰红石", icon = "Interface\\Icons\\INV_Helmet_01", obtained = true },
|
||||
{ id = 33133, name = "胡里奥之心", icon = "Interface\\Icons\\INV_Chest_Plate01", obtained = false },
|
||||
{ id = 33138, name = "秘法刀石", icon = "Interface\\Icons\\INV_Sword_04", obtained = true },
|
||||
{ id = 33129, name = "菲纳特的爆竹", icon = "Interface\\Icons\\INV_Shield_05", obtained = false },
|
||||
{ id = 33132, name = "精致焰红石", icon = "Interface\\Icons\\INV_Helmet_01", obtained = true },
|
||||
{ id = 33133, name = "胡里奥之心", icon = "Interface\\Icons\\INV_Chest_Plate01", obtained = false },
|
||||
{ id = 33138, name = "秘法刀石", icon = "Interface\\Icons\\INV_Sword_04", obtained = true },
|
||||
{ id = 33129, name = "菲纳特的爆竹", icon = "Interface\\Icons\\INV_Shield_05", obtained = false },
|
||||
{ id = 33132, name = "精致焰红石", icon = "Interface\\Icons\\INV_Helmet_01", obtained = true },
|
||||
{ id = 33133, name = "胡里奥之心", icon = "Interface\\Icons\\INV_Chest_Plate01", obtained = false },
|
||||
{ id = 33138, name = "秘法刀石", icon = "Interface\\Icons\\INV_Sword_04", obtained = true },
|
||||
{ id = 33129, name = "菲纳特的爆竹", icon = "Interface\\Icons\\INV_Shield_05", obtained = false },
|
||||
{ id = 33132, name = "精致焰红石", icon = "Interface\\Icons\\INV_Helmet_01", obtained = true },
|
||||
{ id = 33133, name = "胡里奥之心", icon = "Interface\\Icons\\INV_Chest_Plate01", obtained = false },
|
||||
{ id = 33138, name = "秘法刀石", icon = "Interface\\Icons\\INV_Sword_04", obtained = true },
|
||||
{ id = 33129, name = "菲纳特的爆竹", icon = "Interface\\Icons\\INV_Shield_05", obtained = false },
|
||||
{ id = 33132, name = "精致焰红石", icon = "Interface\\Icons\\INV_Helmet_01", obtained = true },
|
||||
{ id = 33133, name = "胡里奥之心", icon = "Interface\\Icons\\INV_Chest_Plate01", obtained = false },
|
||||
}
|
||||
callback(items)
|
||||
end
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetAttributes(callback)
|
||||
local attributes = {
|
||||
{ Name = "生命值", value = 999, isPositive = true },
|
||||
{ Name = "近战攻强", value = 999, isPositive = true },
|
||||
{ Name = "法术强度", value = 999, isPositive = true },
|
||||
{ Name = "暴击等级", value = 999, isPositive = true },
|
||||
{ Name = "造成奥术伤害", value = 999, isPositive = true },
|
||||
{ Name = "造成火焰伤害", value = 999, isPositive = true },
|
||||
{ Name = "受到所有伤害", value = 999, isPositive = false },
|
||||
{ Name = "造成暴击伤害", value = 999, isPositive = true },
|
||||
{ Name = "造成所有伤害", value = 999, isPositive = true },
|
||||
{ Name = "治疗效果", value = 999, isPositive = true },
|
||||
}
|
||||
callback(attributes)
|
||||
end
|
||||
|
||||
function SM_Collections.LocalDataProvider:GetAttributesForSpecificItem(itemId, itemType, callback)
|
||||
local attributeMap = {
|
||||
mount = {
|
||||
[458] = {
|
||||
{ Name = "移动速度", value = 60, isPositive = true },
|
||||
{ Name = "耐力", value = 50, isPositive = true },
|
||||
{ Name = "载重", value = 100, isPositive = true },
|
||||
},
|
||||
[459] = {
|
||||
{ Name = "移动速度", value = 100, isPositive = true },
|
||||
{ Name = "敏捷", value = 80, isPositive = true },
|
||||
{ Name = "夜视", value = 1, isPositive = true },
|
||||
},
|
||||
[468] = {
|
||||
{ Name = "移动速度", value = 100, isPositive = true },
|
||||
{ Name = "威望", value = 25, isPositive = true },
|
||||
{ Name = "圣光抗性", value = 15, isPositive = true },
|
||||
},
|
||||
},
|
||||
companion = {
|
||||
[62508] = {
|
||||
{ Name = "忠诚度", value = 100, isPositive = true },
|
||||
{ Name = "战斗辅助", value = 20, isPositive = true },
|
||||
{ Name = "寻宝能力", value = 15, isPositive = true },
|
||||
},
|
||||
[28871] = {
|
||||
{ Name = "火焰抗性", value = 50, isPositive = true },
|
||||
{ Name = "法力恢复", value = 10, isPositive = true },
|
||||
{ Name = "照明", value = 1, isPositive = true },
|
||||
},
|
||||
},
|
||||
card = {
|
||||
[11502] = {
|
||||
{ Name = "火焰伤害", value = 500, isPositive = true },
|
||||
{ Name = "法术强度", value = 200, isPositive = true },
|
||||
{ Name = "冰霜抗性", value = 75, isPositive = true },
|
||||
},
|
||||
[24248] = {
|
||||
{ Name = "冰霜伤害", value = 600, isPositive = true },
|
||||
{ Name = "亡灵控制", value = 100, isPositive = true },
|
||||
{ Name = "生命汲取", value = 50, isPositive = true },
|
||||
},
|
||||
}
|
||||
}
|
||||
local attributes = attributeMap[itemType] and attributeMap[itemType][itemId] or {}
|
||||
if SM_Collections.Config.Debug then
|
||||
print("LocalDataProvider: 为", itemType, itemId, "返回", #attributes, "个特定属性")
|
||||
end
|
||||
callback(attributes)
|
||||
end
|
||||
|
||||
-- 服务端数据提供者
|
||||
SM_Collections.ServerDataProvider = SM_Collections.DataProvider:new()
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetMounts(callback)
|
||||
self:SendServerRequest("GET_MOUNTS", {}, function(response)
|
||||
if response and response.success then
|
||||
if SM_Collections.Config.Debug then
|
||||
print("ServerDataProvider: 从服务端获取到", #response.data, "个坐骑")
|
||||
end
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取坐骑失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetMounts(callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetCompanions(callback)
|
||||
self:SendServerRequest("GET_COMPANIONS", {}, function(response)
|
||||
if response and response.success then
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取小伙伴收藏失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetCompanions(callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetCards(callback)
|
||||
self:SendServerRequest("GET_CARDS", {}, function(response)
|
||||
if response and response.success then
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取卡牌收藏失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetCards(callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetItems(callback)
|
||||
self:SendServerRequest("GET_ITEMS", {}, function(response)
|
||||
if response and response.success then
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取物品收藏失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetItems(callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetAttributes(callback)
|
||||
self:SendServerRequest("GET_ATTRIBUTES", {}, function(response)
|
||||
if response and response.success then
|
||||
if SM_Collections.Config.Debug then
|
||||
print("ServerDataProvider: 从服务端获取到", #response.data, "个属性加成")
|
||||
end
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取坐骑属性加成收藏失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetAttributes(callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:GetAttributesForSpecificItem(itemId, itemType, callback)
|
||||
local requestData = {
|
||||
itemId = itemId,
|
||||
itemType = itemType
|
||||
}
|
||||
self:SendServerRequest("GET_ITEM_ATTRIBUTES", requestData, function(response)
|
||||
if response and response.success then
|
||||
if SM_Collections.Config.Debug then
|
||||
print("ServerDataProvider: 从服务端获取到", #response.data, "个特定属性")
|
||||
end
|
||||
callback(response.data)
|
||||
else
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
print("服务端获取特定属性失败,回退到本地数据")
|
||||
SM_Collections.LocalDataProvider:GetAttributesForSpecificItem(itemId, itemType, callback)
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections.ServerDataProvider:SendServerRequest(command, data, callback)
|
||||
if SM_Collections.Config.Debug then
|
||||
print("发送服务端请求:", command)
|
||||
end
|
||||
SM_Collections.pendingCallbacks = SM_Collections.pendingCallbacks or {}
|
||||
if command == "GET_MOUNTS" then
|
||||
SM_Collections.pendingCallbacks.mounts = callback
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_MOUNTS", "WHISPER", UnitName("player"))
|
||||
elseif command == "GET_ATTRIBUTES" then
|
||||
SM_Collections.pendingCallbacks.attributes = callback
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_ATTRIBUTES", "WHISPER", UnitName("player"))
|
||||
elseif command == "GET_COMPANIONS" then
|
||||
SM_Collections.pendingCallbacks.companions = callback
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_COMPANIONS", "WHISPER", UnitName("player"))
|
||||
elseif command == "GET_CARDS" then
|
||||
SM_Collections.pendingCallbacks.cards = callback
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_CARDS", "WHISPER", UnitName("player"))
|
||||
elseif command == "GET_ITEMS" then
|
||||
SM_Collections.pendingCallbacks.items = callback
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_ITEMS", "WHISPER", UnitName("player"))
|
||||
elseif command == "GET_ITEM_ATTRIBUTES" then
|
||||
SM_Collections.pendingCallbacks.item_attributes = callback
|
||||
local requestMsg = data.itemType .. "|" .. data.itemId
|
||||
SendAddonMessage("SM_C_COLLECTIONS_REQUEST", "GET_ITEM_ATTRIBUTES|" .. requestMsg, "WHISPER", UnitName("player"))
|
||||
end
|
||||
local timeoutFrame = CreateFrame("Frame")
|
||||
local startTime = GetTime()
|
||||
local timeoutSeconds = SM_Collections.Config.ServerTimeout / 1000
|
||||
timeoutFrame:SetScript("OnUpdate", function(self, elapsed)
|
||||
if GetTime() - startTime >= timeoutSeconds then
|
||||
local callbackKey = command:lower():gsub("get_", "")
|
||||
if SM_Collections.pendingCallbacks and SM_Collections.pendingCallbacks[callbackKey] then
|
||||
print("服务端请求超时:", command)
|
||||
if SM_Collections.Config.FallbackToLocal then
|
||||
local localProvider = SM_Collections.LocalDataProvider:new()
|
||||
if command == "GET_MOUNTS" then
|
||||
localProvider:GetMounts(callback)
|
||||
elseif command == "GET_ATTRIBUTES" then
|
||||
localProvider:GetAttributes(callback)
|
||||
elseif command == "GET_COMPANIONS" then
|
||||
localProvider:GetCompanions(callback)
|
||||
elseif command == "GET_CARDS" then
|
||||
localProvider:GetCards(callback)
|
||||
elseif command == "GET_ITEMS" then
|
||||
localProvider:GetItems(callback)
|
||||
end
|
||||
else
|
||||
callback({})
|
||||
end
|
||||
SM_Collections.pendingCallbacks[callbackKey] = nil
|
||||
end
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- 数据管理器
|
||||
SM_Collections.DataManager = {}
|
||||
function SM_Collections.DataManager:Initialize()
|
||||
if SM_Collections.Config.UseServerData then
|
||||
self.dataProvider = SM_Collections.ServerDataProvider:new()
|
||||
print("使用服务端数据提供者")
|
||||
else
|
||||
self.dataProvider = SM_Collections.LocalDataProvider:new()
|
||||
print("使用本地数据提供者")
|
||||
end
|
||||
end
|
||||
function SM_Collections.DataManager:GetMounts(callback) self.dataProvider:GetMounts(callback) end
|
||||
function SM_Collections.DataManager:GetCompanions(callback) self.dataProvider:GetCompanions(callback) end
|
||||
function SM_Collections.DataManager:GetCards(callback) self.dataProvider:GetCards(callback) end
|
||||
function SM_Collections.DataManager:GetItems(callback) self.dataProvider:GetItems(callback) end
|
||||
function SM_Collections.DataManager:GetAttributes(callback) self.dataProvider:GetAttributes(callback) end
|
||||
function SM_Collections.DataManager:GetAttributesForSpecificItem(itemId, itemType, callback) self.dataProvider:GetAttributesForSpecificItem(itemId, itemType, callback) end
|
||||
|
||||
-- 兼容性坐骑数据
|
||||
SM_Collections.Mounts = {
|
||||
[458] = { 284, 2, 0, "Brown Horse", "A favorite among Stormwind's guards thanks to its patience and stamina.", 2, "|cFFFFD200Vendor: |rWorld Vendors|n|cFFFFD200Cost: |r1|TINTERFACE\\MONEYFRAME\\UI-GOLDICON.BLP:0|t" },
|
||||
[459] = { 4268, 2, 64, "Gray Wolf", "This breed of wolf prefers hunting in the fog, relying on its smoky hide to camouflage it from unsuspecting prey.", 2, "|cFFFFD200Vendor: |rOgunaro Wolfrunner|n|cFFFFD200Zone: |rOrgrimmar|n|cFFFFD200Cost: |r1|TINTERFACE\\MONEYFRAME\\UI-GOLDICON.BLP:0|t" },
|
||||
[468] = { 305, 2, 64, "White Stallion", "The powerful and unyielding white stallion features heavily in the myths of ancient human tribes.", 2, "|cFFFFD200Legacy|r" },
|
||||
[470] = { 308, 2, 0, "Black Stallion", "Rumored to be favored by SI:7 for night missions due to its dark coat.", 2, "|cFFFFD200Vendor: |rUnger Statforth|n|cFFFFD200Zone: |rWetlands|n|cFFFFD200Cost: |r1|TINTERFACE\\MONEYFRAME\\UI-GOLDICON.BLP:0|t" },
|
||||
[578] = { 356, 2, 64, "Black Wolf", "Can howl loudly enough to be heard for miles.", 2, "|cFFFFD200Vendor: |rOgunaro Wolfrunner|n|cFFFFD200Zone: |rOrgrimmar|n|cFFFFD200Cost: |r1|TINTERFACE\\MONEYFRAME\\UI-GOLDICON.BLP:0|t" },
|
||||
}
|
||||
91
SM_Events.lua
Normal file
91
SM_Events.lua
Normal file
@ -0,0 +1,91 @@
|
||||
-- SM_Events.lua
|
||||
|
||||
-- 斜杠命令
|
||||
SLASH_SM_COLLECTIONS1 = "/smcollections"
|
||||
SLASH_SM_COLLECTIONS2 = "/sm收藏"
|
||||
SlashCmdList["SM_COLLECTIONS"] = function()
|
||||
if not SM_Collections.MainFrame then
|
||||
SM_Collections:CreateMainFrame()
|
||||
end
|
||||
if SM_Collections.MainFrame:IsVisible() then
|
||||
SM_Collections.MainFrame:Hide()
|
||||
else
|
||||
SM_Collections.MainFrame:Show()
|
||||
if not SM_Collections.CurrentTab then
|
||||
SM_Collections:ShowTab(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理坐骑数据
|
||||
function SM_Collections:HandleMountsData(msg)
|
||||
local data = self:MessageSplit(msg, "|")
|
||||
local mounts = {}
|
||||
for i = 1, #data, 4 do
|
||||
if data[i] and data[i + 1] and data[i + 2] and data[i + 3] then
|
||||
table.insert(mounts, {
|
||||
id = tonumber(data[i]),
|
||||
name = data[i + 1],
|
||||
description = data[i + 2],
|
||||
obtained = data[i + 3] == "1"
|
||||
})
|
||||
end
|
||||
end
|
||||
if self.pendingCallbacks and self.pendingCallbacks.mounts then
|
||||
self.pendingCallbacks.mounts(mounts)
|
||||
self.pendingCallbacks.mounts = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理属性数据
|
||||
function SM_Collections:HandleAttributesData(msg)
|
||||
local data = self:MessageSplit(msg, "|")
|
||||
local attributes = {}
|
||||
for i = 1, #data, 3 do
|
||||
if data[i] and data[i + 1] and data[i + 2] then
|
||||
table.insert(attributes, {
|
||||
Name = data[i],
|
||||
value = tonumber(data[i + 1]),
|
||||
isPositive = data[i + 2] == "1"
|
||||
})
|
||||
end
|
||||
end
|
||||
if self.pendingCallbacks and self.pendingCallbacks.attributes then
|
||||
self.pendingCallbacks.attributes(attributes)
|
||||
self.pendingCallbacks.attributes = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 消息处理函数
|
||||
function SM_Collections_MessageEvent(self, event, packet, msg, type, sender)
|
||||
if event == 'CHAT_MSG_ADDON' then
|
||||
if packet == 'SM_S_COLLECTIONS_MOUNTS' then
|
||||
SM_Collections:HandleMountsData(msg)
|
||||
elseif packet == 'SM_S_COLLECTIONS_COMPANIONS' then
|
||||
SM_Collections:HandleCompanionsData(msg)
|
||||
elseif packet == 'SM_S_COLLECTIONS_CARDS' then
|
||||
SM_Collections:HandleCardsData(msg)
|
||||
elseif packet == 'SM_S_COLLECTIONS_ITEMS' then
|
||||
SM_Collections:HandleItemsData(msg)
|
||||
elseif packet == 'SM_S_COLLECTIONS_ATTRIBUTES' then
|
||||
SM_Collections:HandleAttributesData(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 事件监听框架
|
||||
local SM_Collections_EventFrame = CreateFrame('Frame', 'SM_Collections_EventFrame')
|
||||
SM_Collections_EventFrame:RegisterEvent('CHAT_MSG_ADDON')
|
||||
SM_Collections_EventFrame:RegisterEvent('ADDON_LOADED')
|
||||
SM_Collections_EventFrame:SetScript('OnEvent', function(self, event, ...)
|
||||
if event == 'ADDON_LOADED' then
|
||||
local addonName = ...
|
||||
if addonName == "SM_CollectionSystem" then
|
||||
SM_Collections.DataManager:Initialize()
|
||||
print("SM收藏系统已加载!使用 /smcollections 打开界面")
|
||||
print("数据源模式:", SM_Collections.Config.UseServerData and "服务端" or "本地")
|
||||
end
|
||||
elseif event == 'CHAT_MSG_ADDON' then
|
||||
SM_Collections_MessageEvent(self, event, ...)
|
||||
end
|
||||
end)
|
||||
395
SM_UI_MainFrame.lua
Normal file
395
SM_UI_MainFrame.lua
Normal file
@ -0,0 +1,395 @@
|
||||
-- SM_UI_MainFrame.lua
|
||||
|
||||
-- 创建主界面
|
||||
function SM_Collections:CreateMainFrame()
|
||||
if self.MainFrame then
|
||||
return self.MainFrame
|
||||
end
|
||||
|
||||
SM_Collections_Frame = CreateFrame("Frame", "SM_Collections_MainFrame", UIParent);
|
||||
SM_Collections_Frame:SetSize(800, 540);
|
||||
SM_Collections_Frame:SetPoint("CENTER", 0, 0);
|
||||
SM_Collections_Frame_Texture = SM_Collections_Frame:CreateTexture(nil, 'OVERLAY')
|
||||
SM_Collections_Frame_Texture:SetPoint('TOP')
|
||||
SM_Collections_Frame_Texture:SetAllPoints(SM_Collections_Frame)
|
||||
SM_Collections_Frame_Texture:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\back")
|
||||
|
||||
-- 左上角圆形头像/LOGO
|
||||
local icon = SM_Collections_Frame:CreateTexture(nil, "ARTWORK")
|
||||
icon:SetSize(80, 80)
|
||||
icon:SetPoint("TOPLEFT", 5, -5)
|
||||
SetPortraitToTexture(icon, "Interface\\ICONS\\INV_Misc_QuestionMark")
|
||||
|
||||
-- 标题
|
||||
local title = SM_Collections_Frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
|
||||
title:SetPoint("TOP", 0, -20)
|
||||
title:SetText("我的收藏系统")
|
||||
|
||||
-- 关闭按钮
|
||||
local closeBtn = CreateFrame("Button", "SM_CollectionsCloseBtn", SM_Collections_Frame, "UIPanelCloseButton")
|
||||
closeBtn:SetSize(40, 40)
|
||||
closeBtn:SetPoint("TOPRIGHT", 4, -8)
|
||||
closeBtn:SetScript("OnClick", function() SM_Collections_Frame:Hide() end)
|
||||
|
||||
-- 创建右侧面板容器
|
||||
local rightSidePanel = CreateFrame("Frame", "SM_CollectionsRightSidePanel", SM_Collections_Frame)
|
||||
rightSidePanel:SetSize(190, 400)
|
||||
rightSidePanel:SetPoint("TOPRIGHT", 20, -80)
|
||||
SM_Collections_Frame.RightSidePanel = rightSidePanel
|
||||
self.RightSidePanel = rightSidePanel
|
||||
|
||||
-- 右侧面板
|
||||
local rightPanel = CreateFrame("Frame", nil, SM_Collections_Frame)
|
||||
rightPanel:SetPoint("TOPRIGHT", SM_Collections_Frame, "TOPRIGHT", -20, -60)
|
||||
rightPanel:SetSize(320, 420)
|
||||
|
||||
-- 名称
|
||||
rightPanel.name = rightPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
|
||||
rightPanel.name:SetPoint("TOPLEFT", rightPanel, "TOPLEFT", 16, -16)
|
||||
rightPanel.name:SetJustifyH("LEFT")
|
||||
|
||||
-- 描述
|
||||
rightPanel.desc = rightPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
rightPanel.desc:SetPoint("TOPLEFT", rightPanel.name, "BOTTOMLEFT", 0, -8)
|
||||
rightPanel.desc:SetWidth(280)
|
||||
rightPanel.desc:SetJustifyH("LEFT")
|
||||
rightPanel.desc:SetWordWrap(true)
|
||||
|
||||
-- 坐骑召唤、小伙伴召唤、卡牌召唤按钮
|
||||
rightSidePanel.CallButon = CreateFrame("Button", "SM_CollectionsRightSidePanelCallButon", rightSidePanel)
|
||||
rightSidePanel.CallButon:SetSize(30, 30)
|
||||
rightSidePanel.CallButon:SetPoint("TOPRIGHT", -40, 30)
|
||||
rightSidePanel.CallButon:SetNormalTexture("Interface\\ICONS\\Ability_Mount_RidingHorse.blp")
|
||||
rightSidePanel.CallButon:SetHighlightTexture("Interface\\ICONS\\Ability_Mount_RidingHorse.blp")
|
||||
rightSidePanel.CallButon:SetPushedTexture("Interface\\ICONS\\Ability_Mount_RidingHorse.blp")
|
||||
rightSidePanel.CallButon:SetScript("OnClick", function() print("召唤") end)
|
||||
|
||||
-- 创建标题容器
|
||||
local titleContainer = CreateFrame("Frame", nil, rightSidePanel)
|
||||
titleContainer:SetSize(180, 30)
|
||||
titleContainer:SetPoint("TOPLEFT", 5, -5)
|
||||
|
||||
-- 坐骑名称文本 - 使用自定义字体
|
||||
local titleFont = CreateFont("SM_TitleFont")
|
||||
titleFont:SetFont("Fonts\\ZYKai_T.ttf", 20, "MONOCHROME")
|
||||
local MountNama = titleContainer:CreateFontString(nil, "OVERLAY")
|
||||
MountNama:SetPoint("LEFT", 0, 0)
|
||||
MountNama:SetFontObject(titleFont)
|
||||
MountNama:SetText("")
|
||||
MountNama:SetJustifyH("LEFT")
|
||||
MountNama:SetJustifyV("TOP")
|
||||
MountNama:SetTextColor(230 / 255, 150 / 255, 0 / 255)
|
||||
rightSidePanel.MountNama = MountNama
|
||||
|
||||
-- 创建介绍文本容器
|
||||
local introContainer = CreateFrame("Frame", nil, rightSidePanel)
|
||||
introContainer:SetSize(180, 120) -- 增加高度以容纳更多文本
|
||||
introContainer:SetPoint("TOPLEFT", titleContainer, "BOTTOMLEFT", 0, -10)
|
||||
|
||||
-- 介绍文本 - 使用自定义字体
|
||||
local descFont = CreateFont("SM_DescFont")
|
||||
descFont:SetFont("Fonts\\ZYKai_T.ttf", 12, "MONOCHROME")
|
||||
local introText = introContainer:CreateFontString(nil, "OVERLAY")
|
||||
introText:SetPoint("TOPLEFT", 0, 0)
|
||||
introText:SetSize(180, 0) -- 宽度固定,高度自适应
|
||||
introText:SetJustifyH("LEFT")
|
||||
introText:SetJustifyV("TOP")
|
||||
introText:SetSpacing(2)
|
||||
introText:SetWordWrap(true)
|
||||
introText:SetFontObject(descFont)
|
||||
introText:SetText("")
|
||||
rightSidePanel.introText = introText
|
||||
|
||||
-- 属性加成标题 - 调整位置防止与介绍文本重叠
|
||||
local AttributeBonusFrame = CreateFrame("Frame", "AttributeBonusFrame", rightSidePanel)
|
||||
AttributeBonusFrame:SetSize(150, 20)
|
||||
AttributeBonusFrame:SetPoint("CENTER", introContainer, "CENTER", -25, -40) -- 增加间距
|
||||
AttributeBonusFrame:SetBackdrop({ bgFile = "Interface\\AddOns\\SM_CollectionSystem\\Textures\\AttributeBonusFrame" })
|
||||
|
||||
local AttributeBonusFrameText = AttributeBonusFrame:CreateFontString(nil, "OVERLAY")
|
||||
AttributeBonusFrameText:SetPoint("CENTER", 0, 0)
|
||||
AttributeBonusFrameText:SetFontObject(titleFont)
|
||||
AttributeBonusFrameText:SetText("属性加成")
|
||||
AttributeBonusFrameText:SetFont("Fonts\\ZYKai_T.ttf", 16, "MONOCHROME")
|
||||
AttributeBonusFrame:Hide()
|
||||
rightSidePanel.AttributeBonusFrame = AttributeBonusFrame
|
||||
|
||||
-- 拖拽功能
|
||||
SM_Collections_Frame:SetScript("OnMouseDown", function(self, button)
|
||||
if button == "LeftButton" then
|
||||
self:StartMoving()
|
||||
end
|
||||
end)
|
||||
SM_Collections_Frame:SetScript("OnMouseUp", function(self, button)
|
||||
if button == "LeftButton" then
|
||||
self:StopMovingOrSizing()
|
||||
end
|
||||
end)
|
||||
|
||||
-- 创建标签页
|
||||
self:CreateTabs(SM_Collections_Frame)
|
||||
|
||||
-- 创建内容区域
|
||||
local contentFrame = CreateFrame("Frame", "SM_CollectionsContentFrame", SM_Collections_Frame)
|
||||
contentFrame:SetPoint("TOPLEFT", 20, -80)
|
||||
contentFrame:SetPoint("BOTTOMRIGHT", -20, 20)
|
||||
SM_Collections_Frame.ContentFrame = contentFrame
|
||||
|
||||
self.MainFrame = SM_Collections_Frame
|
||||
return SM_Collections_Frame
|
||||
end
|
||||
|
||||
-- 创建标签页
|
||||
function SM_Collections:CreateTabs(parent)
|
||||
local tabs = {}
|
||||
local tabNames = { "坐骑收藏", "小伙伴收藏", "卡牌收藏", "物品收藏" }
|
||||
for i = 1, 4 do
|
||||
local tab = CreateFrame("Button", "SM_CollectionTab" .. i, parent, "CharacterFrameTabButtonTemplate")
|
||||
tab:SetSize(120, 30)
|
||||
tab:SetID(i)
|
||||
if i == 1 then
|
||||
tab:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", 20, 5)
|
||||
else
|
||||
tab:SetPoint("LEFT", tabs[i - 1], "RIGHT", 5, 0)
|
||||
end
|
||||
tab:SetText(tabNames[i])
|
||||
tab:SetScript("OnClick", function(self)
|
||||
SM_Collections:UpdateTabAppearance(self:GetID())
|
||||
SM_Collections:ShowTab(self:GetID())
|
||||
PlaySound("igCharacterInfoTab")
|
||||
end)
|
||||
tabs[i] = tab
|
||||
end
|
||||
parent.tabs = tabs
|
||||
parent.numTabs = 4
|
||||
parent.selectedTab = 1
|
||||
self:UpdateTabAppearance(1)
|
||||
end
|
||||
|
||||
-- 更新标签页外观
|
||||
function SM_Collections:UpdateTabAppearance(selectedTab)
|
||||
if not self.MainFrame or not self.MainFrame.tabs then return end
|
||||
for i = 1, self.MainFrame.numTabs do
|
||||
local tab = self.MainFrame.tabs[i]
|
||||
if tab then
|
||||
if i == selectedTab then
|
||||
tab:SetAlpha(1.0)
|
||||
if tab.GetFontString and tab:GetFontString() then
|
||||
tab:GetFontString():SetTextColor(1, 1, 1)
|
||||
end
|
||||
else
|
||||
tab:SetAlpha(0.7)
|
||||
if tab.GetFontString and tab:GetFontString() then
|
||||
tab:GetFontString():SetTextColor(0.7, 0.7, 0.7)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.MainFrame.selectedTab = selectedTab
|
||||
self.CurrentTab = selectedTab
|
||||
end
|
||||
|
||||
-- 显示指定标签页
|
||||
function SM_Collections:ShowTab(tabId)
|
||||
self:UpdateTabAppearance(tabId)
|
||||
if self.MainFrame and self.MainFrame.RightSidePanel then
|
||||
if self.MainFrame.RightSidePanel.MountNama then
|
||||
self.MainFrame.RightSidePanel.MountNama:SetText("")
|
||||
end
|
||||
if self.MainFrame.RightSidePanel.introText then
|
||||
self.MainFrame.RightSidePanel.introText:SetText("")
|
||||
end
|
||||
if self.MainFrame.RightSidePanel.AttributeBonusFrame then
|
||||
self.MainFrame.RightSidePanel.AttributeBonusFrame:Hide()
|
||||
end
|
||||
end
|
||||
if self.CurrentPanel then
|
||||
self.CurrentPanel:Hide()
|
||||
local children = { self.CurrentPanel:GetChildren() }
|
||||
for _, child in ipairs(children) do
|
||||
child:Hide()
|
||||
end
|
||||
self.CurrentPanel = nil
|
||||
end
|
||||
if self.MainFrame and self.MainFrame.ContentFrame then
|
||||
local children = { self.MainFrame.ContentFrame:GetChildren() }
|
||||
for _, child in ipairs(children) do
|
||||
child:Hide()
|
||||
end
|
||||
end
|
||||
if self.MainFrame and self.MainFrame.RightSidePanel then
|
||||
if tabId == 4 then
|
||||
self.MainFrame.RightSidePanel:Hide()
|
||||
else
|
||||
self.MainFrame.RightSidePanel:Show()
|
||||
end
|
||||
end
|
||||
if tabId == 1 then
|
||||
self:ShowMounts()
|
||||
elseif tabId == 2 then
|
||||
self:ShowCompanions()
|
||||
elseif tabId == 3 then
|
||||
self:ShowCards()
|
||||
elseif tabId == 4 then
|
||||
self:ShowItems()
|
||||
end
|
||||
end
|
||||
|
||||
-- 下面补充内容切换的函数(示例)
|
||||
function SM_Collections:ShowMounts()
|
||||
print("显示坐骑")
|
||||
SM_Collections.DataManager:GetMounts(function(mounts)
|
||||
local panel = self:CreateSplitPanel(self.MainFrame.ContentFrame, mounts, "mount")
|
||||
local firstObtained = nil
|
||||
for _, mount in ipairs(mounts) do
|
||||
if mount.obtained then
|
||||
firstObtained = mount
|
||||
break
|
||||
end
|
||||
end
|
||||
if firstObtained then
|
||||
-- 只在模型下方显示坐骑名称
|
||||
-- panel.nameText:SetText(firstObtained.name)
|
||||
|
||||
-- 不在模型下方显示描述文本,只设置右侧面板
|
||||
if self.MainFrame and self.MainFrame.RightSidePanel then
|
||||
if self.MainFrame.RightSidePanel.MountNama then
|
||||
self.MainFrame.RightSidePanel.MountNama:SetText(firstObtained.name or "")
|
||||
end
|
||||
if self.MainFrame.RightSidePanel.introText then
|
||||
self.MainFrame.RightSidePanel.introText:SetText(firstObtained.description or "")
|
||||
self.MainFrame.RightSidePanel.introText:SetHeight(0) -- 自动调整高度
|
||||
end
|
||||
end
|
||||
|
||||
local creatureDisplayID = self:GetCreatureDisplayID(firstObtained.id, "mount")
|
||||
if creatureDisplayID and creatureDisplayID > 0 then
|
||||
panel.model:Hide()
|
||||
panel.model:SetPosition(0, 0, 0)
|
||||
panel.model.zoomLevel = 0
|
||||
panel.model:Show()
|
||||
panel.model:SetCreature(creatureDisplayID)
|
||||
print("显示坐骑= " .. creatureDisplayID)
|
||||
end
|
||||
|
||||
-- 更新右侧面板的属性加成
|
||||
self:UpdateRightPanel(firstObtained, "mount")
|
||||
end
|
||||
panel:Show()
|
||||
self.CurrentPanel = panel
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections:ShowCompanions()
|
||||
print("显示小伙伴")
|
||||
SM_Collections.DataManager:GetCompanions(function(companions)
|
||||
local panel = self:CreateSplitPanel(self.MainFrame.ContentFrame, companions, "companion")
|
||||
local firstObtained = nil
|
||||
for _, companion in ipairs(companions) do
|
||||
if companion.obtained then
|
||||
firstObtained = companion
|
||||
break
|
||||
end
|
||||
end
|
||||
if firstObtained then
|
||||
-- 只在模型下方显示名称
|
||||
--panel.nameText:SetText(firstObtained.name)
|
||||
|
||||
-- 不在模型下方显示描述文本,只设置右侧面板
|
||||
if self.MainFrame and self.MainFrame.RightSidePanel then
|
||||
if self.MainFrame.RightSidePanel.MountNama then
|
||||
self.MainFrame.RightSidePanel.MountNama:SetText(firstObtained.name or "")
|
||||
end
|
||||
if self.MainFrame.RightSidePanel.introText then
|
||||
self.MainFrame.RightSidePanel.introText:SetText(firstObtained.description or "")
|
||||
self.MainFrame.RightSidePanel.introText:SetHeight(0) -- 自动调整高度
|
||||
end
|
||||
end
|
||||
|
||||
local creatureDisplayID = self:GetCreatureDisplayID(firstObtained.id, "companion")
|
||||
if creatureDisplayID and creatureDisplayID > 0 then
|
||||
panel.model:Hide()
|
||||
panel.model:SetPosition(0, 0, 0)
|
||||
panel.model.zoomLevel = 0
|
||||
panel.model:Show()
|
||||
panel.model:SetCreature(creatureDisplayID)
|
||||
print("显示小伙伴= " .. creatureDisplayID)
|
||||
end
|
||||
|
||||
-- 更新右侧面板的属性加成
|
||||
self:UpdateRightPanel(firstObtained, "companion")
|
||||
end
|
||||
panel:Show()
|
||||
self.CurrentPanel = panel
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections:ShowCards()
|
||||
print("显示卡牌收藏")
|
||||
SM_Collections.DataManager:GetCards(function(cards)
|
||||
local panel = self:CreateSplitPanel(self.MainFrame.ContentFrame, cards, "card")
|
||||
local firstObtained = nil
|
||||
for _, card in ipairs(cards) do
|
||||
if card.obtained then
|
||||
firstObtained = card
|
||||
break
|
||||
end
|
||||
end
|
||||
if firstObtained then
|
||||
-- 只在模型下方显示名称
|
||||
--panel.nameText:SetText(firstObtained.name)
|
||||
|
||||
-- 不在模型下方显示描述文本,只设置右侧面板
|
||||
if self.MainFrame and self.MainFrame.RightSidePanel then
|
||||
if self.MainFrame.RightSidePanel.MountNama then
|
||||
self.MainFrame.RightSidePanel.MountNama:SetText(firstObtained.name or "")
|
||||
end
|
||||
if self.MainFrame.RightSidePanel.introText then
|
||||
self.MainFrame.RightSidePanel.introText:SetText(firstObtained.description or "")
|
||||
self.MainFrame.RightSidePanel.introText:SetHeight(0) -- 自动调整高度
|
||||
end
|
||||
end
|
||||
|
||||
local creatureDisplayID = self:GetCreatureDisplayID(firstObtained.id, "card")
|
||||
if creatureDisplayID and creatureDisplayID > 0 then
|
||||
panel.model:Hide()
|
||||
panel.model:SetPosition(0, 0, 0)
|
||||
panel.model.zoomLevel = 0
|
||||
panel.model:Show()
|
||||
panel.model:SetCreature(creatureDisplayID)
|
||||
print("显示卡牌收藏= " .. creatureDisplayID)
|
||||
end
|
||||
|
||||
-- 更新右侧面板的属性加成
|
||||
self:UpdateRightPanel(firstObtained, "card")
|
||||
end
|
||||
panel:Show()
|
||||
self.CurrentPanel = panel
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections:ShowItems()
|
||||
print("显示物品函数")
|
||||
SM_Collections.DataManager:GetItems(function(items)
|
||||
local panel = CreateFrame("Frame", "SM_CollectionsItemsPanel", self.MainFrame.ContentFrame)
|
||||
panel:SetAllPoints()
|
||||
panel:SetBackdrop({
|
||||
bgFile = "Interface\\AddOns\\SM_CollectionSystem\\Interface\\DialogFrame\\UI-DialogBox-Background",
|
||||
edgeFile = "Interface\\AddOns\\SM_CollectionSystem\\Interface\\DialogFrame\\UI-DialogBox-Border",
|
||||
tile = true,
|
||||
tileSize = 32,
|
||||
edgeSize = 32,
|
||||
insets = { left = 11, right = 12, top = 12, bottom = 11 }
|
||||
})
|
||||
local scrollFrameName = "SM_ItemScrollFrame_" .. math.random(1000, 9999)
|
||||
local scrollFrame = CreateFrame("ScrollFrame", scrollFrameName, panel, "UIPanelScrollFrameTemplate")
|
||||
scrollFrame:SetSize(740, 480)
|
||||
scrollFrame:SetPoint("TOPLEFT", 10, -10)
|
||||
local scrollChild = CreateFrame("Frame", "SM_CollectionsItemsScrollChild", scrollFrame)
|
||||
scrollChild:SetSize(720, 1)
|
||||
scrollFrame:SetScrollChild(scrollChild)
|
||||
self:CreateItemGrid(scrollChild, items)
|
||||
panel:Show()
|
||||
self.CurrentPanel = panel
|
||||
end)
|
||||
end
|
||||
349
SM_UI_SplitPanel.lua
Normal file
349
SM_UI_SplitPanel.lua
Normal file
@ -0,0 +1,349 @@
|
||||
-- SM_UI_SplitPanel.lua
|
||||
|
||||
-- 迁移左右分栏、列表、滚动条、模型、物品网格、CreateSplitPanel、CreateListItems、CreateItemGrid等所有UI细节和逻辑
|
||||
-- ...(此处插入完整实现,详见原始大文件)
|
||||
|
||||
function SM_Collections:CreateSplitPanel(parent, data, itemType)
|
||||
assert(parent, "CreateSplitPanel: parent is nil!")
|
||||
local panel = CreateFrame("Frame", "SM_CollectionsPanel", parent)
|
||||
panel:SetAllPoints()
|
||||
|
||||
-- 左侧列表
|
||||
local listFrame = CreateFrame("Frame", "SM_CollectionslistFrame", panel)
|
||||
listFrame:SetSize(220, 410)
|
||||
listFrame:SetPoint("TOPLEFT", 5, -13)
|
||||
listFrame:SetBackdrop({
|
||||
bgFile = "Interface\\AddOns\\SM_CollectionSystem\\Textures\\liebiaoditu"
|
||||
})
|
||||
|
||||
local scrollFrameName = "SM_ScrollFrame_" .. itemType .. "_" .. math.random(1000, 9999)
|
||||
local scrollFrame = CreateFrame("ScrollFrame", scrollFrameName, listFrame, "UIPanelScrollFrameTemplate")
|
||||
scrollFrame:SetSize(200, 415)
|
||||
scrollFrame:SetPoint("TOPLEFT", 5, 2)
|
||||
|
||||
-- 滚动条装饰
|
||||
local BackgroundFrame = CreateFrame("Frame", "SM_CollectionsOverlayFrame", scrollFrame)
|
||||
BackgroundFrame:SetSize(25, 410)
|
||||
BackgroundFrame:SetPoint("RIGHT", scrollFrame, "RIGHT", 25.5, 1)
|
||||
BackgroundFrame:SetFrameLevel(scrollFrame:GetFrameLevel() + 1)
|
||||
local ScrollBarBackground = BackgroundFrame:CreateTexture(nil, "BACKGROUND")
|
||||
ScrollBarBackground:SetSize(25, 410)
|
||||
ScrollBarBackground:SetPoint("CENTER", BackgroundFrame, "CENTER", 0, 0)
|
||||
ScrollBarBackground:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\cooldown")
|
||||
|
||||
local overlayFrame = CreateFrame("Frame", "SM_CollectionsOverlayFrame", BackgroundFrame)
|
||||
overlayFrame:SetSize(30, 420)
|
||||
overlayFrame:SetPoint("CENTER", BackgroundFrame, "CENTER", 0, 1)
|
||||
overlayFrame:SetFrameLevel(BackgroundFrame:GetFrameLevel() + 10)
|
||||
local scrollBarOverlay = overlayFrame:CreateTexture(nil, "OVERLAY")
|
||||
scrollBarOverlay:SetAllPoints(overlayFrame)
|
||||
scrollBarOverlay:SetTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\ScrollFrame")
|
||||
scrollBarOverlay:SetTexCoord(0, 1, 0, 1)
|
||||
scrollBarOverlay:SetVertexColor(1, 1, 1, 1)
|
||||
scrollBarOverlay:SetBlendMode("BLEND")
|
||||
|
||||
local scrollChild = CreateFrame("Frame", "SM_CollectionsScrollChild", scrollFrame)
|
||||
scrollChild:SetSize(300, 1)
|
||||
scrollFrame:SetScrollChild(scrollChild)
|
||||
|
||||
-- 右侧模型显示
|
||||
local modelFrame = CreateFrame("Frame", "SM_CollectionsModelFrame", parent)
|
||||
modelFrame:SetSize(380, 430)
|
||||
modelFrame:SetPoint("CENTER", 30, -3)
|
||||
modelFrame:SetFrameStrata("HIGH")
|
||||
modelFrame:SetFrameLevel(parent:GetFrameLevel() + 10)
|
||||
|
||||
-- 3D模型
|
||||
local model = CreateFrame("PlayerModel", "SM_CollectionsModel", modelFrame)
|
||||
model:SetSize(360, 415)
|
||||
model:SetPoint("TOP", 5, 0)
|
||||
model:SetCamera(0)
|
||||
model:SetFacing(0)
|
||||
model.zoomLevel = 0
|
||||
model:SetPosition(0, 0, 0)
|
||||
model:SetFrameStrata("HIGH")
|
||||
model:SetFrameLevel(modelFrame:GetFrameLevel() + 1)
|
||||
|
||||
-- 模型旋转功能
|
||||
model:EnableMouse(true)
|
||||
model:SetScript("OnMouseDown", function(self, button)
|
||||
if button == "LeftButton" then
|
||||
self.isRotating = true
|
||||
self.lastX = GetCursorPosition()
|
||||
end
|
||||
end)
|
||||
model:SetScript("OnMouseUp", function(self, button)
|
||||
if button == "LeftButton" then
|
||||
self.isRotating = false
|
||||
end
|
||||
end)
|
||||
|
||||
local ROTATE_SPEED = math.rad(90)
|
||||
model.isRotatingLeft = false
|
||||
model.isRotatingRight = false
|
||||
|
||||
-- 左旋转按钮
|
||||
local rotateLeftBtn = CreateFrame("Button", nil, modelFrame)
|
||||
rotateLeftBtn:SetSize(32, 32)
|
||||
rotateLeftBtn:SetPoint("BOTTOM", modelFrame, "BOTTOM", -50, 30)
|
||||
rotateLeftBtn:SetNormalTexture("Interface\\Buttons\\UI-RotationLeft-Button-Up")
|
||||
rotateLeftBtn:SetPushedTexture("Interface\\Buttons\\UI-RotationLeft-Button-Down")
|
||||
rotateLeftBtn:SetHighlightTexture("Interface\\Buttons\\UI-RotationLeft-Button-Highlight")
|
||||
rotateLeftBtn:SetFrameStrata("HIGH")
|
||||
rotateLeftBtn:SetFrameLevel(modelFrame:GetFrameLevel() + 2)
|
||||
rotateLeftBtn:SetScript("OnMouseDown", function() model.isRotatingLeft = true end)
|
||||
rotateLeftBtn:SetScript("OnMouseUp", function() model.isRotatingLeft = false end)
|
||||
rotateLeftBtn:HookScript("OnLeave", function() model.isRotatingLeft = false end)
|
||||
|
||||
-- 右旋转按钮
|
||||
local rotateRightBtn = CreateFrame("Button", nil, modelFrame)
|
||||
rotateRightBtn:SetSize(32, 32)
|
||||
rotateRightBtn:SetPoint("BOTTOM", modelFrame, "BOTTOM", 50, 30)
|
||||
rotateRightBtn:SetNormalTexture("Interface\\Buttons\\UI-RotationRight-Button-Up")
|
||||
rotateRightBtn:SetPushedTexture("Interface\\Buttons\\UI-RotationRight-Button-Down")
|
||||
rotateRightBtn:SetHighlightTexture("Interface\\Buttons\\UI-RotationRight-Button-Highlight")
|
||||
rotateRightBtn:SetFrameStrata("HIGH")
|
||||
rotateRightBtn:SetFrameLevel(modelFrame:GetFrameLevel() + 2)
|
||||
rotateRightBtn:SetScript("OnMouseDown", function() model.isRotatingRight = true end)
|
||||
rotateRightBtn:SetScript("OnMouseUp", function() model.isRotatingRight = false end)
|
||||
rotateRightBtn:HookScript("OnLeave", function() model.isRotatingRight = false end)
|
||||
|
||||
-- 旋转更新
|
||||
model:SetScript("OnUpdate", function(self, elapsed)
|
||||
if self.isRotating then
|
||||
local x = GetCursorPosition()
|
||||
local delta = (x - (self.lastX or x)) * 0.01
|
||||
self.lastX = x
|
||||
self:SetFacing(self:GetFacing() + delta)
|
||||
end
|
||||
if self.isRotatingLeft then
|
||||
self:SetFacing(self:GetFacing() + ROTATE_SPEED * elapsed)
|
||||
elseif self.isRotatingRight then
|
||||
self:SetFacing(self:GetFacing() - ROTATE_SPEED * elapsed)
|
||||
end
|
||||
end)
|
||||
|
||||
-- UI元素 - 移除重复的文本显示
|
||||
local nameText = modelFrame:CreateFontString(nil, "OVERLAY","GameFontNormalLarge")
|
||||
nameText:SetPoint("BOTTOM", modelFrame, "BOTTOM", 0, 80) -- 将名称移到模型下方,避免与模型重叠
|
||||
nameText:SetTextColor(1, 1, 1)
|
||||
nameText:SetWidth(320) -- 限制宽度避免文本溢出
|
||||
nameText:SetHeight(0) -- 自动调整高度
|
||||
nameText:SetJustifyH("CENTER")
|
||||
|
||||
-- 描述文本不在模型框架中显示,让右侧面板来显示
|
||||
local descText = modelFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
descText:SetSize(320, 0) -- 自动高度
|
||||
descText:SetPoint("TOP", nameText, "BOTTOM", 0, -5) -- 放在名称下方
|
||||
descText:SetJustifyH("CENTER")
|
||||
descText:Hide() -- 隐藏这个文本,我们将使用右侧面板的文本
|
||||
|
||||
panel.listFrame = listFrame
|
||||
panel.scrollChild = scrollChild
|
||||
panel.modelFrame = modelFrame
|
||||
panel.model = model
|
||||
panel.nameText = nameText
|
||||
panel.descText = descText
|
||||
|
||||
self:CreateListItems(scrollChild, data, itemType, model, nameText, descText)
|
||||
-- 绑定当前panel,便于切换标签时只隐藏panel,不隐藏模型区
|
||||
if self.CurrentPanel then
|
||||
self.CurrentPanel:Hide()
|
||||
end
|
||||
self.CurrentPanel = panel
|
||||
return panel
|
||||
end
|
||||
|
||||
function SM_Collections:CreateListItems(parent, data, itemType, model, nameText, descText)
|
||||
local buttonW = 170
|
||||
local buttonHeight = 40
|
||||
local spacing = 2
|
||||
local iconSize = 30
|
||||
if itemType == "card" then
|
||||
buttonW = 200
|
||||
end
|
||||
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 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)
|
||||
local name, rank, icon = GetSpellInfo(item.id)
|
||||
if icon then
|
||||
ButtonIcon:SetNormalTexture(icon)
|
||||
ButtonIcon:SetHighlightTexture(icon)
|
||||
else
|
||||
ButtonIcon:SetNormalTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
ButtonIcon:SetHighlightTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
end
|
||||
ButtonIcon:SetFrameLevel(button:GetFrameLevel() + 1)
|
||||
ButtonIcon:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(ButtonIcon, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetHyperlink("spell:" .. item.id)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
ButtonIcon:SetScript("OnLeave", function() GameTooltip:Hide() end)
|
||||
ButtonIcon:Show()
|
||||
end
|
||||
local text = button:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
if itemType == "card" then
|
||||
button:SetPoint("TOPLEFT", 0, -(i - 1) * (buttonHeight + spacing))
|
||||
text:SetPoint("CENTER", 0, 0)
|
||||
else
|
||||
text:SetPoint("LEFT", 10, 0)
|
||||
end
|
||||
text:SetText(item.name)
|
||||
text:SetTextColor(item.obtained and 1 or 0.5, item.obtained and 1 or 0.5, item.obtained and 1 or 0.5)
|
||||
button:SetScript("OnClick", function()
|
||||
--nameText:SetText(item.name)
|
||||
-- 不在点击时显示获得状态,只显示名称
|
||||
local creatureDisplayID = self:GetCreatureDisplayID(item.id, itemType)
|
||||
if creatureDisplayID and creatureDisplayID > 0 then
|
||||
model:Hide()
|
||||
model:SetPosition(0, 0, 0)
|
||||
model.zoomLevel = 0
|
||||
model:Show()
|
||||
model:SetCreature(creatureDisplayID)
|
||||
print("creatureDisplayID= ", creatureDisplayID)
|
||||
end
|
||||
self:UpdateRightPanel(item, itemType)
|
||||
end)
|
||||
-- 在鼠标悬停时在工具提示中显示获得状态
|
||||
button:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetText(item.name)
|
||||
local statusText = item.obtained and "|cFF00FF00已获得|r" or "|cFFFF0000未获得|r"
|
||||
GameTooltip:AddLine(statusText)
|
||||
GameTooltip:Show()
|
||||
|
||||
-- 不在模型下方显示获得状态
|
||||
--nameText:SetText(item.name)
|
||||
--nameText:SetTextColor(1, 1, 1)
|
||||
end)
|
||||
|
||||
button:SetScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
button:Show()
|
||||
end
|
||||
local totalHeight = #data * (buttonHeight + spacing)
|
||||
parent:SetHeight(math.max(totalHeight, 1))
|
||||
end
|
||||
|
||||
function SM_Collections:UpdateRightPanel(selectedItem, itemType)
|
||||
if not self.MainFrame or not self.MainFrame.RightSidePanel then
|
||||
return
|
||||
end
|
||||
local rightPanel = self.MainFrame.RightSidePanel
|
||||
|
||||
-- 更新坐骑名称
|
||||
if rightPanel.MountNama then
|
||||
rightPanel.MountNama:SetText(selectedItem.name or "")
|
||||
end
|
||||
|
||||
-- 更新描述文本并确保正确换行
|
||||
if rightPanel.introText then
|
||||
rightPanel.introText:SetText(selectedItem.description or "")
|
||||
rightPanel.introText:SetHeight(0) -- 重置高度以便自动计算
|
||||
end
|
||||
|
||||
-- 显示属性加成
|
||||
if rightPanel.AttributeBonusFrame then
|
||||
self:UpdateAttributesForItem(selectedItem, rightPanel.AttributeBonusFrame, itemType)
|
||||
end
|
||||
end
|
||||
|
||||
function SM_Collections:UpdateAttributesForItem(item, parentFrame, itemType)
|
||||
local children = { parentFrame:GetChildren() }
|
||||
for _, child in ipairs(children) do
|
||||
if child:GetName() and string.find(child:GetName(), "SM_CollectionsAttributeutton") then
|
||||
child:Hide()
|
||||
end
|
||||
end
|
||||
self:GetAttributesForItem(item, function(attributes)
|
||||
if #attributes == 0 then
|
||||
parentFrame:Hide()
|
||||
return
|
||||
end
|
||||
parentFrame:Show()
|
||||
local buttonH = 150
|
||||
local buttonW = 20
|
||||
for i, attribute in ipairs(attributes) do
|
||||
local AttributeName = attribute.Name
|
||||
local AttributeValue = attribute.value
|
||||
local isPositive = attribute.isPositive
|
||||
local button = CreateFrame("Button", "SM_CollectionsAttributeutton" .. i, parentFrame)
|
||||
button:SetSize(buttonH, buttonW)
|
||||
button:SetNormalTexture("Interface\\AddOns\\SM_CollectionSystem\\Textures\\AttributeuttonTexture")
|
||||
button:SetPoint("TOPLEFT", 0, -30 - (i - 1) * (buttonW))
|
||||
local nameText = button:CreateFontString(nil, "OVERLAY")
|
||||
nameText:SetPoint("CENTER", 0, 0)
|
||||
nameText:SetFont("Fonts\\ZYKai_T.ttf", 10, "MONOCHROME")
|
||||
nameText:SetText(AttributeName)
|
||||
nameText:SetTextColor(1, 1, 1)
|
||||
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)
|
||||
valueText:SetTextColor(isPositive and 0 or 1, isPositive and 1 or 0, 0)
|
||||
button:Show()
|
||||
end
|
||||
end, itemType)
|
||||
end
|
||||
|
||||
function SM_Collections:GetAttributesForItem(item, callback, itemType)
|
||||
SM_Collections.DataManager:GetAttributesForSpecificItem(item.id, itemType, function(attributes)
|
||||
callback(attributes)
|
||||
end)
|
||||
end
|
||||
|
||||
function SM_Collections:CreateItemGrid(parent, items)
|
||||
local buttonSize = 40
|
||||
local spacing = 5
|
||||
local buttonsPerRow = 16
|
||||
for i, item in ipairs(items) do
|
||||
local button = CreateFrame("Button", "SM_CollectionsItemGridButton", parent)
|
||||
button:SetSize(buttonSize, buttonSize)
|
||||
local row = math.floor((i - 1) / buttonsPerRow)
|
||||
local col = (i - 1) % buttonsPerRow
|
||||
button:SetPoint("TOPLEFT", 10 + col * (buttonSize + spacing), -10 + -row * (buttonSize + spacing))
|
||||
local texture = button:CreateTexture(nil, "ARTWORK")
|
||||
texture:SetAllPoints()
|
||||
local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture =
|
||||
GetItemInfo(item.id)
|
||||
texture:SetTexture(itemTexture)
|
||||
if not item.obtained then
|
||||
texture:SetDesaturated(true)
|
||||
else
|
||||
texture:SetDesaturated(false)
|
||||
end
|
||||
button:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
|
||||
button:HookScript("OnClick", function()
|
||||
if item.obtained then
|
||||
print("选择了物品: " .. item.name)
|
||||
else
|
||||
print("您还没有获得: " .. item.name)
|
||||
end
|
||||
end)
|
||||
button:HookScript("OnEnter", function(self)
|
||||
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetText(item.name)
|
||||
GameTooltip:SetHyperlink('Hitem:' .. item.id)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
button:HookScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
button:Show()
|
||||
end
|
||||
local rows = math.ceil(#items / buttonsPerRow)
|
||||
local totalHeight = rows * (buttonSize + spacing)
|
||||
parent:SetHeight(math.max(totalHeight, 1))
|
||||
end
|
||||
48
SM_Utils.lua
Normal file
48
SM_Utils.lua
Normal file
@ -0,0 +1,48 @@
|
||||
-- SM_Utils.lua
|
||||
|
||||
function SM_Collections:MessageSplit(inputstr, sep)
|
||||
if not inputstr or inputstr == "" then
|
||||
return {}
|
||||
end
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local t = {}
|
||||
for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
|
||||
table.insert(t, str)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function SM_Collections:GetMountInfo(spellID)
|
||||
local info = self.Mounts[spellID]
|
||||
if info then
|
||||
return unpack(info, 1, 9)
|
||||
end
|
||||
end
|
||||
|
||||
function SM_Collections:GetCreatureDisplayID(itemID, itemType)
|
||||
if itemType == "mount" then
|
||||
local mountInfo = self:GetMountInfo(itemID)
|
||||
if mountInfo then
|
||||
return mountInfo -- 第一个返回值就是 creatureDisplayID
|
||||
end
|
||||
elseif itemType == "companion" then
|
||||
local companionMap = {
|
||||
[62508] = 33194, -- 丹莫罗熊宝宝 -> 熊的显示ID
|
||||
[28871] = 16701, -- 仲夏之魂 -> 火元素显示ID
|
||||
[13548] = 30379, -- 农场小鸡 -> 鸡的显示ID
|
||||
[23811] = 14878, -- 加布林
|
||||
}
|
||||
return companionMap[itemID] or itemID
|
||||
elseif itemType == "card" then
|
||||
local cardMap = {
|
||||
[11502] = 11502, -- 拉格纳罗斯
|
||||
[24248] = 24248, -- 巫妖王
|
||||
[19299] = 19299, -- 死亡耳语者
|
||||
[32588] = 32588, -- 伊利丹
|
||||
}
|
||||
return cardMap[itemID] or itemID
|
||||
end
|
||||
return itemID
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user