更新
This commit is contained in:
parent
c48a9deb66
commit
d00ce59006
BIN
excel/cha.xlsx
BIN
excel/cha.xlsx
Binary file not shown.
BIN
excel/enemy.xlsx
BIN
excel/enemy.xlsx
Binary file not shown.
Binary file not shown.
BIN
excel/level.xlsx
BIN
excel/level.xlsx
Binary file not shown.
@ -41,6 +41,7 @@ function UIList:Init(Prefab: Instance)
|
||||
self.Instances = {}
|
||||
self.Connections = {}
|
||||
self.LayoutOrderKey = nil
|
||||
self.reverse = false
|
||||
self.Component = nil
|
||||
self.UIRoot = Prefab
|
||||
self.Org = Utils:FindInDescendantsUI(Prefab, "__org")
|
||||
@ -89,10 +90,23 @@ function UIList:RemoveData(key)
|
||||
end
|
||||
end
|
||||
|
||||
function UIList:SetLayoutOrder(keyName: string)
|
||||
self.LayoutOrderKey = keyName
|
||||
function UIList:FindSameDataInstance(data)
|
||||
for _, ui in pairs(self.Instances) do
|
||||
ui.UIRoot.LayoutOrder = tonumber(ui.Data[keyName])
|
||||
if ui.Data == data then
|
||||
return ui
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UIList:SetLayoutOrder(keyName: string, reverse: boolean?)
|
||||
self.LayoutOrderKey = keyName
|
||||
if reverse then self.reverse = true else self.reverse = false end
|
||||
for _, ui in pairs(self.Instances) do
|
||||
if self.reverse then
|
||||
ui.UIRoot.LayoutOrder = 1000 - tonumber(ui.Data[keyName])
|
||||
else
|
||||
ui.UIRoot.LayoutOrder = tonumber(ui.Data[keyName])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -106,7 +120,11 @@ function UIList:SetSingleInstance(index: number, data: table)
|
||||
uiInstance.Name = index
|
||||
uiInstance.Parent = self.Org.Parent
|
||||
if self.LayoutOrderKey then
|
||||
uiInstance.LayoutOrder = tonumber(child.Data[self.LayoutOrderKey])
|
||||
if self.reverse then
|
||||
uiInstance.LayoutOrder = 1000 - tonumber(child.Data[self.LayoutOrderKey])
|
||||
else
|
||||
uiInstance.LayoutOrder = tonumber(child.Data[self.LayoutOrderKey])
|
||||
end
|
||||
end
|
||||
self.Instances[index] = child
|
||||
|
||||
@ -129,7 +147,10 @@ function UIList:GetMinLayoutOrderInstance()
|
||||
end
|
||||
|
||||
function UIList:Refresh()
|
||||
for _, ui in pairs(self.Instances) do ui:Destroy() end
|
||||
for _, ui in pairs(self.Instances) do
|
||||
if ui.UIRoot then ui.UIRoot:Destroy() end
|
||||
ui:Destroy()
|
||||
end
|
||||
self.Instances = {}
|
||||
|
||||
if not self.Component then warn("UIList:Refresh() Component未设置") return end
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{"id":1,"type":1,"effectAttribute":"attack","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":2,"type":1,"effectAttribute":"hp","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":1,"type":1,"effectAttribute":"attack","cost":[1,10,20],"lvAdd":[100,845],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":2,"type":1,"effectAttribute":"hp","cost":[1,10,20],"lvAdd":[2000,845],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":3,"type":1,"effectAttribute":"swordAtk","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":4,"type":1,"effectAttribute":"swordWearBase","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
|
||||
{"id":5,"type":1,"effectAttribute":"swordWearSpe","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
|
||||
|
@ -1,3 +1,3 @@
|
||||
[
|
||||
{"id":1,"name":1,"attack":10,"hp":100,"walkSpeed":10,"atkSpeed":1}
|
||||
{"id":1,"name":1,"attack":100,"hp":2000,"walkSpeed":10,"atkSpeed":1}
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
[
|
||||
{"id":1,"type":1,"name":1,"attack":10,"hp":100,"walkSpeed":10,"attackSpeed":2,"model":"Thief"},
|
||||
{"id":1,"type":1,"name":1,"attack":83,"hp":400,"walkSpeed":10,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":2,"type":1,"name":2,"attack":30,"hp":300,"walkSpeed":10,"attackSpeed":1,"model":"Thief"},
|
||||
{"id":1000,"type":2,"name":1000,"attack":50,"hp":1000,"walkSpeed":20,"attackSpeed":1,"model":"Thief"}
|
||||
{"id":1000,"type":2,"name":1000,"attack":240,"hp":2000,"walkSpeed":20,"attackSpeed":1,"model":"Thief"}
|
||||
]
|
@ -1,17 +1,17 @@
|
||||
[
|
||||
{"id":1,"cost":[2,20]},
|
||||
{"id":2,"cost":[2,30]},
|
||||
{"id":3,"cost":[2,40]},
|
||||
{"id":4,"cost":[2,50]},
|
||||
{"id":5,"cost":[2,60]},
|
||||
{"id":6,"cost":[2,70]},
|
||||
{"id":7,"cost":[2,80]},
|
||||
{"id":8,"cost":[2,90]},
|
||||
{"id":9,"cost":[2,100]},
|
||||
{"id":10,"cost":[2,110]},
|
||||
{"id":11,"cost":[2,120]},
|
||||
{"id":12,"cost":[2,130]},
|
||||
{"id":13,"cost":[2,140]},
|
||||
{"id":14,"cost":[2,150]},
|
||||
{"id":15,"cost":[2,160]}
|
||||
{"id":1,"cost":[1,500]},
|
||||
{"id":2,"cost":[1,500]},
|
||||
{"id":3,"cost":[1,500]},
|
||||
{"id":4,"cost":[1,500]},
|
||||
{"id":5,"cost":[1,500]},
|
||||
{"id":6,"cost":[1,500]},
|
||||
{"id":7,"cost":[1,500]},
|
||||
{"id":8,"cost":[1,500]},
|
||||
{"id":9,"cost":[1,500]},
|
||||
{"id":10,"cost":[1,500]},
|
||||
{"id":11,"cost":[1,500]},
|
||||
{"id":12,"cost":[1,500]},
|
||||
{"id":13,"cost":[1,500]},
|
||||
{"id":14,"cost":[1,500]},
|
||||
{"id":15,"cost":[1,500]}
|
||||
]
|
@ -1,22 +1,52 @@
|
||||
[
|
||||
{"id":1,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1]]},
|
||||
{"id":2,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":3,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":4,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":5,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]]},
|
||||
{"id":6,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":7,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":8,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":9,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":10,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]]},
|
||||
{"id":11,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":12,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":13,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":14,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":15,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]]},
|
||||
{"id":16,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":17,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":18,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":19,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1],[10,1,1,10,2,1]]},
|
||||
{"id":20,"type":2,"timeLimit":60,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1000,1]]}
|
||||
{"id":1,"type":1,"timeLimit":null,"atkBonus":500,"hpBonus":500,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":2,"type":1,"timeLimit":null,"atkBonus":520,"hpBonus":520,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":3,"type":1,"timeLimit":null,"atkBonus":540,"hpBonus":540,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":4,"type":1,"timeLimit":null,"atkBonus":560,"hpBonus":560,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":5,"type":2,"timeLimit":60,"atkBonus":1050,"hpBonus":1050,"wave":[[10,1000,1]]},
|
||||
{"id":6,"type":1,"timeLimit":null,"atkBonus":600,"hpBonus":600,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":7,"type":1,"timeLimit":null,"atkBonus":620,"hpBonus":620,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":8,"type":1,"timeLimit":null,"atkBonus":640,"hpBonus":640,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":9,"type":1,"timeLimit":null,"atkBonus":660,"hpBonus":660,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":10,"type":2,"timeLimit":60,"atkBonus":1100,"hpBonus":1100,"wave":[[10,1000,1]]},
|
||||
{"id":11,"type":1,"timeLimit":null,"atkBonus":700,"hpBonus":700,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":12,"type":1,"timeLimit":null,"atkBonus":720,"hpBonus":720,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":13,"type":1,"timeLimit":null,"atkBonus":740,"hpBonus":740,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":14,"type":1,"timeLimit":null,"atkBonus":760,"hpBonus":760,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":15,"type":2,"timeLimit":60,"atkBonus":1150,"hpBonus":1150,"wave":[[10,1000,1]]},
|
||||
{"id":16,"type":1,"timeLimit":null,"atkBonus":800,"hpBonus":800,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":17,"type":1,"timeLimit":null,"atkBonus":820,"hpBonus":820,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":18,"type":1,"timeLimit":null,"atkBonus":840,"hpBonus":840,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":19,"type":1,"timeLimit":null,"atkBonus":860,"hpBonus":860,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":20,"type":2,"timeLimit":60,"atkBonus":1250,"hpBonus":1250,"wave":[[10,1000,1]]},
|
||||
{"id":21,"type":1,"timeLimit":null,"atkBonus":900,"hpBonus":900,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":22,"type":1,"timeLimit":null,"atkBonus":920,"hpBonus":920,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":23,"type":1,"timeLimit":null,"atkBonus":940,"hpBonus":940,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":24,"type":1,"timeLimit":null,"atkBonus":960,"hpBonus":960,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":25,"type":2,"timeLimit":60,"atkBonus":1350,"hpBonus":1350,"wave":[[10,1000,1]]},
|
||||
{"id":26,"type":1,"timeLimit":null,"atkBonus":1000,"hpBonus":1000,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":27,"type":1,"timeLimit":null,"atkBonus":1020,"hpBonus":1020,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":28,"type":1,"timeLimit":null,"atkBonus":1040,"hpBonus":1040,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":29,"type":1,"timeLimit":null,"atkBonus":1060,"hpBonus":1060,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":30,"type":2,"timeLimit":60,"atkBonus":1500,"hpBonus":1500,"wave":[[10,1000,1]]},
|
||||
{"id":31,"type":1,"timeLimit":null,"atkBonus":1100,"hpBonus":1100,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":32,"type":1,"timeLimit":null,"atkBonus":1120,"hpBonus":1120,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":33,"type":1,"timeLimit":null,"atkBonus":1140,"hpBonus":1140,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":34,"type":1,"timeLimit":null,"atkBonus":1160,"hpBonus":1160,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":35,"type":2,"timeLimit":60,"atkBonus":2000,"hpBonus":2000,"wave":[[10,1000,1]]},
|
||||
{"id":36,"type":1,"timeLimit":null,"atkBonus":1200,"hpBonus":1200,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":37,"type":1,"timeLimit":null,"atkBonus":1220,"hpBonus":1220,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":38,"type":1,"timeLimit":null,"atkBonus":1240,"hpBonus":1240,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":39,"type":1,"timeLimit":null,"atkBonus":1260,"hpBonus":1260,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":40,"type":2,"timeLimit":60,"atkBonus":2500,"hpBonus":2500,"wave":[[10,1000,1]]},
|
||||
{"id":41,"type":1,"timeLimit":null,"atkBonus":1300,"hpBonus":1300,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":42,"type":1,"timeLimit":null,"atkBonus":1320,"hpBonus":1320,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":43,"type":1,"timeLimit":null,"atkBonus":1340,"hpBonus":1340,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":44,"type":1,"timeLimit":null,"atkBonus":1360,"hpBonus":1360,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":45,"type":2,"timeLimit":60,"atkBonus":3000,"hpBonus":3000,"wave":[[10,1000,1]]},
|
||||
{"id":46,"type":1,"timeLimit":null,"atkBonus":1400,"hpBonus":1400,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":47,"type":1,"timeLimit":null,"atkBonus":1420,"hpBonus":1420,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":48,"type":1,"timeLimit":null,"atkBonus":1440,"hpBonus":1440,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":49,"type":1,"timeLimit":null,"atkBonus":1460,"hpBonus":1460,"wave":[[10,1,1,50,1,1,100,1,1,150,1,1,200,1,1,250,1,1]]},
|
||||
{"id":50,"type":2,"timeLimit":60,"atkBonus":3500,"hpBonus":3500,"wave":[[10,1000,1]]}
|
||||
]
|
@ -64,7 +64,11 @@ function BookProxy:AddBook(Player: Player, BookId: number, UniqueEquipmentId: nu
|
||||
local EquipmentData = EquipmentProxy:GetEquipmentData(Player, UniqueEquipmentId)
|
||||
if not EquipmentData then return end
|
||||
|
||||
|
||||
-- 变成字符串,因为在次读取后,是字典
|
||||
local BookId = tostring(BookId)
|
||||
local orgBookData = ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId]
|
||||
|
||||
-- 检查是否已经存在
|
||||
if orgBookData then
|
||||
-- 图鉴没原先品质高就返回
|
||||
@ -86,6 +90,7 @@ end
|
||||
|
||||
-- 解锁图鉴
|
||||
function BookProxy:UnlockBook(Player: Player, BookId: number)
|
||||
local BookId = tostring(BookId)
|
||||
local pData = Utils:GetPlayerDataFolder(Player)
|
||||
if not pData then return end
|
||||
|
||||
@ -102,7 +107,7 @@ end
|
||||
|
||||
-- 检查是否解锁对应图鉴
|
||||
function BookProxy:IsBookUnlocked(Player: Player, BookId: number)
|
||||
return ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId] ~= nil
|
||||
return ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[tostring(BookId)]
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -21,7 +21,6 @@ local JsonParam = require(ReplicatedStorage.Json.Param)
|
||||
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
|
||||
local RE_WearEquipment = ReplicatedStorage.Events.RE_WearEquipment
|
||||
|
||||
|
||||
--> Constants
|
||||
local STORE_NAME = "Equipment"
|
||||
|
||||
@ -219,12 +218,12 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
|
||||
------------------------------------------------------------
|
||||
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME][UniqueId] = ResultData
|
||||
print(ArchiveProxy.pData[Player.UserId][STORE_NAME])
|
||||
Utils:CreateDataInstance(Player, UniqueId, ResultData, GetPlayerEquipmentFolder(Player))
|
||||
local equipmentInstance = Utils:CreateDataInstance(Player, UniqueId, ResultData, GetPlayerEquipmentFolder(Player))
|
||||
|
||||
-- 添加图鉴记录
|
||||
local BookProxy = require(ServerStorage.Proxy.BookProxy)
|
||||
BookProxy:AddBook(Player, EquipmentId, UniqueId)
|
||||
return equipmentInstance
|
||||
end
|
||||
|
||||
-- 回收装备
|
||||
|
@ -20,6 +20,7 @@ local JsonForge = require(ReplicatedStorage.Json.Forge)
|
||||
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
|
||||
local RE_Forge = ReplicatedStorage.Events.RE_Forge
|
||||
local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes
|
||||
local RE_ShowGetEquipments = ReplicatedStorage.Events.RE_ShowGetEquipments
|
||||
|
||||
--> Constants
|
||||
local STORE_NAME = "PlayerInfo"
|
||||
@ -67,6 +68,7 @@ local STATS_DATA = {
|
||||
name = {type = ENUM_STATE_TYPE.String, value = "PlayerName"},
|
||||
level = {type = ENUM_STATE_TYPE.Number, value = 1},
|
||||
exp = {type = ENUM_STATE_TYPE.Number, value = 0},
|
||||
forge = {type = ENUM_STATE_TYPE.Number, value = 1},
|
||||
}
|
||||
|
||||
-- 初始化玩家状态信息(采用额外添加的模式,如果没有写值,就覆盖写入)
|
||||
@ -75,7 +77,7 @@ local function ExtraAddPlayerStats(Player: Player, StatsData: table)
|
||||
-- 如果列表中不包含信息就添加到表中
|
||||
for StateKey, StateValue in STATS_DATA do
|
||||
if not StatsData[StateKey] then
|
||||
StatsData[StateKey] = StateValue
|
||||
StatsData[StateKey] = StateValue.value
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -97,7 +99,6 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats = {}
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME].Items = {}
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade = {}
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME].Forge = 1
|
||||
end
|
||||
|
||||
-- 放在外面是为了以后系统新增内容方便(同时不用在初始化数据是做写入了)
|
||||
@ -108,7 +109,7 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
|
||||
CreateInfoInstance(Player, ItemsFolder, ItemId, ENUM_STATE_TYPE.Number, ItemValue)
|
||||
end
|
||||
for StateKey, StateData in ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats do
|
||||
CreateInfoInstance(Player, StatsFolder, StateKey, StateData.type, StateData.value)
|
||||
CreateInfoInstance(Player, StatsFolder, StateKey, STATS_DATA[StateKey].type, StateData)
|
||||
end
|
||||
for AttributeId, AttributeLv in ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade do
|
||||
CreateInfoInstance(Player, AttributesUpgradeFolder, AttributeId, "NumberValue", AttributeLv)
|
||||
@ -127,7 +128,7 @@ end
|
||||
function PlayerInfoProxy:GetPlayerLevel(Player: Player)
|
||||
if not Player then warn('获取玩家等级失败: ', Player.Name) return end
|
||||
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME]
|
||||
return playerInfoData.Stats.level.value
|
||||
return playerInfoData.Stats.level
|
||||
end
|
||||
|
||||
function PlayerInfoProxy:GetPlayerAttributesUpgrade(Player: Player, AttributeName: string)
|
||||
@ -153,7 +154,7 @@ function PlayerInfoProxy:UpgradeAttribute(Player: Player, AttributeId: number)
|
||||
requireMoney = attributeData["cost"][2]
|
||||
requireBattleValue = attributeData["battleValueLimit"][1]
|
||||
else
|
||||
requireMoney = attributeData["cost"][2] + (nowLv - 1) * attributeData["cost"][3]
|
||||
requireMoney = math.floor(attributeData["cost"][2] ^ (nowLv - 1) * attributeData["cost"][3] / 100)
|
||||
requireBattleValue = attributeData["battleValueLimit"][1] + (nowLv - 1) * attributeData["battleValueLimit"][2]
|
||||
end
|
||||
|
||||
@ -255,6 +256,7 @@ end
|
||||
-- 打造装备
|
||||
function PlayerInfoProxy:MakeForge(Player: Player, EquipmentId: number, Count: number)
|
||||
if not Player or not EquipmentId then warn('打造装备失败: ', Player.Name,EquipmentId) return end
|
||||
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME]
|
||||
|
||||
local PlayerInfoFolder = GetPlayerInfoFolder(Player)
|
||||
if not PlayerInfoFolder then return end
|
||||
@ -266,18 +268,23 @@ function PlayerInfoProxy:MakeForge(Player: Player, EquipmentId: number, Count: n
|
||||
return
|
||||
end
|
||||
|
||||
-- 锻造数量>1,判断是否到达最高锻造等级
|
||||
local ForgeLv = PlayerInfoProxy:GetPlayerInfo(Player).Forge
|
||||
if Count > 1 then
|
||||
local MaxForgeLv = Utils:GetMaxIdFromJson(JsonForge, ForgeLv)
|
||||
if ForgeLv < MaxForgeLv then
|
||||
RE_PlayerTip:FireClient(Player, "锻造等级已到达最高等级")
|
||||
return
|
||||
-- 判断金钱是否足够
|
||||
local MaxForgeLv = Utils:GetMaxIdFromJson(JsonForge)
|
||||
local ShouldCostMoney = 0
|
||||
for i = 1, Count do
|
||||
-- 读取等级并且做最大值限制
|
||||
local ForgeLv = ArchiveProxy.pData[Player.UserId][STORE_NAME]["Stats"].forge
|
||||
ForgeLv = ForgeLv > MaxForgeLv and MaxForgeLv or ForgeLv
|
||||
|
||||
local ForgeData = Utils:GetIdDataFromJson(JsonForge, ForgeLv)
|
||||
ShouldCostMoney = ShouldCostMoney + ForgeData["cost"][2]
|
||||
|
||||
if ForgeLv > MaxForgeLv then
|
||||
ForgeLv = MaxForgeLv
|
||||
else
|
||||
ForgeLv = ForgeLv + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- 判断金钱是否足够
|
||||
local ShouldCostMoney = Utils:GetIdDataFromJson(JsonForge, ForgeLv)["cost"][2] * Count
|
||||
if not self:HasEnoughItem(Player, 1, ShouldCostMoney) then
|
||||
RE_PlayerTip:FireClient(Player, "金钱不足")
|
||||
return
|
||||
@ -286,16 +293,19 @@ function PlayerInfoProxy:MakeForge(Player: Player, EquipmentId: number, Count: n
|
||||
self:ChangeItemCount(Player, 1, -ShouldCostMoney)
|
||||
|
||||
-- 生成对应装备
|
||||
local ResultData = {}
|
||||
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
|
||||
for i = 1, Count do
|
||||
EquipmentProxy:AddEquipment(Player, EquipmentId)
|
||||
local EquipmentInstance = EquipmentProxy:AddEquipment(Player, EquipmentId)
|
||||
table.insert(ResultData, EquipmentInstance)
|
||||
end
|
||||
|
||||
-- 锻造升级
|
||||
ForgeLv = ForgeLv + Count
|
||||
ChangeInfoInstance(Player, PlayerInfoFolder, "Forge", ForgeLv)
|
||||
ArchiveProxy.pData[Player.UserId][STORE_NAME]["Stats"].forge = ArchiveProxy.pData[Player.UserId][STORE_NAME]["Stats"].forge + Count
|
||||
ChangeInfoInstance(Player, PlayerInfoFolder:FindFirstChild("Stats"), "forge", ArchiveProxy.pData[Player.UserId][STORE_NAME]["Stats"].forge)
|
||||
|
||||
-- TODO: 添加对应奖励弹窗
|
||||
-- 装备奖励弹窗
|
||||
RE_ShowGetEquipments:FireClient(Player, ResultData)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -307,7 +317,8 @@ function PlayerInfoProxy:GetPlayerUpgradeAttributes(Player: Player)
|
||||
local attributes = {}
|
||||
for AttributeId, AttributeLv in playerInfoData.AttributesUpgrade do
|
||||
local attributeData = Utils:GetIdDataFromJson(JsonAttributesUpgrade, AttributeId)
|
||||
attributes[attributeData["effectAttribute"]] = attributeData["lvAdd"][1] + (AttributeLv - 1) * attributeData["lvAdd"][2]
|
||||
-- attributes[attributeData["effectAttribute"]] = attributeData["lvAdd"][1] + (AttributeLv - 1) * attributeData["lvAdd"][2]
|
||||
attributes[attributeData["effectAttribute"]] = math.floor(attributeData["lvAdd"][1] ^ (AttributeLv - 1) * attributeData["lvAdd"][2] / 10000)
|
||||
end
|
||||
return attributes
|
||||
end
|
||||
|
69
src/StarterPlayerScripts/ClientMain/HealthBar.luau
Normal file
69
src/StarterPlayerScripts/ClientMain/HealthBar.luau
Normal file
@ -0,0 +1,69 @@
|
||||
local HealthBar = {}
|
||||
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
local Workspace = game:GetService("Workspace")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
local BoardFolder = ReplicatedStorage:WaitForChild("UI"):WaitForChild("Board")
|
||||
local HeadBar = BoardFolder:WaitForChild("HeadBar")
|
||||
|
||||
local LocalPlayer = Players.LocalPlayer
|
||||
local MobsFolder = Workspace:WaitForChild("Mobs"):WaitForChild(LocalPlayer.UserId)
|
||||
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
|
||||
|
||||
local Connections = {}
|
||||
|
||||
local function SetHp(child, hpFill, Attributes)
|
||||
local hpValue = Attributes:GetAttribute("hp")
|
||||
local maxHpValue = Attributes:GetAttribute("maxhp")
|
||||
hpFill.Size = UDim2.new(hpValue / maxHpValue, 0, 1, 0)
|
||||
end
|
||||
|
||||
local function SetHealthBar(child, prefab)
|
||||
local HealthBarInstance = prefab:Clone()
|
||||
|
||||
local CoordinateFrame: CFrame, Size: Vector3 = child:GetBoundingBox()
|
||||
HealthBarInstance.Adornee = child.HumanoidRootPart
|
||||
HealthBarInstance.StudsOffsetWorldSpace = Vector3.new(0, (CoordinateFrame.Position.Y+Size.Y/2) - child.HumanoidRootPart.Position.Y+2, 0)
|
||||
HealthBarInstance.Enabled = true
|
||||
local hpFill = HealthBarInstance:WaitForChild("Canvas"):WaitForChild("HealthBar"):WaitForChild("Fill")
|
||||
HealthBarInstance.Parent = child
|
||||
|
||||
local Attributes = child:WaitForChild("Attributes")
|
||||
local attributeCon = Attributes.AttributeChanged:Connect(function(attribute)
|
||||
if attribute == "hp" then
|
||||
SetHp(child, hpFill, Attributes)
|
||||
end
|
||||
end)
|
||||
Connections[child] = attributeCon
|
||||
|
||||
-- 初始化设置血量
|
||||
SetHp(child, hpFill, Attributes)
|
||||
end
|
||||
|
||||
-- 玩家自己特殊监听
|
||||
SetHealthBar(Character, HeadBar)
|
||||
|
||||
-- 监听玩家角色重新生成(暂时没放在Connections中)
|
||||
LocalPlayer.CharacterAdded:Connect(function(newCharacter)
|
||||
Character = newCharacter
|
||||
SetHealthBar(Character, HeadBar)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- TODO: 监听玩家怪物目录下的怪物增减,处理对应血条
|
||||
MobsFolder.ChildAdded:Connect(function(child)
|
||||
if child:IsA("Model") then
|
||||
SetHealthBar(child, HeadBar)
|
||||
end
|
||||
end)
|
||||
|
||||
MobsFolder.ChildRemoved:Connect(function(child)
|
||||
if Connections[child] then
|
||||
Connections[child]:Disconnect()
|
||||
Connections[child] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
return HealthBar
|
@ -15,7 +15,7 @@ UserInputService.InputBegan:Connect(function(input, gameProcessed)
|
||||
if input.KeyCode == Enum.KeyCode.H then
|
||||
RE_PlayerHelper:FireServer("CleanPlayerData")
|
||||
elseif input.KeyCode == Enum.KeyCode.J then
|
||||
RE_PlayerHelper:FireServer("AddItem", {1, 100})
|
||||
RE_PlayerHelper:FireServer("AddItem", {1, 1000})
|
||||
elseif input.KeyCode == Enum.KeyCode.K then
|
||||
RE_UpgradeAttributes:FireServer(1)
|
||||
elseif input.KeyCode == Enum.KeyCode.L then
|
||||
|
@ -12,6 +12,7 @@ local RE_PerformanceEvent = EventsFolder:FindFirstChild("RE_PerformanceEvent")
|
||||
local RE_CleanPlayerPerformance = EventsFolder:FindFirstChild("RE_CleanPlayerPerformance")
|
||||
local RE_DamagePerformance = EventsFolder:FindFirstChild("RE_DamagePerformance")
|
||||
local RE_AbilityPerformance = EventsFolder:FindFirstChild("RE_AbilityPerformance")
|
||||
local RE_ShowGetEquipments = EventsFolder:FindFirstChild("RE_ShowGetEquipments")
|
||||
|
||||
--> Dependencies
|
||||
local UIManager = require(script.Parent.Parent.UI.UIManager)
|
||||
@ -113,6 +114,13 @@ RE_CleanPlayerPerformance.OnClientEvent:Connect(function(CleanedPlayer: Player)
|
||||
PerformanceClient.pData[UserId] = nil
|
||||
end)
|
||||
|
||||
-- 监听获取装备事件调用
|
||||
RE_ShowGetEquipments.OnClientEvent:Connect(function(EquipmentDetail: table)
|
||||
if not UIManager:IsOpened("GetEquipmentsWindow") then
|
||||
UIManager:OpenWindow("GetEquipmentsWindow", EquipmentDetail)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打开默认界面
|
||||
UIManager:OpenWindow("MainWindow")
|
||||
UIManager:OpenWindow("TipsWindow")
|
||||
|
@ -4,10 +4,98 @@ local FolderWindows = script.Parent.Windows
|
||||
|
||||
UIManager.Instances = {}
|
||||
UIManager.Windows = {}
|
||||
UIManager.WindowStack = {} -- 窗口堆栈
|
||||
UIManager.ExcludeFromStack = { -- 不受堆栈影响的窗口列表
|
||||
"TipsWindow", -- 主窗口
|
||||
"AbilityStateWindow",
|
||||
-- 可以继续添加其他窗口名称
|
||||
}
|
||||
|
||||
for _, child in FolderWindows:GetChildren() do
|
||||
UIManager.Windows[child.Name] = require(child)
|
||||
end
|
||||
|
||||
-- 获取窗口的ZIndex
|
||||
local function getWindowZIndex(windowInstance)
|
||||
if not windowInstance or not windowInstance.UIRoot then
|
||||
return 0
|
||||
end
|
||||
return windowInstance.UIRoot.ZIndex or 0
|
||||
end
|
||||
|
||||
-- 设置窗口的Interactable
|
||||
local function setWindowInteractable(windowInstance, interactable)
|
||||
if not windowInstance or not windowInstance.UIRoot then
|
||||
return
|
||||
end
|
||||
|
||||
-- 根窗口本身就是CanvasGroup
|
||||
if windowInstance.UIRoot:IsA("CanvasGroup") then
|
||||
windowInstance.UIRoot.Interactable = interactable
|
||||
end
|
||||
end
|
||||
|
||||
-- 检查窗口是否在排除列表中
|
||||
local function isExcludedFromStack(windowName)
|
||||
for _, excludedName in ipairs(UIManager.ExcludeFromStack) do
|
||||
if windowName == excludedName then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 管理窗口堆栈
|
||||
local function manageWindowStack(newWindowName, newWindowInstance)
|
||||
-- 检查是否在排除列表中
|
||||
if isExcludedFromStack(newWindowName) then
|
||||
return
|
||||
end
|
||||
|
||||
local newZIndex = getWindowZIndex(newWindowInstance)
|
||||
|
||||
-- 检查堆栈中所有窗口,设置ZIndex较低的窗口为false
|
||||
for i = #UIManager.WindowStack, 1, -1 do
|
||||
local stackWindow = UIManager.WindowStack[i]
|
||||
local stackZIndex = getWindowZIndex(stackWindow.instance)
|
||||
|
||||
-- 如果堆栈中窗口的ZIndex小于等于新窗口,设置为false
|
||||
if stackZIndex <= newZIndex then
|
||||
-- 设置之前窗口的Interactable为false
|
||||
setWindowInteractable(stackWindow.instance, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- 将新窗口添加到堆栈顶部
|
||||
table.insert(UIManager.WindowStack, {
|
||||
name = newWindowName,
|
||||
instance = newWindowInstance,
|
||||
zIndex = newZIndex
|
||||
})
|
||||
end
|
||||
|
||||
-- 移除窗口堆栈中的窗口
|
||||
local function removeFromWindowStack(windowName)
|
||||
-- 检查是否在排除列表中
|
||||
if isExcludedFromStack(windowName) then
|
||||
return
|
||||
end
|
||||
|
||||
for i = #UIManager.WindowStack, 1, -1 do
|
||||
if UIManager.WindowStack[i].name == windowName then
|
||||
table.remove(UIManager.WindowStack, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- 如果堆栈不为空,设置顶部窗口的Interactable为true
|
||||
if #UIManager.WindowStack > 0 then
|
||||
local topWindow = UIManager.WindowStack[#UIManager.WindowStack]
|
||||
setWindowInteractable(topWindow.instance, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- 打开窗口
|
||||
function UIManager:OpenWindow(WindowName: string, Data: table?)
|
||||
if not UIManager.Windows[WindowName] then
|
||||
warn("UIManager:OpenWindow() 窗口不存在:" .. WindowName)
|
||||
@ -16,22 +104,21 @@ function UIManager:OpenWindow(WindowName: string, Data: table?)
|
||||
|
||||
UIManager.Instances[WindowName] = UIManager.Windows[WindowName]:Init(self, Data)
|
||||
UIManager.Instances[WindowName]:OnOpenWindow()
|
||||
|
||||
-- 管理窗口堆栈
|
||||
manageWindowStack(WindowName, UIManager.Instances[WindowName])
|
||||
end
|
||||
|
||||
function UIManager:SetData(WindowName: string, Data: table)
|
||||
if not UIManager.Instances[WindowName] then
|
||||
warn("UIManager:SetData() 窗口不存在:" .. WindowName)
|
||||
return
|
||||
end
|
||||
UIManager.Instances[WindowName]:SetData(Data)
|
||||
end
|
||||
|
||||
-- 关闭窗口
|
||||
function UIManager:CloseWindow(WindowName: string)
|
||||
if not UIManager.Instances[WindowName] then
|
||||
warn("UIManager:CloseWindow() 窗口不存在:" .. WindowName)
|
||||
return
|
||||
end
|
||||
|
||||
-- 从堆栈中移除窗口
|
||||
removeFromWindowStack(WindowName)
|
||||
|
||||
UIManager.Instances[WindowName]:OnCloseWindow()
|
||||
UIManager.Instances[WindowName]:Destroy()
|
||||
UIManager.Instances[WindowName] = nil
|
||||
@ -41,5 +128,51 @@ function UIManager:IsOpened(WindowName: string)
|
||||
return UIManager.Instances[WindowName] ~= nil
|
||||
end
|
||||
|
||||
-- 获取当前窗口堆栈信息(用于调试)
|
||||
function UIManager:GetWindowStackInfo()
|
||||
local info = {}
|
||||
for i, window in ipairs(UIManager.WindowStack) do
|
||||
table.insert(info, {
|
||||
name = window.name,
|
||||
zIndex = window.zIndex,
|
||||
index = i
|
||||
})
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
||||
-- 打印窗口堆栈(用于调试)
|
||||
function UIManager:PrintWindowStack()
|
||||
print("=== 窗口堆栈信息 ===")
|
||||
for i, window in ipairs(UIManager.WindowStack) do
|
||||
print(string.format("[%d] %s (ZIndex: %d)", i, window.name, window.zIndex))
|
||||
end
|
||||
print("==================")
|
||||
end
|
||||
|
||||
-- 添加窗口到排除列表
|
||||
function UIManager:AddToExcludeList(windowName)
|
||||
for _, excludedName in ipairs(UIManager.ExcludeFromStack) do
|
||||
if windowName == excludedName then
|
||||
return
|
||||
end
|
||||
end
|
||||
table.insert(UIManager.ExcludeFromStack, windowName)
|
||||
end
|
||||
|
||||
-- 从排除列表中移除窗口
|
||||
function UIManager:RemoveFromExcludeList(windowName)
|
||||
for i, excludedName in ipairs(UIManager.ExcludeFromStack) do
|
||||
if windowName == excludedName then
|
||||
table.remove(UIManager.ExcludeFromStack, i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 获取排除列表
|
||||
function UIManager:GetExcludeList()
|
||||
return UIManager.ExcludeFromStack
|
||||
end
|
||||
|
||||
return UIManager
|
@ -44,6 +44,7 @@ function CreateWindow:Init(UIManager: table, Data: table?)
|
||||
["_tmpQuality"] = 0,
|
||||
["_toggleAutoRecycle"] = 0,
|
||||
["_imgAutoRecycleActive"] = 0,
|
||||
["__moneyCoin"] = 0,
|
||||
}
|
||||
self.MultNumber = 1
|
||||
self.AutoRecycle = false
|
||||
@ -107,7 +108,7 @@ function CreateWindow:OnOpenWindow()
|
||||
Quality = child:GetAttribute("quality"),
|
||||
Timestamp = child:GetAttribute("timestamp"),
|
||||
}
|
||||
self.Variables["__listWeaponPackage"]:AddData(self.Data[child.Name])
|
||||
self.Variables["__listWeaponPackage"]:AddData(child.Name, self.Data[child.Name])
|
||||
end)
|
||||
table.insert(self.Connections, childAddCon)
|
||||
|
||||
@ -140,10 +141,12 @@ function CreateWindow:OnOpenWindow()
|
||||
|
||||
if self.Data then
|
||||
local minInstance = self.Variables["__listWeaponPackage"]:GetMinLayoutOrderInstance()
|
||||
self:ShowDetailInfo(minInstance.Data)
|
||||
if minInstance then
|
||||
self:ShowDetailInfo(minInstance.Data)
|
||||
|
||||
self.LastActiveItem = minInstance
|
||||
minInstance:SetSelected(true)
|
||||
self.LastActiveItem = minInstance
|
||||
minInstance:SetSelected(true)
|
||||
end
|
||||
else
|
||||
self:ShowDetailInfo()
|
||||
end
|
||||
|
@ -0,0 +1,43 @@
|
||||
local AttributeShow = {}
|
||||
AttributeShow.__index = AttributeShow
|
||||
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
local Localization = require(ReplicatedStorage.Tools.Localization)
|
||||
local JsonEquipment = require(ReplicatedStorage.Json.Equipment)
|
||||
local JsonItemProp = require(ReplicatedStorage.Json.ItemProp)
|
||||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||||
|
||||
function AttributeShow:Init(data: table)
|
||||
local self = {}
|
||||
self.Data = data
|
||||
self.Variables = {
|
||||
["_tmpAttributeName"] = 0,
|
||||
["_tmpValue"] = 0,
|
||||
}
|
||||
|
||||
setmetatable(self, AttributeShow)
|
||||
return self
|
||||
end
|
||||
|
||||
function AttributeShow:Refresh()
|
||||
local attributeData = Utils:GetSpecialKeyDataFromJson(JsonAttributes, "effectAttribute", self.Data.attribute)
|
||||
self.Variables._tmpAttributeName.Text = self.Data.attribute
|
||||
self.UIRoot.LayoutOrder = 1000 - attributeData.id
|
||||
|
||||
if attributeData.type == 2 then
|
||||
self.Variables._tmpValue.Text = string.format("%.2f%%", self.Data.value / 100)
|
||||
else
|
||||
self.Variables._tmpValue.Text = self.Data.value
|
||||
end
|
||||
end
|
||||
|
||||
function AttributeShow:Destroy()
|
||||
for k, v in pairs(self) do
|
||||
self[k] = nil
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
return AttributeShow
|
@ -0,0 +1,77 @@
|
||||
local EquipmentShow = {}
|
||||
EquipmentShow.__index = EquipmentShow
|
||||
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
local Localization = require(ReplicatedStorage.Tools.Localization)
|
||||
local JsonEquipment = require(ReplicatedStorage.Json.Equipment)
|
||||
local JsonItemProp = require(ReplicatedStorage.Json.ItemProp)
|
||||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||||
|
||||
local FolderEquipment = ReplicatedStorage:WaitForChild("Prefabs"):WaitForChild("Equipments")
|
||||
|
||||
function EquipmentShow:Init(data: table)
|
||||
local self = {}
|
||||
self.Data = data
|
||||
self.Variables = {
|
||||
["_imgView"] = 0,
|
||||
["_btnSelect"] = 0,
|
||||
}
|
||||
self.Connections = {}
|
||||
|
||||
setmetatable(self, EquipmentShow)
|
||||
return self
|
||||
end
|
||||
|
||||
function EquipmentShow:Refresh()
|
||||
local equipmentData = Utils:GetIdDataFromJson(JsonEquipment, self.Data["orgId"])
|
||||
|
||||
-- 模型
|
||||
local part = FolderEquipment:FindFirstChild(equipmentData.modelName):Clone()
|
||||
part.Handle.Position = Vector3.new(0, 0, 0)
|
||||
part.Handle.CFrame = CFrame.new(0, 0, 0) * CFrame.Angles(math.rad(90), 0, 0)
|
||||
part.Parent = self.Variables["_imgView"]
|
||||
self.Prefab = part
|
||||
|
||||
-- 相机
|
||||
local viewportCamera = Instance.new("Camera")
|
||||
self.Variables["_imgView"].CurrentCamera = viewportCamera
|
||||
viewportCamera.Parent = self.Variables["_imgView"]
|
||||
viewportCamera.CFrame = CFrame.new(Vector3.new(0, 0, 6), part.Handle.Position)
|
||||
self.ViewCamera = viewportCamera
|
||||
|
||||
-- 旋转
|
||||
self.taskRotation = task.spawn(function()
|
||||
while true do
|
||||
self.Prefab.Handle.CFrame = self.Prefab.Handle.CFrame * CFrame.Angles(0, 0, 0.01)
|
||||
task.wait(0.01)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function EquipmentShow:OnInitFinish()
|
||||
-- 点击事件
|
||||
local con = self.Variables["_btnSelect"].Activated:Connect(function()
|
||||
self.TopUI:ReShowDetail(self.Data)
|
||||
end)
|
||||
table.insert(self.Connections, con)
|
||||
end
|
||||
|
||||
function EquipmentShow:Destroy()
|
||||
if self.Connections then
|
||||
for k, v in pairs(self.Connections) do
|
||||
v:Disconnect()
|
||||
end
|
||||
end
|
||||
if self.taskRotation then
|
||||
task.cancel(self.taskRotation)
|
||||
self.taskRotation = nil
|
||||
end
|
||||
for k, v in pairs(self) do
|
||||
self[k] = nil
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
return EquipmentShow
|
@ -0,0 +1,252 @@
|
||||
--> Services
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
--> Dependencies
|
||||
local UIWindow = require(ReplicatedStorage.Base.UIWindow)
|
||||
local UIEnums = require(ReplicatedStorage.Base.UIEnums)
|
||||
|
||||
--> Json
|
||||
local JsonItemProp = require(ReplicatedStorage.Json.ItemProp)
|
||||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||||
|
||||
--> Modules
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
local Localization = require(ReplicatedStorage.Tools.Localization)
|
||||
local AttributeShow = require(script.AttributeShow)
|
||||
local EquipmentShow = require(script.EquipmentShow)
|
||||
|
||||
local LocalPlayer = game:GetService("Players").LocalPlayer
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function centerSpecificListItem(scrollingFrame, targetItem)
|
||||
-- 检查参数是否有效
|
||||
if not scrollingFrame or not targetItem then
|
||||
warn("centerSpecificListItem: 参数无效")
|
||||
return
|
||||
end
|
||||
|
||||
-- 等待UI完全加载
|
||||
task.wait()
|
||||
|
||||
local canvasSize = scrollingFrame.CanvasSize
|
||||
local absoluteSize = scrollingFrame.AbsoluteSize
|
||||
|
||||
-- 检查尺寸是否有效
|
||||
if not canvasSize or not absoluteSize then
|
||||
warn("centerSpecificListItem: 尺寸无效", scrollingFrame.Name)
|
||||
return
|
||||
end
|
||||
|
||||
-- 获取目标项的位置和尺寸
|
||||
local itemPosition = targetItem.Position
|
||||
local itemSize = targetItem.AbsoluteSize
|
||||
|
||||
-- 检查位置和尺寸是否有效
|
||||
if not itemPosition or not itemSize then
|
||||
warn("centerSpecificListItem: 目标项位置或尺寸无效", targetItem.Name)
|
||||
return
|
||||
end
|
||||
|
||||
-- 计算目标项在ScrollingFrame中的绝对位置
|
||||
local itemAbsolutePosition = targetItem.AbsolutePosition
|
||||
|
||||
-- 计算目标项的中心位置(相对于ScrollingFrame)
|
||||
local itemCenterX = itemAbsolutePosition.X + (itemSize.X / 2)
|
||||
|
||||
-- 计算容器中心位置
|
||||
local containerCenterX = absoluteSize.X / 2
|
||||
|
||||
-- 计算目标项在ScrollingFrame内容中的位置
|
||||
local currentCanvasPosition = scrollingFrame.CanvasPosition
|
||||
|
||||
-- 计算需要的偏移量,使目标项居中
|
||||
-- 目标项中心位置 - 容器中心位置 = 需要的偏移量
|
||||
local offsetX = itemCenterX - containerCenterX
|
||||
|
||||
-- 计算新的CanvasPosition(当前位置 + 需要的偏移量)
|
||||
local newCanvasPositionX = currentCanvasPosition.X + offsetX
|
||||
|
||||
-- 确保不超出边界
|
||||
-- CanvasSize是UDim2,需要计算实际的像素宽度
|
||||
local contentWidth = canvasSize.X.Offset + (canvasSize.X.Scale * absoluteSize.X)
|
||||
local maxOffset = contentWidth - absoluteSize.X
|
||||
|
||||
newCanvasPositionX = math.clamp(newCanvasPositionX, 0, math.max(0, maxOffset))
|
||||
|
||||
-- 设置canvasPosition
|
||||
scrollingFrame.CanvasPosition = Vector2.new(newCanvasPositionX, 0)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local GetEquipmentsWindow = {}
|
||||
GetEquipmentsWindow.__index = GetEquipmentsWindow
|
||||
setmetatable(GetEquipmentsWindow, {__index = UIWindow})
|
||||
|
||||
function GetEquipmentsWindow:Init(UIManager: table, Data: table?)
|
||||
local self = UIWindow:Init(UIManager, Data)
|
||||
setmetatable(self, GetEquipmentsWindow)
|
||||
self.Variables = {
|
||||
["_goRewardsPanel"] = 0,
|
||||
["_goDetailPanel"] = 0,
|
||||
|
||||
["_goBase"] = 0,
|
||||
["_goExAttributesPanel"] = 0,
|
||||
["_goElementPanel"] = 0,
|
||||
["_goElementDefPanel"] = 0,
|
||||
|
||||
["__listBaseAttributes"] = 0,
|
||||
["__listExAttributes"] = 0,
|
||||
["__listElement"] = 0,
|
||||
["__listElementDef"] = 0,
|
||||
|
||||
["_tmpName"] = 0,
|
||||
["_tmpQuality"] = 0,
|
||||
|
||||
["__listEquipments"] = 0,
|
||||
["_btnLeft"] = 0,
|
||||
["_btnRight"] = 0,
|
||||
|
||||
["_btnClose"] = 0,
|
||||
}
|
||||
self.UIRootName = "ui_w_get_equipments"
|
||||
self.UIParentName = UIEnums.UIParent.UIRoot
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function GetEquipmentsWindow:TransformKeyTable(data: table)
|
||||
local newData = {}
|
||||
local index = 1
|
||||
for k, v in pairs(data) do
|
||||
newData[index] = {}
|
||||
newData[index]["attribute"] = k
|
||||
newData[index]["value"] = v
|
||||
index = index + 1
|
||||
end
|
||||
return newData
|
||||
end
|
||||
|
||||
function GetEquipmentsWindow:ShowDetail(equipmentInstance: Instance)
|
||||
local equipmentData = Utils:GetIdDataFromJson(JsonItemProp, equipmentInstance:GetAttribute("orgId"))
|
||||
self.Variables["_tmpName"].Text = Localization:GetLanguageData(equipmentData.textId)
|
||||
self.Variables["_tmpQuality"].Text = equipmentInstance:GetAttribute("quality")
|
||||
|
||||
local baseAttributes = equipmentInstance:FindFirstChild("attributes"):GetAttributes()
|
||||
local exAttributes = equipmentInstance:FindFirstChild("exAttributes"):GetAttributes()
|
||||
local elements = equipmentInstance:FindFirstChild("elements"):GetAttributes()
|
||||
local elementDef = equipmentInstance:FindFirstChild("elementDef"):GetAttributes()
|
||||
|
||||
self.Variables["__listBaseAttributes"]:SetData(self:TransformKeyTable(baseAttributes))
|
||||
self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(exAttributes))
|
||||
self.Variables["__listElement"]:SetData(self:TransformKeyTable(elements))
|
||||
self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef))
|
||||
|
||||
-- 额外属性
|
||||
if #exAttributes > 0 then
|
||||
self.Variables["_goExAttributesPanel"].Visible = true
|
||||
self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(exAttributes))
|
||||
else
|
||||
self.Variables["_goExAttributesPanel"].Visible = false
|
||||
end
|
||||
|
||||
-- 元素属性
|
||||
if #elements > 0 then
|
||||
self.Variables["_goElementPanel"].Visible = true
|
||||
self.Variables["__listElement"]:SetData(self:TransformKeyTable(elements))
|
||||
else
|
||||
self.Variables["_goElementPanel"].Visible = false
|
||||
end
|
||||
|
||||
-- 元素定义属性
|
||||
if #elementDef > 0 then
|
||||
self.Variables["_goElementDefPanel"].Visible = true
|
||||
self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef))
|
||||
else
|
||||
self.Variables["_goElementDefPanel"].Visible = false
|
||||
end
|
||||
end
|
||||
|
||||
function GetEquipmentsWindow:SetCenter(listName, equipmentData)
|
||||
-- 等待一帧确保UI已加载,然后设置居中
|
||||
task.spawn(function()
|
||||
task.wait() -- 等待一帧
|
||||
local targetInstance = self.Variables[listName]:FindSameDataInstance(equipmentData)
|
||||
if targetInstance and targetInstance.UIRoot then
|
||||
-- 查找ScrollingFrame
|
||||
local scrollingFrame = self.Variables[listName].UIRoot
|
||||
if scrollingFrame:IsA("ScrollingFrame") then
|
||||
centerSpecificListItem(scrollingFrame, targetInstance.UIRoot)
|
||||
else
|
||||
-- 如果不是ScrollingFrame,查找子级中的ScrollingFrame
|
||||
local scroller = scrollingFrame:FindFirstChildWhichIsA("ScrollingFrame")
|
||||
if scroller then
|
||||
centerSpecificListItem(scroller, targetInstance.UIRoot)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function GetEquipmentsWindow:ReShowDetail(equipmentData)
|
||||
local equipmentInstance
|
||||
for _, instance in self.Data do
|
||||
if instance.Name == tostring(equipmentData.id) then
|
||||
equipmentInstance = instance
|
||||
break
|
||||
end
|
||||
end
|
||||
self:ShowDetail(equipmentInstance)
|
||||
self:SetCenter("__listEquipments", equipmentData)
|
||||
end
|
||||
|
||||
function GetEquipmentsWindow:OnOpenWindow()
|
||||
UIWindow.OnOpenWindow(self)
|
||||
|
||||
local equipmentsData = {}
|
||||
local maxQuality = 0
|
||||
local showDetailData = nil
|
||||
|
||||
for _, equipmentInstance in self.Data do
|
||||
local attributes = equipmentInstance:GetAttributes()
|
||||
equipmentsData[equipmentInstance.Name] = attributes
|
||||
|
||||
-- 同时找到最高品质的装备
|
||||
if attributes.quality and attributes.quality > maxQuality then
|
||||
maxQuality = attributes.quality
|
||||
showDetailData = attributes
|
||||
end
|
||||
end
|
||||
|
||||
self.Variables["__listEquipments"]:AddComponent(EquipmentShow)
|
||||
self.Variables["__listEquipments"]:SetData(equipmentsData)
|
||||
self.Variables["__listEquipments"]:SetLayoutOrder("quality", true)
|
||||
|
||||
if not showDetailData then warn("ShowDetail Is Null") return end
|
||||
|
||||
self:SetCenter("__listEquipments", showDetailData)
|
||||
|
||||
-- 基础属性
|
||||
self.Variables["__listBaseAttributes"]:AddComponent(AttributeShow)
|
||||
self.Variables["__listExAttributes"]:AddComponent(AttributeShow)
|
||||
self.Variables["__listElement"]:AddComponent(AttributeShow)
|
||||
self.Variables["__listElementDef"]:AddComponent(AttributeShow)
|
||||
|
||||
-- 找到对应的原始equipmentInstance来显示详情
|
||||
for _, equipmentInstance in self.Data do
|
||||
if equipmentInstance:GetAttribute("quality") == showDetailData.quality then
|
||||
self:ShowDetail(equipmentInstance)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local closeCon = self.Variables["_btnClose"].Activated:Connect(function()
|
||||
self.UIManager:CloseWindow(script.Name)
|
||||
end)
|
||||
table.insert(self.Connections, closeCon)
|
||||
end
|
||||
|
||||
|
||||
|
||||
return GetEquipmentsWindow
|
@ -5,6 +5,13 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
local UIWindow = require(ReplicatedStorage.Base.UIWindow)
|
||||
local UIEnums = require(ReplicatedStorage.Base.UIEnums)
|
||||
|
||||
--> Json
|
||||
local JsonLevel = require(ReplicatedStorage.Json.Level)
|
||||
|
||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||
|
||||
local LocalPlayer = game:GetService("Players").LocalPlayer
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local MainWindow = {}
|
||||
@ -18,6 +25,9 @@ function MainWindow:Init(UIManager: table, Data: table?)
|
||||
["_btnMainCreate"] = 0,
|
||||
["_btnMainCha"] = 0,
|
||||
["_btnMainAttributeUpgrade"] = 0,
|
||||
|
||||
["_tmpNowLevel"] = 0,
|
||||
["_imgBoss"] = 0,
|
||||
}
|
||||
self.UIRootName = "ui_w_main"
|
||||
self.UIParentName = UIEnums.UIParent.UIRoot
|
||||
@ -25,6 +35,16 @@ function MainWindow:Init(UIManager: table, Data: table?)
|
||||
return self
|
||||
end
|
||||
|
||||
function MainWindow:SetShowLevel(level: number)
|
||||
self.Variables["_tmpNowLevel"].Text = string.format("第%d关", level)
|
||||
local levelData = Utils:GetIdDataFromJson(JsonLevel, level)
|
||||
if levelData.type == 2 then
|
||||
self.Variables["_imgBoss"].Visible = true
|
||||
else
|
||||
self.Variables["_imgBoss"].Visible = false
|
||||
end
|
||||
end
|
||||
|
||||
function MainWindow:OnOpenWindow()
|
||||
UIWindow.OnOpenWindow(self)
|
||||
|
||||
@ -41,6 +61,16 @@ function MainWindow:OnOpenWindow()
|
||||
table.insert(self.Connections, createCon)
|
||||
table.insert(self.Connections, chaCon)
|
||||
table.insert(self.Connections, attributeUpgradeCon)
|
||||
|
||||
local playerDataFolder = Utils:WaitPlayerDataFolder(LocalPlayer)
|
||||
local StatsFolder = playerDataFolder:WaitForChild("PlayerInfo"):WaitForChild("Stats")
|
||||
local levelCon = StatsFolder.level.Changed:Connect(function(newValue)
|
||||
self:SetShowLevel(newValue)
|
||||
end)
|
||||
|
||||
-- 初始值设置
|
||||
self:SetShowLevel(StatsFolder.level.Value)
|
||||
table.insert(self.Connections, levelCon)
|
||||
end
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user