diff --git a/excel/Rune.xlsx b/excel/Rune.xlsx new file mode 100644 index 0000000..d48bb19 Binary files /dev/null and b/excel/Rune.xlsx differ diff --git a/excel/attribute.xlsx b/excel/attribute.xlsx index 47de1e7..16f4933 100644 Binary files a/excel/attribute.xlsx and b/excel/attribute.xlsx differ diff --git a/excel/cha.xlsx b/excel/cha.xlsx index c6b70c7..2419450 100644 Binary files a/excel/cha.xlsx and b/excel/cha.xlsx differ diff --git a/excel/equipment.xlsx b/excel/equipment.xlsx index 229668c..e1ec9c3 100644 Binary files a/excel/equipment.xlsx and b/excel/equipment.xlsx differ diff --git a/excel/item.xlsx b/excel/item.xlsx index 9765d39..28081fa 100644 Binary files a/excel/item.xlsx and b/excel/item.xlsx differ diff --git a/excel/language.xlsx b/excel/language.xlsx index 1ef273c..f2a2d9c 100644 Binary files a/excel/language.xlsx and b/excel/language.xlsx differ diff --git a/src/ReplicatedStorage/Json/ItemProp.json b/src/ReplicatedStorage/Json/ItemProp.json index c36a664..c5bd145 100644 --- a/src/ReplicatedStorage/Json/ItemProp.json +++ b/src/ReplicatedStorage/Json/ItemProp.json @@ -95,5 +95,6 @@ {"id":50012,"type":3,"typeArgs":[],"quality":13,"iconId":13,"nameId":50012,"textId":70012,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null}, {"id":50013,"type":3,"typeArgs":[],"quality":14,"iconId":14,"nameId":50013,"textId":70013,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null}, {"id":50014,"type":3,"typeArgs":[],"quality":15,"iconId":15,"nameId":50014,"textId":70014,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null}, -{"id":50015,"type":3,"typeArgs":[],"quality":16,"iconId":16,"nameId":50015,"textId":70015,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null} +{"id":50015,"type":3,"typeArgs":[],"quality":16,"iconId":16,"nameId":50015,"textId":70015,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null}, +{"id":60000,"type":7,"typeArgs":[],"quality":1,"iconId":60000,"nameId":60000,"textId":80000,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null} ] \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Language_En_US.json b/src/ReplicatedStorage/Json/Language_En_US.json index ac1eb76..7d76d47 100644 --- a/src/ReplicatedStorage/Json/Language_En_US.json +++ b/src/ReplicatedStorage/Json/Language_En_US.json @@ -41,6 +41,10 @@ {"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"}, {"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"}, {"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"}, +{"id":1010,"text":"尚未祝福"}, +{"id":1011,"text":"祝福:出现{0}属性的概率+{1}"}, +{"id":1012,"text":"祝福:出现{0}技能的概率+{1}"}, +{"id":1013,"text":"祝福:出现{0}晶石的概率+{1}"}, {"id":20000,"text":"普攻"}, {"id":20001,"text":"剑气"}, {"id":40000,"text":"测试装备1"}, diff --git a/src/ReplicatedStorage/Json/Language_Zh_CN.json b/src/ReplicatedStorage/Json/Language_Zh_CN.json index ac1eb76..7d76d47 100644 --- a/src/ReplicatedStorage/Json/Language_Zh_CN.json +++ b/src/ReplicatedStorage/Json/Language_Zh_CN.json @@ -41,6 +41,10 @@ {"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"}, {"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"}, {"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"}, +{"id":1010,"text":"尚未祝福"}, +{"id":1011,"text":"祝福:出现{0}属性的概率+{1}"}, +{"id":1012,"text":"祝福:出现{0}技能的概率+{1}"}, +{"id":1013,"text":"祝福:出现{0}晶石的概率+{1}"}, {"id":20000,"text":"普攻"}, {"id":20001,"text":"剑气"}, {"id":40000,"text":"测试装备1"}, diff --git a/src/ReplicatedStorage/Json/Rune.json b/src/ReplicatedStorage/Json/Rune.json new file mode 100644 index 0000000..2da4fae --- /dev/null +++ b/src/ReplicatedStorage/Json/Rune.json @@ -0,0 +1,3 @@ +[ +{"id":60000,"type":1,"icon":1,"nameId":20000,"behaviourName":"Attack","recycle":[]} +] \ No newline at end of file diff --git a/src/ReplicatedStorage/Tools/Utils.luau b/src/ReplicatedStorage/Tools/Utils.luau index 86a3d47..4ed273f 100644 --- a/src/ReplicatedStorage/Tools/Utils.luau +++ b/src/ReplicatedStorage/Tools/Utils.luau @@ -114,7 +114,7 @@ function Utils:GetRandomIdFromJsonWithType(JsonData: table, Type: number, Except while ExceptIdList and table.find(ExceptIdList, randomId) do randomId = rng:NextInteger(1, #result) end - return randomId + return result[randomId] end -- 获取随机id,ExceptIdList为可选参数,如果传入则排除ExceptIdList中的id diff --git a/src/ServerStorage/Proxy/BookProxy.luau b/src/ServerStorage/Proxy/BookProxy.luau index c9278e7..615c0f0 100644 --- a/src/ServerStorage/Proxy/BookProxy.luau +++ b/src/ServerStorage/Proxy/BookProxy.luau @@ -19,7 +19,7 @@ local JsonEquipment = require(ReplicatedStorage.Json.Equipment) --> Events local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip -local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes +local RE_Blessing = ReplicatedStorage.Events.RE_Blessing --> Constants local STORE_NAME = "Book" @@ -141,14 +141,20 @@ function BookProxy:BlessingBook(Player: Player, BookId: number, BlessingType: nu local BlessingCostItemId = 20 + BlessingType - 1 local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy) local hasEnoughItem = PlayerInfoProxy:HasEnoughItem(Player, BlessingCostItemId, BlessingCount) - if not hasEnoughItem then warn("没有足够货币, 无法祝福") return end + if not hasEnoughItem then + RE_PlayerTip:FireClient(Player, "没有足够货币, 无法祝福") + return + end -- 消耗祝福道具 PlayerInfoProxy:ChangeItemCount(Player, BlessingCostItemId, -BlessingCount) -- 获取祝福 local EquipmentData = Utils:GetIdDataFromJson(JsonEquipment, BookId) - if not EquipmentData then warn("获取装备数据失败") return end + if not EquipmentData then + RE_PlayerTip:FireClient(Player, "获取装备数据失败") + return + end -- 如果类型相同,则直接定向 local isNotDefine = true @@ -164,14 +170,23 @@ function BookProxy:BlessingBook(Player: Player, BookId: number, BlessingType: nu -- 没有定向的话, 就随机 if isNotDefine then -- 随机 - BlessingData = Utils:GetRandomIdFromJsonWithType(JsonBlessing, BlessingType) - if not BlessingData then warn("获取祝福数据失败, 请检查配置表内容", BlessingType) return end + BlessingData = Utils:GetIdDataFromJson(JsonBlessing, Utils:GetRandomIdFromJsonWithType(JsonBlessing, BlessingType)) + if not BlessingData then + RE_PlayerTip:FireClient(Player, "获取祝福数据失败, 请检查配置表内容", BlessingType) + return + end end -- 设置祝福属性 ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingId = BlessingData.id ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingRate = Rng:GetRandomInt(BlessingData.minRate, BlessingData.maxRate) + -- 修改实例的信息 + + local bookInstance = GetPlayerBookFolder(Player):FindFirstChild(BookId) + bookInstance:SetAttribute("blessingId", ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingId) + bookInstance:SetAttribute("blessingRate", ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].blessingRate) + -- 设置祝福成功,向前端发送信息 end @@ -201,4 +216,8 @@ ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(Player: Player) BookProxy:OnPlayerRemoving(Player) end) +RE_Blessing.OnServerEvent:Connect(function(Player: Player, BookId: number, BlessingType: number, BlessingCount: number) + BookProxy:BlessingBook(Player, BookId, BlessingType, BlessingCount) +end) + return BookProxy \ No newline at end of file diff --git a/src/ServerStorage/Proxy/EquipmentProxy.luau b/src/ServerStorage/Proxy/EquipmentProxy.luau index 6083ab1..d30bc81 100644 --- a/src/ServerStorage/Proxy/EquipmentProxy.luau +++ b/src/ServerStorage/Proxy/EquipmentProxy.luau @@ -294,6 +294,25 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number) end end + -- 随机生成符文数量 + local RuneProxy = require(ServerStorage.Proxy.RuneProxy) + local maxRuneNumber = PlayerInfoProxy:GetPlayerInfo(Player).runeNumber or 0 + local runeNumber = rng:NextInteger(0, maxRuneNumber) + ResultData.maxRuneNumber = runeNumber + if runeNumber > 0 then + local spawnRunesId = {} + for i = 1, runeNumber do + -- 是否生成符文 + local isTrigger = Rng:GetRandomInt(1, 100) <= 5 + if isTrigger then + local newRuneId = RuneProxy:GetRandomRuneId(spawnRunesId) + table.insert(spawnRunesId, newRuneId) + local newRuneData, newRuneInstance = RuneProxy:AddRune(Player, newRuneId) + RuneProxy:WearRune(Player, newRuneData.id, UniqueId) + end + end + end + ------------------------------------------------------------ -- 添加图鉴记录 diff --git a/src/ServerStorage/Proxy/RuneProxy.luau b/src/ServerStorage/Proxy/RuneProxy.luau new file mode 100644 index 0000000..3d4096e --- /dev/null +++ b/src/ServerStorage/Proxy/RuneProxy.luau @@ -0,0 +1,279 @@ +-- 技能系统(存储用) +local RuneProxy = {} + +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Variables +local Utils = require(ReplicatedStorage.Tools.Utils) +local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy) +local Rng = require(ReplicatedStorage.Tools.Rng) + +--> Json +local JsonRune = require(ReplicatedStorage.Json.Rune) + +--> Events +local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip + +--> Constants +local STORE_NAME = "Rune" + +-------------------------------------------------------------------------------- + +-- 获取玩家信息文件夹 +local function GetPlayerRuneFolder(Player: Player) + local pData = Utils:GetPlayerDataFolder(Player) + if not pData then return end + local RuneFolder = pData:FindFirstChild("Rune") + return RuneFolder +end + +-------------------------------------------------------------------------------- + +-- 初始化玩家 +function RuneProxy:InitPlayer(Player: Player) + local pData = Utils:WaitPlayerDataFolder(Player) + if not pData then return end + local RuneFolder = Utils:CreateFolder("Rune", pData) + + -- 新玩家数据初始化 + if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then + ArchiveProxy.pData[Player.UserId][STORE_NAME] = {} + end + + -- 创建玩家信息实例 + for RuneUniqueId, RuneData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do + Utils:CreateDataInstance(Player, RuneUniqueId, RuneData, RuneFolder) + end +end + +-------------------------------------------------------------------------------- + +-- 添加技能 +local EXCEPT_KEYS = {"id"} +function RuneProxy:AddRune(Player: Player, RuneId: number) + local pData = Utils:GetPlayerDataFolder(Player) + if not pData then return end + + local RuneData = Utils:GetIdDataFromJson(JsonRune, RuneId) + if not RuneData then return end + + local UniqueId = Utils:GenUniqueId(ArchiveProxy.pData[Player.UserId][STORE_NAME]) + -- 配置表内容 + local ResultData = {} + for key, value in pairs(RuneData) do + if not table.find(EXCEPT_KEYS, key) then + ResultData[key] = value + end + end + + ResultData.id = UniqueId + ResultData.orgId = RuneId + -- 记录穿戴的装备UniqueId + ResultData.wearing = 0 + ResultData.wearingSlot = 0 + + ArchiveProxy.pData[Player.UserId][STORE_NAME][UniqueId] = ResultData + local RuneInstance = Utils:CreateDataInstance(Player, UniqueId, ResultData, GetPlayerRuneFolder(Player)) + return Utils:DeepCopyTable(ResultData), RuneInstance +end + +-- 合成符文 +function RuneProxy:CombineRune(Player: Player, RuneData: table) + local pData = Utils:GetPlayerDataFolder(Player) + if not pData then return end + + if #RuneData ~= 3 then warn('符文合成数量不正确', Player.Name, RuneData) return end + + -- 获取合成符文数据 + local sameQuality = true + for _, rune in RuneData do + if rune.quality >= 3 then warn('符文品质已达到上限', Player.Name, RuneData) return end + if rune.quality ~= RuneData[1].quality then + sameQuality = false + break + end + end + + if not sameQuality then warn('符文品质不相同', Player.Name, RuneData) return end + + -- 获取合成符文品质 + local higherQuality = RuneData[1].quality + 1 + + -- 添加合成符文 + local newRuneId = self:GetRandomRuneIdByQuality(higherQuality) + if not newRuneId then warn('合成符文不存在', Player.Name, RuneData) return end + self:AddRune(Player, newRuneId) + + -- 销毁符文 + for _, rune in RuneData do self:DestroyRune(Player, rune.id) end +end + +-- 销毁符文 +function RuneProxy:DestroyRune(Player: Player, UniqueId: number) + local pData = Utils:GetPlayerDataFolder(Player) + if not pData then return end + + -- 获取符文实例存储数据 + local UniqueData = ArchiveProxy.pData[Player.UserId][UniqueId] + if not UniqueData then return end + + -- 检查是否有符文实例 + local RuneInstance = GetPlayerRuneFolder(Player):FindFirstChild(UniqueId) + if not RuneInstance then warn('符文实例不存在: ' , Player.Name, UniqueId) return end + + -- 销毁 + RuneInstance:Destroy() + ArchiveProxy.pData[Player.UserId][UniqueId] = nil +end + +-- 穿戴符文 +function RuneProxy:WearRune(Player: Player, RuneUniqueId: number, EquipmentUniqueId: number) + local pData = Utils:GetPlayerDataFolder(Player) + if not pData then print("pData不存在", Player.Name) return end + + -- 获取技能实例存储数据 + local UniqueData = ArchiveProxy.pData[Player.UserId][STORE_NAME][RuneUniqueId] + if not UniqueData then print("UniqueData不存在", Player.Name, RuneUniqueId) return end + + -- 检查是否有技能实例 + local RuneInstance = GetPlayerRuneFolder(Player):FindFirstChild(RuneUniqueId) + if not RuneInstance then warn('符文实例不存在: ' , Player.Name, RuneUniqueId) return end + + -- 获取装备数据 + local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy) + local EquipmentData = EquipmentProxy:GetEquipmentData(Player, EquipmentUniqueId) + + -- 遍历符文查看现在穿了几个 + local wearingCount = 0 + local wearingSlot = {} + for _, RuneData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do + if RuneData.wearing == EquipmentUniqueId then + wearingCount = wearingCount + 1 + table.insert(wearingSlot, RuneData.wearingSlot) + end + end + + -- 检查装备是否有符文槽位 + if EquipmentData.maxRuneNumber <= 0 then + RE_PlayerTip:FireClient(Player, "装备没有符文槽位") + return + end + + -- 检查槽位数量是否充足 + if wearingCount >= EquipmentData.maxRuneNumber then + RE_PlayerTip:FireClient(Player, "装备已满符文槽位") + return + end + + + -- 查找到空槽位 + local emptySlot = {} + for i = 1, EquipmentData.maxRuneNumber do + if not table.find(wearingSlot, i) then + table.insert(emptySlot, i) + end + end + + -- 随机镶嵌槽位 + UniqueData.wearingSlot = emptySlot[Rng:GetRandomInt(1, #emptySlot)] + UniqueData.wearing = EquipmentUniqueId + RuneInstance:SetAttribute("wearing", EquipmentUniqueId) + RuneInstance:SetAttribute("wearingSlot", UniqueData.wearingSlot) +end + +-- 获取随机指定品质符文 +function RuneProxy:GetRandomRuneIdByQuality(Quality: number, ExceptIdList: table) + ExceptIdList = ExceptIdList or {} + local candidateIds = {} + for _, rune in ipairs(JsonRune) do + if not table.find(ExceptIdList, rune.id) and rune.quality == Quality and rune.isInPool then + table.insert(candidateIds, rune.id) + end + end + + if #candidateIds == 0 then + return nil -- 没有可用技能 + end + local rng = Random.new() + local idx = rng:NextInteger(1, #candidateIds) + return candidateIds[idx] +end + + +-- 获取随机技能id +function RuneProxy:GetRandomRuneId(ExceptIdList: table) + ExceptIdList = ExceptIdList or {} + local candidateIds = {} + + -- TODO:这里之后还得做生成品质概率筛选,暂时只产出1级符文 + for _, rune in ipairs(JsonRune) do + local id = rune.id + if not table.find(ExceptIdList, id) and rune.isInPool and rune.quality == 1 then + table.insert(candidateIds, id) + end + end + if #candidateIds == 0 then + return nil -- 没有可用技能 + end + local rng = Random.new() + local idx = rng:NextInteger(1, #candidateIds) + return candidateIds[idx] +end + +-- 获取穿戴中的符文 +function RuneProxy:GetPlayerWearingRuneData(Player: Player) + local wearingRuneUniqueId = {} + local behaviourNames = {} + -- 穿戴中的填入 + local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy) + local wearingEquipments = EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player) + for _, RuneData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do + if RuneData.wearing > 0 and table.find(wearingEquipments, RuneData.wearing) then + table.insert(wearingRuneUniqueId, RuneData.id) + local RuneData = Utils:GetIdDataFromJson(JsonRune, RuneData.orgId) + table.insert(behaviourNames, RuneData.behaviourName) + end + end + return wearingRuneUniqueId, behaviourNames +end + +-- 获取对应装备槽位上的技能 +function RuneProxy:GetPlayerRuneByEquipmentUniqueId(Player: Player, EquipmentUniqueId: number) + local wearingUniqueId, wearingOrgId = {}, {} + local runeFolder = GetPlayerRuneFolder(Player) + for _, RuneInstance in runeFolder:GetChildren() do + if RuneInstance:GetAttribute("wearing") == EquipmentUniqueId then + table.insert(wearingUniqueId, RuneInstance:GetAttribute("uniqueId")) + table.insert(wearingOrgId, RuneInstance:GetAttribute("orgId")) + end + end + return wearingUniqueId, wearingOrgId +end + +-------------------------------------------------------------------------------- + +-- 获取技能属性 +function RuneProxy:GetPlayerRuneWearingAttributes(Player: Player) + -- TODO:暂时没有,之后如果技能附带属性值时再加 +end + +-- 获取玩家属性 +function RuneProxy:GetPlayerAttributes(Player: Player) + local attributesList = {} + attributesList.RuneWearingAttributes = self:GetPlayerRuneWearingAttributes(Player) + return attributesList +end + +-------------------------------------------------------------------------------- + +function RuneProxy:OnPlayerRemoving(Player: Player) + +end + +ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(Player: Player) + RuneProxy:OnPlayerRemoving(Player) +end) + +return RuneProxy \ No newline at end of file diff --git a/src/StarterPlayerScripts/ClientMain/Helper.luau b/src/StarterPlayerScripts/ClientMain/Helper.luau index d76e0fc..a4b0056 100644 --- a/src/StarterPlayerScripts/ClientMain/Helper.luau +++ b/src/StarterPlayerScripts/ClientMain/Helper.luau @@ -16,6 +16,9 @@ UserInputService.InputBegan:Connect(function(input, gameProcessed) RE_PlayerHelper:FireServer("CleanPlayerData") elseif input.KeyCode == Enum.KeyCode.J then RE_PlayerHelper:FireServer("AddItem", {1, 1000}) + RE_PlayerHelper:FireServer("AddItem", {20, 10}) + RE_PlayerHelper:FireServer("AddItem", {21, 10}) + RE_PlayerHelper:FireServer("AddItem", {22, 10}) elseif input.KeyCode == Enum.KeyCode.K then -- RE_UpgradeAttributes:FireServer(1) RE_PlayerHelper:FireServer("AddItem", {2, 1000}) diff --git a/src/StarterPlayerScripts/UI/Common/SpecialShow.luau b/src/StarterPlayerScripts/UI/Common/SpecialShow.luau index 3a9c161..c9ef8c0 100644 --- a/src/StarterPlayerScripts/UI/Common/SpecialShow.luau +++ b/src/StarterPlayerScripts/UI/Common/SpecialShow.luau @@ -9,6 +9,7 @@ local JsonEquipment = require(ReplicatedStorage.Json.Equipment) -- local JsonItemProp = require(ReplicatedStorage.Json.ItemProp) local JsonAttributes = require(ReplicatedStorage.Json.Attributes) local JsonAbility = require(ReplicatedStorage.Json.Ability) +local JsonBlessing = require(ReplicatedStorage.Json.Blessing) function SpecialShow:Init(data: table) local self = {} @@ -45,10 +46,36 @@ function SpecialShow:Refresh() thirdDesc = thirdDesc .. "%" end - print(baseDesc, firstDesc, secondDesc, thirdDesc) self.Variables._tmpDescTitle.Text = Localization:FormatString(baseDesc, firstDesc, secondDesc, thirdDesc) - self.Variables._tmpSpecialRate.Visible = false -- self.Variables._tmpSpecialRate.Text = Localization:GetLanguageData(itemData.nameId) + + -- 特殊祝福通过数据中的特殊标记进行显示设置 + if self.Data.showSpecialBlessing then + self.Variables._tmpSpecialRate.Visible = true + local baseRateDesc, firstRateDesc, secondRateDesc = "", "", "" + local specialRateDesc = "" + if self.Data.blessingId and self.Data.blessingRate then + local blessingData = Utils:GetIdDataFromJson(JsonBlessing, self.Data.blessingId) + if blessingData.type == 1 then + baseRateDesc = Localization:GetLanguageData(1011) + firstRateDesc = Localization:GetLanguageData(Utils:GetIdDataFromJson(JsonAttributes, blessingData.effect).nameId) + elseif blessingData.type == 2 then + baseRateDesc = Localization:GetLanguageData(1012) + firstRateDesc = Localization:GetLanguageData(Utils:GetIdDataFromJson(JsonAbility,blessingData.effect).nameId) + elseif blessingData.type == 3 then + baseRateDesc = Localization:GetLanguageData(1013) + end + secondRateDesc = self.Data.blessingRate .. "%" + specialRateDesc = Localization:FormatString(baseRateDesc, firstRateDesc, secondRateDesc) + else + -- 显示尚未祝福 + specialRateDesc = Localization:GetLanguageData(1010) + end + self.Variables._tmpSpecialRate.Text = specialRateDesc + else + self.Variables._tmpSpecialRate.Visible = false + end + end function SpecialShow:Destroy() diff --git a/src/StarterPlayerScripts/UI/Windows/BlessingWindow/WeaponItem.luau b/src/StarterPlayerScripts/UI/Windows/BlessingWindow/WeaponItem.luau new file mode 100644 index 0000000..550c8a5 --- /dev/null +++ b/src/StarterPlayerScripts/UI/Windows/BlessingWindow/WeaponItem.luau @@ -0,0 +1,124 @@ +local WeaponItem = {} +WeaponItem.__index = WeaponItem + +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +local Utils = require(ReplicatedStorage.Tools.Utils) +local Localization = require(ReplicatedStorage.Tools.Localization) +local Signal = require(ReplicatedStorage.Tools.Signal) + +local JsonItemProp = require(ReplicatedStorage.Json.ItemProp) +local JsonEquipment = require(ReplicatedStorage.Json.Equipment) +local JsonBlessing = require(ReplicatedStorage.Json.Blessing) + +local LocalPlayer = game.Players.LocalPlayer + +local FolderEquipment = ReplicatedStorage:WaitForChild("Prefabs"):WaitForChild("Equipments") + +function WeaponItem:Init(data: table) + local self = {} + self.Data = data + self.Variables = { + ["_imgIcon"] = 0, + ["_tmpName"] = 0, + ["_tmpQuality"] = 0, + ["_btnClick"] = 0, + ["_imgSelected"] = 0, + ["_imgView"] = 0, + + ["_bgNowBlessingFrame"] = 0, + ["_imgNowBlessing"] = 0, + } + self.SignalConnections = {} + self.Connections = {} + + setmetatable(self, WeaponItem) + return self +end + +function WeaponItem:SetSelected(isSelected: boolean) + self.Variables._imgSelected.Visible = isSelected +end + +function WeaponItem:Refresh() + local itemData = Utils:GetIdDataFromJson(JsonItemProp, self.Data.OrgId) + self.Variables._imgIcon.Image = Localization:GetImageData(itemData.iconId) + self.Variables._tmpName.Text = Localization:GetLanguageData(itemData.nameId) + self.Variables._tmpQuality.Text = Localization:GetColoredEquipmentQualityDesc(self.Data.Quality) + + 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 + + -- 如果图鉴没有,就设置成黑色的 + if self.Data.Timestamp == 0 then + part.Handle.Mesh.TextureId = Localization:GetBlackTexture() + end + + -- 宝石显示 + if self.Data.BlessingId then + self.Variables["_imgNowBlessing"].Visible = true + local blessingData = Utils:GetIdDataFromJson(JsonBlessing, self.Data.BlessingId) + local iconId = Utils:GetIdDataFromJson(JsonItemProp, 20 + blessingData.type - 1).iconId + self.Variables["_imgNowBlessing"].Image = Localization:GetImageData(iconId) + else + self.Variables["_imgNowBlessing"].Visible = false + end +end + +function WeaponItem:OnInitFinish() + -- 点击事件 + local con = self.Variables["_btnClick"].Activated:Connect(function() + self.TopUI:ShowDetailInfo(self.Data) + self:SetSelected(true) + + if self.TopUI.LastActiveItem then + self.TopUI.LastActiveItem:SetSelected(false) + end + self.TopUI.LastActiveItem = self + end) + table.insert(self.Connections, con) + + -- 监听属性变化 + local DataFolder = Utils:GetPlayerDataFolder(LocalPlayer):FindFirstChild("Book") + local bookInstance = DataFolder:FindFirstChild(tostring(self.Data.OrgId)) + local bookCon = bookInstance.AttributeChanged:Connect(function(attribute) + local dataKey = nil + if attribute == "blessingId" then + dataKey = "BlessingId" + elseif attribute == "blessingRate" then + dataKey = "BlessingRate" + elseif attribute == "quality" then + dataKey = "Quality" + end + + if dataKey then + self.Data[dataKey] = bookInstance:GetAttribute(attribute) + self:Refresh() + + -- 更新父类显示 + self.TopUI:UpdateDetailInfo(self.Data) + end + end) + table.insert(self.Connections, bookCon) +end + +function WeaponItem:Destroy() + for k, v in pairs(self) do + self[k] = nil + end + self = nil +end + +return WeaponItem \ No newline at end of file diff --git a/src/StarterPlayerScripts/UI/Windows/BlessingWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/BlessingWindow/init.luau new file mode 100644 index 0000000..2b4f9ff --- /dev/null +++ b/src/StarterPlayerScripts/UI/Windows/BlessingWindow/init.luau @@ -0,0 +1,249 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +--> Dependencies +local UIWindow = require(ReplicatedStorage.Base.UIWindow) +local UIEnums = require(ReplicatedStorage.Base.UIEnums) + +--> Components +local WeaponItem = require(script.WeaponItem) + +--> Variables +local Utils = require(ReplicatedStorage.Tools.Utils) +local Localization = require(ReplicatedStorage.Tools.Localization) +local Signal = require(ReplicatedStorage.Tools.Signal) + +--> Json +local JsonItemProp = require(ReplicatedStorage.Json.ItemProp) +local JsonForge = require(ReplicatedStorage.Json.Forge) +local JsonBlessing = require(ReplicatedStorage.Json.Blessing) +local JsonEquipment = require(ReplicatedStorage.Json.Equipment) + +--> Events +local RE_Blessing = ReplicatedStorage.Events.RE_Blessing + +local LocalPlayer = game.Players.LocalPlayer + +local CommonFolder = LocalPlayer:WaitForChild("PlayerScripts"):WaitForChild("UI"):WaitForChild("Common") +local SpecialShow = require(CommonFolder:WaitForChild("SpecialShow")) + + +-------------------------------------------------------------------------------- + +local BlessingWindow = {} +BlessingWindow.__index = BlessingWindow +setmetatable(BlessingWindow, {__index = UIWindow}) + +function BlessingWindow:Init(UIManager: table, Data: table?) + local self = UIWindow:Init(UIManager, Data) + setmetatable(self, BlessingWindow) + self.Variables = { + ["_btnBgClose"] = 0, + + ["_goWeaponPanel"] = 0, + ["_btnClose"] = 0, + + ["__listWeaponPackage"] = 0, + -- 详情面板 + ["_btnBlessing"] = 0, + ["_btnMult"] = 0, + ["_imgIcon"] = 0, + ["_tmpName"] = 0, + ["_tmpQuality"] = 0, + + ["_bgNowBlessingFrame"] = 0, + ["_imgNowBlessing"] = 0, + + ["__moneyCoin"] = 0, + ["__listSpecial"] = 0, + ["_goSelectBlessing"] = 0, + + ["_goBlessing1"] = 0, + ["_goBlessing2"] = 0, + ["_goBlessing3"] = 0, + + ["_imgBlessingSelected1"] = 0, + ["_imgBlessingSelected2"] = 0, + ["_imgBlessingSelected3"] = 0, + + ["_btnBlessing1"] = 0, + ["_btnBlessing2"] = 0, + ["_btnBlessing3"] = 0, + + ["__moneyBlessing1"] = 0, + ["__moneyBlessing2"] = 0, + ["__moneyBlessing3"] = 0, + + } + self.MultNumber = 1 + self.MultArray = {1, 2, 5, 10} + self.MultIndex = 1 + self.AutoRecycle = false + self.UIRootName = "ui_w_blessing" + self.UIParentName = UIEnums.UIParent.UIRoot + self.BlessingType = 1 + self.NowDetailBookId = nil + + self.LastActiveItem = nil + + return self +end + +function BlessingWindow:ShowDetailInfo(data: table?) + if data then + self.NowDetailBookId = data.OrgId + + self.Variables["_imgIcon"].Image = Localization:GetImageData(Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).iconId) + self.Variables["_tmpName"].Text = Localization:GetLanguageData(Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).nameId) + self.Variables["_tmpQuality"].Text = Localization:GetColoredEquipmentQualityDesc(data.Quality) + + -- 当前祝福显示 + self.Variables["_imgNowBlessing"].Visible = true + if data.BlessingId then + local blessingData = Utils:GetIdDataFromJson(JsonBlessing, data.BlessingId) + local iconId = Utils:GetIdDataFromJson(JsonItemProp, 20 + blessingData.type - 1).iconId + self.Variables["_imgNowBlessing"].Image = Localization:GetImageData(iconId) + end + + local equipmentData = Utils:GetIdDataFromJson(JsonEquipment, data.OrgId) + -- 祝福顶部特殊显示 + self.Variables["__listSpecial"]:SetData({[1] = { + orgId = data.OrgId, + specialType = equipmentData.specialType, + specialRequire = equipmentData.specialRequire, + showSpecialBlessing = true, + blessingId = data.BlessingId, + blessingRate = data.BlessingRate, + }}) + + else + self.NowDetailBookId = nil + + self.Variables["_imgIcon"].Image = "" + self.Variables["_tmpName"].Text = "" + self.Variables["_tmpQuality"].Text = "" + + self.Variables["_imgNowBlessing"].Visible = false + end +end + +function BlessingWindow:UpdateDetailInfo(data) + if self.NowDetailBookId == data.OrgId then + self:ShowDetailInfo(data) + end +end + +function BlessingWindow:OnClickMult() + self.MultIndex += 1 + if self.MultIndex > #self.MultArray then self.MultIndex = 1 end + self.MultNumber = self.MultArray[self.MultIndex] + self.Variables["_btnMult"].Text = "x" .. self.MultNumber +end + +function BlessingWindow:OnClickBlessing() + if self.LastActiveItem then + local data = self.LastActiveItem.Data + RE_Blessing:FireServer(data.OrgId, self.BlessingType, self.MultNumber) + end +end + +-- 设置祝福类型 +function BlessingWindow:SetBlessingType(type: number) + self.BlessingType = type + for i = 1, 3 do + self.Variables["_imgBlessingSelected" .. i].Visible = i == type + end +end + +function BlessingWindow:OnOpenWindow() + UIWindow.OnOpenWindow(self) + + -- 自己进行数据处理 + local DataFolder = Utils:GetPlayerDataFolder(LocalPlayer):FindFirstChild("Book") + local data = {} + for _, child in DataFolder:GetChildren() do + data[child.Name] = { + OrgId = tonumber(child.Name), + Quality = child:GetAttribute("quality"), + Timestamp = child:GetAttribute("timestamp"), + BlessingId = child:GetAttribute("blessingId"), + BlessingRate = child:GetAttribute("blessingRate"), + } + end + self:SetData(data) + + -- 监听数据变化 + local childAddCon = DataFolder.ChildAdded:Connect(function(child) + self.Data[child.Name] = { + OrgId = tonumber(child.Name), + Quality = child:GetAttribute("quality"), + Timestamp = child:GetAttribute("timestamp"), + BlessingId = child:GetAttribute("blessingId"), + BlessingRate = child:GetAttribute("blessingRate"), + } + self.Variables["__listWeaponPackage"]:AddData(child.Name, self.Data[child.Name]) + end) + table.insert(self.Connections, childAddCon) + + -- 点击事件 + local bgCloseCon = self.Variables["_btnBgClose"].Activated:Connect(function() + self.UIManager:CloseWindow(script.Name) + end) + local closeCon = self.Variables["_btnClose"].Activated:Connect(function() + self.UIManager:CloseWindow(script.Name) + end) + local multCon = self.Variables["_btnMult"].Activated:Connect(function() + self:OnClickMult() + end) + local createCon = self.Variables["_btnBlessing"].Activated:Connect(function() + self:OnClickBlessing() + end) + + table.insert(self.Connections, bgCloseCon) + table.insert(self.Connections, closeCon) + table.insert(self.Connections, multCon) + table.insert(self.Connections, createCon) + + -- 设置祝福类型 + local blessingBtn1Con = self.Variables["_btnBlessing1"].Activated:Connect(function() + self:SetBlessingType(1) + end) + local blessingBtn2Con = self.Variables["_btnBlessing2"].Activated:Connect(function() + self:SetBlessingType(2) + end) + local blessingBtn3Con = self.Variables["_btnBlessing3"].Activated:Connect(function() + self:SetBlessingType(3) + end) + table.insert(self.Connections, blessingBtn1Con) + table.insert(self.Connections, blessingBtn2Con) + table.insert(self.Connections, blessingBtn3Con) + + -- 默认祝福显示 + self:SetBlessingType(self.BlessingType) + + self.Variables["__listWeaponPackage"]:AddComponent(WeaponItem) + self.Variables["__listWeaponPackage"]:SetData(self.Data) + self.Variables["__listWeaponPackage"]:SetLayoutOrder("OrgId") + + self.Variables["__listSpecial"]:AddComponent(SpecialShow) + + if self.Data then + local minInstance = self.Variables["__listWeaponPackage"]:GetMinLayoutOrderInstance() + if minInstance then + self:ShowDetailInfo(minInstance.Data) + + self.LastActiveItem = minInstance + minInstance:SetSelected(true) + end + else + self:ShowDetailInfo() + end +end + +function BlessingWindow:OnCloseWindow() + UIWindow.OnCloseWindow(self) +end + + + +return BlessingWindow \ No newline at end of file diff --git a/src/StarterPlayerScripts/UI/Windows/CreateWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/CreateWindow/init.luau index b413f55..067ef97 100644 --- a/src/StarterPlayerScripts/UI/Windows/CreateWindow/init.luau +++ b/src/StarterPlayerScripts/UI/Windows/CreateWindow/init.luau @@ -92,8 +92,8 @@ end function CreateWindow:ShowDetailInfo(data: table?) if data then self.Variables["_imgIcon"].Image = Localization:GetImageData(Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).iconId) - self.Variables["_tmpName"].Text = Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).nameId - self.Variables["_tmpQuality"].Text = Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).quality + self.Variables["_tmpName"].Text = Localization:GetLanguageData(Utils:GetIdDataFromJson(JsonItemProp, data.OrgId).nameId) + self.Variables["_tmpQuality"].Text = Localization:GetColoredEquipmentQualityDesc(data.Quality) else self.Variables["_imgIcon"].Image = "" self.Variables["_tmpName"].Text = "" diff --git a/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau index 3bc4894..0410f85 100644 --- a/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau +++ b/src/StarterPlayerScripts/UI/Windows/MainWindow/init.luau @@ -86,6 +86,7 @@ function MainWindow:Init(UIManager: table, Data: table?) ["_btnMainCha"] = 0, ["_btnMainAttributeUpgrade"] = 0, ["_btnStartChallenge"] = 0, + ["_btnBlessing"] = 0, -- 锻造条 ["_goForgeBar"] = 0, @@ -150,11 +151,15 @@ function MainWindow:OnOpenWindow() local startChallengeCon = self.Variables["_btnStartChallenge"].Activated:Connect(function() self:OnClickChallengeButton() end) + local blessingCon = self.Variables["_btnBlessing"].Activated:Connect(function() + self.UIManager:OpenWindow("BlessingWindow") + end) table.insert(self.Connections, createCon) table.insert(self.Connections, chaCon) table.insert(self.Connections, attributeUpgradeCon) table.insert(self.Connections, startChallengeCon) + table.insert(self.Connections, blessingCon) local challengeLevelEndCon = challengeLevelEndSignal:Connect(function(result: boolean) self.Variables["_btnStartChallenge"].Visible = true