diff --git a/excel/anim.xlsx b/excel/anim.xlsx new file mode 100644 index 0000000..52ebc72 Binary files /dev/null and b/excel/anim.xlsx differ diff --git a/excel/equipment.xlsx b/excel/equipment.xlsx index 1a1e49e..8488c3a 100644 Binary files a/excel/equipment.xlsx and b/excel/equipment.xlsx differ diff --git a/excel/global.xlsx b/excel/global.xlsx index d41e52d..df27037 100644 Binary files a/excel/global.xlsx and b/excel/global.xlsx differ diff --git a/src/ReplicatedStorage/Base/BehaviourClient.luau b/src/ReplicatedStorage/Base/BehaviourClient.luau index 3fabf58..5d515cb 100644 --- a/src/ReplicatedStorage/Base/BehaviourClient.luau +++ b/src/ReplicatedStorage/Base/BehaviourClient.luau @@ -6,6 +6,10 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") --> Dependencies local EffectDispatcher = require(ReplicatedStorage.Modules.EffectDispatcher) +local Utils = require(ReplicatedStorage.Tools.Utils) + +--> Json +local JsonAnimation = require(ReplicatedStorage.Json.Animation) -------------------------------------------------------------------------------- @@ -19,15 +23,51 @@ function BehaviourClient:Init(CasterPlayer: Player, CastInfo: table, DelayTime: self.ShowTask = nil self.EffectDispatcher = EffectDispatcher + self.Animations = {} return self end +function BehaviourClient:LoadAnimationByName(AnimationName: string) + local AnimationData = Utils:GetSpecialKeyDataFromJson(JsonAnimation, "name", AnimationName) + if not AnimationData then warn("Animation not found") return end + + -- 如果已经加载过,则直接返回 + if self.Animations[AnimationName] then return self.Animations[AnimationName] end + + local Humanoid = self.Character:FindFirstChild("Humanoid") + if not Humanoid then warn("Humanoid not found") return end + local Animator = Humanoid:FindFirstChild("Animator") + if not Animator then warn("Animator not found") return end + + local Animation = Instance.new("Animation") + Animation.AnimationId = "rbxassetid://" .. AnimationData.rbxId + + local AnimationTrack = Animator:LoadAnimation(Animation) + AnimationTrack.Priority = Enum.AnimationPriority[AnimationData.priority] + + self.Animations[AnimationName] = AnimationTrack + Animation:Destroy() + + return AnimationTrack +end + +function BehaviourClient:GetAnimationByName(AnimationName: string) + return self.Animations[AnimationName] +end + function BehaviourClient:Show(CasterPlayer: Player, CastInfo: table, DelayTime: number, CastState: boolean) end -- 销毁 function BehaviourClient:Destroy() + if self.Animations then + for _, AnimationTrack in self.Animations do + AnimationTrack:Destroy() + end + self.Animations = nil + end + if self.ShowTask then task.cancel(self.ShowTask) self.ShowTask = nil diff --git a/src/ReplicatedStorage/Base/UIWindow.luau b/src/ReplicatedStorage/Base/UIWindow.luau index 8a4cc50..185263c 100644 --- a/src/ReplicatedStorage/Base/UIWindow.luau +++ b/src/ReplicatedStorage/Base/UIWindow.luau @@ -13,6 +13,8 @@ local Utils = require(ReplicatedStorage.Tools.Utils) local LocalPlayer = game.Players.LocalPlayer local FolderPlayerGui = LocalPlayer:WaitForChild("PlayerGui") +local FolderStarterPlayerScripts = game.StarterPlayer:WaitForChild("StarterPlayerScripts") +local FolderUIInstanceScripts = FolderStarterPlayerScripts:WaitForChild("UI"):WaitForChild("InstanceScripts") -------------------------------------------------------------------------------- @@ -46,6 +48,7 @@ function UIWindow:AutoInjectVariables() if typeof(varName) == "string" then local firstChar = string.sub(varName, 1, 1) local sixChar = string.sub(varName, 1, 6) + local sevenChar = string.sub(varName, 1, 7) local target if firstChar == "_" then @@ -53,6 +56,11 @@ function UIWindow:AutoInjectVariables() local prefab = Utils:FindInDescendantsUI(self.UIRoot, varName) target = UIList:Init(prefab) target.TopUI = self + elseif sevenChar == "__money" then + target = Utils:FindInDescendantsUI(self.UIRoot, varName) + -- 把脚本放到预制体下 + local newScript = FolderUIInstanceScripts:FindFirstChild("Money"):Clone() + newScript.Parent = target else -- _开头,递归查找 target = Utils:FindInDescendantsUI(self.UIRoot, varName) diff --git a/src/ReplicatedStorage/Json/Animation.json b/src/ReplicatedStorage/Json/Animation.json new file mode 100644 index 0000000..7f1d70f --- /dev/null +++ b/src/ReplicatedStorage/Json/Animation.json @@ -0,0 +1,3 @@ +[ +{"id":1,"name":"SwordWave","rbxId":"133335766636767","priority":"Action"} +] \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Equipment.json b/src/ReplicatedStorage/Json/Equipment.json index a7d7f4d..42cb5ba 100644 --- a/src/ReplicatedStorage/Json/Equipment.json +++ b/src/ReplicatedStorage/Json/Equipment.json @@ -1,18 +1,18 @@ [ -{"id":40000,"type":1,"name":40000,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40001,"type":1,"name":40001,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40002,"type":1,"name":40002,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40003,"type":1,"name":40003,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40004,"type":1,"name":40004,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40005,"type":1,"name":40005,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40006,"type":1,"name":40006,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40007,"type":1,"name":40007,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40008,"type":1,"name":40008,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40009,"type":1,"name":40009,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40010,"type":1,"name":40010,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40011,"type":1,"name":40011,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40012,"type":1,"name":40012,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40013,"type":1,"name":40013,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40014,"type":1,"name":40014,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}, -{"id":40015,"type":1,"name":40015,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10} +{"id":40000,"type":1,"name":40000,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40001,"type":1,"name":40001,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40002,"type":1,"name":40002,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40003,"type":1,"name":40003,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40004,"type":1,"name":40004,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40005,"type":1,"name":40005,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40006,"type":1,"name":40006,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40007,"type":1,"name":40007,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40008,"type":1,"name":40008,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40009,"type":1,"name":40009,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40010,"type":1,"name":40010,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40011,"type":1,"name":40011,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40012,"type":1,"name":40012,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40013,"type":1,"name":40013,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40014,"type":1,"name":40014,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10}, +{"id":40015,"type":1,"name":40015,"attributes":[14,200,10,15,200,10,16,100,0],"modelName":"Zeus","recycle":10} ] \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Param.json b/src/ReplicatedStorage/Json/Param.json index ecbd2fc..aca4859 100644 --- a/src/ReplicatedStorage/Json/Param.json +++ b/src/ReplicatedStorage/Json/Param.json @@ -1,5 +1,6 @@ [ {"id":1,"key":"quality_bonus","intValue":null,"stringValue":null,"intArray":[100,125,150,200,275,375]}, {"id":2,"key":"level_get_bonus","intValue":null,"stringValue":null,"intArray":[5,2]}, -{"id":3,"key":"mob_died_get","intValue":null,"stringValue":null,"intArray":[2,10]} +{"id":3,"key":"mob_died_get","intValue":null,"stringValue":null,"intArray":[2,10]}, +{"id":4,"key":"default_weapon","intValue":null,"stringValue":"Sword","intArray":[]} ] \ No newline at end of file diff --git a/src/ReplicatedStorage/Modules/BehavioursClient/SwordWave.luau b/src/ReplicatedStorage/Modules/BehavioursClient/SwordWave.luau index d10be85..62b2192 100644 --- a/src/ReplicatedStorage/Modules/BehavioursClient/SwordWave.luau +++ b/src/ReplicatedStorage/Modules/BehavioursClient/SwordWave.luau @@ -20,12 +20,16 @@ function SwordWave:Init(CasterPlayer: Player, CastInfo: table, DelayTime: number local self = BehaviourClient:Init(CasterPlayer, CastInfo, DelayTime, CastState) setmetatable(self, SwordWave) + -- 加载动画 + self:LoadAnimationByName("SwordWave") return self end function SwordWave:Show(CasterPlayer: Player, CastInfo: table, DelayTime: number, CastState: boolean) self.ShowTask, self.Projectile, self.Tween = self.EffectDispatcher:ShowProjectile(self.Player, DelayTime, 0, CastInfo.StartPos, CastInfo.EndPos, CastInfo.Duration, Prefab_SwordWave, Enum.EasingStyle.Linear) + + self.EffectDispatcher:ShowAnimation(self.Player, DelayTime, self:GetAnimationByName("SwordWave")) end function SwordWave:Destroy() diff --git a/src/ReplicatedStorage/Modules/EffectDispatcher.luau b/src/ReplicatedStorage/Modules/EffectDispatcher.luau index 8f9fcfd..a497d04 100644 --- a/src/ReplicatedStorage/Modules/EffectDispatcher.luau +++ b/src/ReplicatedStorage/Modules/EffectDispatcher.luau @@ -26,7 +26,6 @@ function EffectDispatcher:ShowProjectile(Caster: Player, DelayTime: number, PreT Projectile.CanCollide = false Projectile.Anchored = true - -- Tween动画 local tweenInfo = TweenInfo.new(Duration, EasingStyle or Enum.EasingStyle.Linear) local direction = (EndPos - StartPos).Unit @@ -43,4 +42,8 @@ function EffectDispatcher:ShowProjectile(Caster: Player, DelayTime: number, PreT return projectileTask, Projectile, tween end +function EffectDispatcher:ShowAnimation(Caster: Player, DelayTime: number, AnimationTrack: AnimationTrack) + AnimationTrack:Play() +end + return EffectDispatcher \ No newline at end of file diff --git a/src/ReplicatedStorage/Tools/Utils.luau b/src/ReplicatedStorage/Tools/Utils.luau index d1051f5..4966c66 100644 --- a/src/ReplicatedStorage/Tools/Utils.luau +++ b/src/ReplicatedStorage/Tools/Utils.luau @@ -11,6 +11,13 @@ local PlayerDataFolder = ReplicatedStorage:WaitForChild("PlayerData") -------------------------------------------------------------------------------- +function Utils:WaitPlayerDataFolder(Player: Player) + local pData = PlayerDataFolder:WaitForChild(Player.UserId) + if pData then return pData end + warn("玩家数据不存在: " .. Player.Name) + return nil +end + function Utils:GetPlayerDataFolder(Player: Player) local pData = PlayerDataFolder:FindFirstChild(Player.UserId) if pData then return pData end diff --git a/src/ServerStorage/Proxy/EquipmentProxy.luau b/src/ServerStorage/Proxy/EquipmentProxy.luau index 9d8796a..a0b63c4 100644 --- a/src/ServerStorage/Proxy/EquipmentProxy.luau +++ b/src/ServerStorage/Proxy/EquipmentProxy.luau @@ -281,6 +281,11 @@ function EquipmentProxy:WearEquipment(Player: Player, EquipmentId: number, Slot: -- 更新玩家数据 PlayerFightProxy:UpdatePlayerFightData(Player) + + -- 给前端的提示(模型穿戴) + if Slot == 1 then + RE_WearEquipment:FireClient(Player, true, EquipmentId, Slot) + end end -- 卸下装备 @@ -288,15 +293,20 @@ function EquipmentProxy:UnwearEquipment(Player: Player, EquipmentId: number) local pData = Utils:GetPlayerDataFolder(Player) if not pData then return end - -- TODO :卸下装备时再关闭模型 - -- 卸下装备 local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId] if not EquipmentData then return end + + -- 给前端的提示(模型卸下) + if EquipmentData.wearing == 1 then + RE_WearEquipment:FireClient(Player, false, EquipmentId, EquipmentData.wearing) + end + ChangeValue(Player, EquipmentId, "wearing", 0) -- 更新玩家数据 PlayerFightProxy:UpdatePlayerFightData(Player) + end -- 获取穿戴中的装备UniqueId diff --git a/src/ServerStorage/Proxy/PlayerFightProxy/init.luau b/src/ServerStorage/Proxy/PlayerFightProxy/init.luau index bd0ecd0..c9b8af4 100644 --- a/src/ServerStorage/Proxy/PlayerFightProxy/init.luau +++ b/src/ServerStorage/Proxy/PlayerFightProxy/init.luau @@ -178,7 +178,7 @@ function PlayerFightProxy:UpdatePlayerFightData(Player: Player) for _, behaviourName in behaviourNameList do playerAI:AddBehaviour(behaviourName) end - playerAI:AddBehaviour("Move") + -- playerAI:AddBehaviour("Move") playerAI:AddBehaviour("SwordWave") diff --git a/src/ServerStorage/Proxy/PlayerInfoProxy.luau b/src/ServerStorage/Proxy/PlayerInfoProxy.luau index f86d984..3d2a261 100644 --- a/src/ServerStorage/Proxy/PlayerInfoProxy.luau +++ b/src/ServerStorage/Proxy/PlayerInfoProxy.luau @@ -335,7 +335,6 @@ end) RE_UpgradeAttributes.OnServerEvent:Connect(function(Player: Player, AttributeId: number) PlayerInfoProxy:UpgradeAttribute(Player, AttributeId) - print(ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade) end) return PlayerInfoProxy \ No newline at end of file diff --git a/src/StarterPlayerScripts/ClientMain/DefaultUIClose.luau b/src/StarterPlayerScripts/ClientMain/DefaultUIClose.luau new file mode 100644 index 0000000..aa43f22 --- /dev/null +++ b/src/StarterPlayerScripts/ClientMain/DefaultUIClose.luau @@ -0,0 +1,6 @@ +local StarterGui = game:GetService("StarterGui") + +-- Disable default health bar and backpack +StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false) + +return {} \ No newline at end of file diff --git a/src/StarterPlayerScripts/ClientMain/MeleeMobAlign.luau b/src/StarterPlayerScripts/ClientMain/MeleeMobAlign.luau index c914c75..eb043d6 100644 --- a/src/StarterPlayerScripts/ClientMain/MeleeMobAlign.luau +++ b/src/StarterPlayerScripts/ClientMain/MeleeMobAlign.luau @@ -9,85 +9,88 @@ fighting any enemy with a melee weapon, especially on platforms like mobile, where shift lock may not be a feature. ]] ---> Services -local CollectionService = game:GetService("CollectionService") -local UserInputService = game:GetService("UserInputService") -local RunService = game:GetService("RunService") -local Players = game:GetService("Players") +-- 临时关闭(原参考demo代码) +return {} ---> Player -local Player = Players.LocalPlayer +-- --> Services +-- local CollectionService = game:GetService("CollectionService") +-- local UserInputService = game:GetService("UserInputService") +-- local RunService = game:GetService("RunService") +-- local Players = game:GetService("Players") ---> Variables -local Focus: Model? +-- --> Player +-- local Player = Players.LocalPlayer ---> Configuration -local Enabled = true +-- --> Variables +-- local Focus: Model? --------------------------------------------------------------------------------- +-- --> Configuration +-- local Enabled = true -if not Enabled then - return {} -end +-- -------------------------------------------------------------------------------- -local function GetNearestMob() - local Character = Player.Character - if not Character then return end +-- if not Enabled then +-- return {} +-- end + +-- local function GetNearestMob() +-- local Character = Player.Character +-- if not Character then return end - local Closest = {MobInstance = nil, Distance = math.huge} +-- local Closest = {MobInstance = nil, Distance = math.huge} - for _, MobInstance in CollectionService:GetTagged("Mob") do - local MobConfig = MobInstance:FindFirstChild("MobConfig") and require(MobInstance.MobConfig) - local Enemy = MobInstance:FindFirstChild("Enemy") - if not MobConfig or not Enemy or Enemy.Health == 0 then continue end +-- for _, MobInstance in CollectionService:GetTagged("Mob") do +-- local MobConfig = MobInstance:FindFirstChild("MobConfig") and require(MobInstance.MobConfig) +-- local Enemy = MobInstance:FindFirstChild("Enemy") +-- if not MobConfig or not Enemy or Enemy.Health == 0 then continue end - local Distance = (Character:GetPivot().Position - MobInstance:GetPivot().Position).Magnitude - local MaxDistance = MobConfig.FollowDistance +-- local Distance = (Character:GetPivot().Position - MobInstance:GetPivot().Position).Magnitude +-- local MaxDistance = MobConfig.FollowDistance - if (Distance < MaxDistance) and (Distance < Closest.Distance) then - Closest.MobInstance = MobInstance - Closest.Distance = Distance - end - end +-- if (Distance < MaxDistance) and (Distance < Closest.Distance) then +-- Closest.MobInstance = MobInstance +-- Closest.Distance = Distance +-- end +-- end - return Closest.MobInstance -end +-- return Closest.MobInstance +-- end -task.defer(function() - while true do - task.wait(1/5) - Focus = GetNearestMob() - end -end) +-- task.defer(function() +-- while true do +-- task.wait(1/5) +-- Focus = GetNearestMob() +-- end +-- end) -RunService:BindToRenderStep("MeleeLock", Enum.RenderPriority.Character.Value + 1, function(DeltaTime: number) - local Character = Player.Character - local Humanoid = Character and Character:FindFirstChild("Humanoid") :: Humanoid? - local HumanoidRootPart = Character and Character:FindFirstChild("HumanoidRootPart") :: BasePart? - if not Humanoid or not HumanoidRootPart then return end +-- RunService:BindToRenderStep("MeleeLock", Enum.RenderPriority.Character.Value + 1, function(DeltaTime: number) +-- local Character = Player.Character +-- local Humanoid = Character and Character:FindFirstChild("Humanoid") :: Humanoid? +-- local HumanoidRootPart = Character and Character:FindFirstChild("HumanoidRootPart") :: BasePart? +-- if not Humanoid or not HumanoidRootPart then return end - local Success = false +-- local Success = false - if Focus and UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then - local Tool = Character:FindFirstChildOfClass("Tool") - local ItemConfig = Tool and require(Tool:FindFirstChild("ItemConfig")) +-- if Focus and UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then +-- local Tool = Character:FindFirstChildOfClass("Tool") +-- local ItemConfig = Tool and require(Tool:FindFirstChild("ItemConfig")) - if ItemConfig and ItemConfig.WeaponType == "Melee" then - local CurrentRotation = HumanoidRootPart.CFrame.Rotation - local GoalRotation = CFrame.lookAt(HumanoidRootPart.Position, Focus:GetPivot().Position).Rotation - local _, Y, _ = CurrentRotation:Lerp(GoalRotation, DeltaTime * 30):ToOrientation() - local X, _, Z = CurrentRotation:ToOrientation() +-- if ItemConfig and ItemConfig.WeaponType == "Melee" then +-- local CurrentRotation = HumanoidRootPart.CFrame.Rotation +-- local GoalRotation = CFrame.lookAt(HumanoidRootPart.Position, Focus:GetPivot().Position).Rotation +-- local _, Y, _ = CurrentRotation:Lerp(GoalRotation, DeltaTime * 30):ToOrientation() +-- local X, _, Z = CurrentRotation:ToOrientation() - Humanoid.AutoRotate = false - HumanoidRootPart.CFrame = CFrame.Angles(X, Y, Z) + HumanoidRootPart.Position +-- Humanoid.AutoRotate = false +-- HumanoidRootPart.CFrame = CFrame.Angles(X, Y, Z) + HumanoidRootPart.Position - Success = true - end - end +-- Success = true +-- end +-- end - if not Success then - Humanoid.AutoRotate = true - end -end) +-- if not Success then +-- Humanoid.AutoRotate = true +-- end +-- end) -return {} \ No newline at end of file +-- return {} \ No newline at end of file diff --git a/src/StarterPlayerScripts/ClientMain/PerformanceClient/init.luau b/src/StarterPlayerScripts/ClientMain/PerformanceClient/init.luau index 43b423b..a526288 100644 --- a/src/StarterPlayerScripts/ClientMain/PerformanceClient/init.luau +++ b/src/StarterPlayerScripts/ClientMain/PerformanceClient/init.luau @@ -115,5 +115,6 @@ end) -- 打开默认界面 UIManager:OpenWindow("MainWindow") +UIManager:OpenWindow("TipsWindow") return PerformanceClient \ No newline at end of file diff --git a/src/StarterPlayerScripts/ClientMain/WeaponModel.luau b/src/StarterPlayerScripts/ClientMain/WeaponModel.luau new file mode 100644 index 0000000..5ce0310 --- /dev/null +++ b/src/StarterPlayerScripts/ClientMain/WeaponModel.luau @@ -0,0 +1,85 @@ +local WeaponModel = {} + +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Utils = require(ReplicatedStorage.Tools.Utils) + +--> Json +local JsonEquipment = require(ReplicatedStorage.Json.Equipment) +local JsonParam = require(ReplicatedStorage.Json.Param) + +--> Events +local RE_WearEquipment = ReplicatedStorage.Events.RE_WearEquipment + +--> Variables +local LocalPlayer = game.Players.LocalPlayer +local Character = LocalPlayer.Character +local LastWeaponName + +-- 如果角色不存在,等待角色加载 +if not Character then + Character = LocalPlayer.CharacterAdded:Wait() +end + +local FolderEquipment = Utils:WaitPlayerDataFolder(LocalPlayer):WaitForChild("Equipment") +local FolderPrefabEquipments = ReplicatedStorage.Prefabs.Equipments +local FolderBackpack = LocalPlayer.Backpack + +function WeaponModel:SetWeaponModel(WeaponInstance: Instance) + local WeaponData = Utils:GetIdDataFromJson(JsonEquipment, tonumber(WeaponInstance:GetAttribute("orgId"))) + if not WeaponData then warn("WeaponData not found") return end + + local WeaponModel = FolderPrefabEquipments:FindFirstChild(WeaponData.modelName) + if not WeaponModel then warn("WeaponModel not found") return end + + local newWeapon = WeaponModel:Clone() + newWeapon.Parent = LocalPlayer.Backpack + Character:FindFirstChild("Humanoid"):EquipTool(newWeapon) + return newWeapon.Name +end + +function WeaponModel:SetDefaultWeaponModel() + local modelName = Utils:GetIdDataFromJson(JsonParam, 4).stringValue + local WeaponModel = FolderPrefabEquipments:FindFirstChild(modelName) + if not WeaponModel then warn("DefaultWeaponModel not found") return end + + local newWeapon = WeaponModel:Clone() + newWeapon.Parent = LocalPlayer.Backpack + + Character:FindFirstChild("Humanoid"):EquipTool(newWeapon) + return newWeapon.Name +end + +-- 初始化 +local instance +for _, WeaponInstance in FolderEquipment:GetChildren() do + if WeaponInstance:GetAttribute("wearing") == 1 then + instance = WeaponInstance + break + end +end +-- 设置初始化武器 +if instance then + LastWeaponName = WeaponModel:SetWeaponModel(instance) +else + LastWeaponName = WeaponModel:SetDefaultWeaponModel() +end + +-- 穿戴装备 +RE_WearEquipment.OnClientEvent:Connect(function(IsWear: boolean, EquipmentId: number, Slot: number) + local oldWeaponName = LastWeaponName + if IsWear then + local newInstance = FolderEquipment:FindFirstChild(EquipmentId) + if not newInstance then warn("newInstance not found") return end + LastWeaponName = WeaponModel:SetWeaponModel(newInstance) + else + LastWeaponName = WeaponModel:SetDefaultWeaponModel() + end + for _, child in FolderBackpack:GetChildren() do + if child.Name == oldWeaponName then + child:Destroy() + end + end +end) + +return WeaponModel \ No newline at end of file diff --git a/src/StarterPlayerScripts/UI/InstanceScripts/Money.client.luau b/src/StarterPlayerScripts/UI/InstanceScripts/Money.client.luau new file mode 100644 index 0000000..77fc543 --- /dev/null +++ b/src/StarterPlayerScripts/UI/InstanceScripts/Money.client.luau @@ -0,0 +1,57 @@ +-- 检查父级是否为Frame类型,如果不是则退出脚本 +if typeof(script.Parent) ~= "Instance" or not script.Parent:IsA("Frame") then return end + +-- 必须读取内容 +local CheckMoneyId = script.Parent:GetAttribute("CheckMoneyId") +local tmpValue = script.Parent:FindFirstChild("_tmpValue") +local imgIcon = script.Parent:FindFirstChild("_imgIcon") +if not CheckMoneyId or not tmpValue or not imgIcon then warn("Money实例内容初始化失败") return end + +--> Server +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +--> Modules +local Utils = require(ReplicatedStorage.Tools.Utils) +local Localization = require(ReplicatedStorage.Tools.Localization) + +--> Json +local JsonItemProp = require(ReplicatedStorage.Json.ItemProp) + +-- 临时变量 +local LocalPlayer = game.Players.LocalPlayer +local connection, connectionFolder + +local PlayerDataFolder = Utils:GetPlayerDataFolder(LocalPlayer) +if not PlayerDataFolder then warn("无法获取玩家数据文件夹") return end + +local PlayerInfo = PlayerDataFolder:FindFirstChild("PlayerInfo") +if not PlayerInfo then warn("无法获取玩家信息文件夹") return end + +local MoneyFolder = PlayerInfo:FindFirstChild("Items") +if not MoneyFolder then warn("无法获取物品文件夹") return end + +local InstanceMoney = MoneyFolder:FindFirstChild(CheckMoneyId) + +local ItemData = Utils:GetIdDataFromJson(JsonItemProp, tonumber(CheckMoneyId)) +imgIcon.Image = Localization:GetImageData(ItemData.iconId) + +if not InstanceMoney then + tmpValue.Text = "0" + connectionFolder = MoneyFolder.ChildAdded:Connect(function(child) + if child.Name == tostring(CheckMoneyId) then + tmpValue.Text = child.Value + InstanceMoney = child + connectionFolder:Disconnect() + end + end) +else + tmpValue.Text = InstanceMoney.Value + connection = InstanceMoney.Changed:Connect(function(newValue) + tmpValue.Text = newValue + end) +end + +script.Destroying:Once(function() + if connectionFolder then connectionFolder:Disconnect() end + if connection then connection:Disconnect() end +end) \ No newline at end of file diff --git a/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/AttributeLvupShow.luau b/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/AttributeLvupShow.luau index 6070115..cde052e 100644 --- a/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/AttributeLvupShow.luau +++ b/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/AttributeLvupShow.luau @@ -45,16 +45,15 @@ function AttributeLvupShow:Refresh() end if self.instance and not self.instanceCon then - local instanceCon = self.instance.ValueChanged:Connect(function() + local instanceCon = self.instance.Changed:Connect(function() self:Refresh() end) self.instanceCon = instanceCon end - local attributeData = Utils:GetSpecialKeyDataFromJson(JsonAttributes, "effectAttribute", self.Data.attribute) + local attributeData = Utils:GetIdDataFromJson(JsonAttributes, self.Data.id) self.Variables._imgIcon.Image = Localization:GetImageData(attributeData.iconId) self.Variables._tmpAttributeName.Text = self.Data.id - self.UIRoot.LayoutOrder = 1000 - attributeData.id local nowLv = self:GetNowLv() self.Variables._tmpLv.Text = "Lv." .. nowLv @@ -91,13 +90,18 @@ function AttributeLvupShow:OnInitFinish() -- 没有实例时,监听文件夹,有实例时,监听实例 if not self.instance then local attributeFolder = Utils:GetPlayerDataFolder(LocalPlayer):FindFirstChild("PlayerInfo"):FindFirstChild("AttributesUpgrade") - local folderCon = attributeFolder.ChildAdded:Connect(function(child) - if child.Name == tostring(self.Data.id) then - self.instance = child - self:Refresh() - end - end) - self.folderCon = folderCon + local attributeInst = attributeFolder:FindFirstChild(tostring(self.Data.id)) + if attributeInst then + self.instance = attributeInst + else + local folderCon = attributeFolder.ChildAdded:Connect(function(child) + if child.Name == tostring(self.Data.id) then + self.instance = child + self:Refresh() + end + end) + self.folderCon = folderCon + end end end diff --git a/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/init.luau index d6198c0..ecf4b69 100644 --- a/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/init.luau +++ b/src/StarterPlayerScripts/UI/Windows/AttributeLvupWindow/init.luau @@ -28,6 +28,11 @@ function AttributeLvupWindow:Init(UIManager: table, Data: table?) ["__listBaseAttributes"] = 0, ["_tmpSpecialTitle"] = 0, ["_tmpBaseTitle"] = 0, + + ["__moneyCoin"] = 0, + + ["_btnClose"] = 0, + ["_btnBgClose"] = 0, } self.UIRootName = "ui_w_attribute_lvup" self.UIParentName = UIEnums.UIParent.UIRoot @@ -59,6 +64,15 @@ function AttributeLvupWindow:OnOpenWindow() self.Variables["__listBaseAttributes"]:SetData(self.Data.Base) self.Variables["__listSpecialAttributes"]:SetLayoutOrder("id") self.Variables["__listBaseAttributes"]:SetLayoutOrder("id") + + 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) + table.insert(self.Connections, bgCloseCon) + table.insert(self.Connections, closeCon) end diff --git a/src/StarterPlayerScripts/UI/Windows/ChaWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/ChaWindow/init.luau index b11bb7b..d1d19c0 100644 --- a/src/StarterPlayerScripts/UI/Windows/ChaWindow/init.luau +++ b/src/StarterPlayerScripts/UI/Windows/ChaWindow/init.luau @@ -81,15 +81,18 @@ function ChaWindow:AddInstanceData(configInstance: Instance, Data: table?) local attributes = configInstance:GetAttributes() -- 归类是否是穿戴的装备 - local parentName = "Package" - if attributes.wearing ~= 0 then parentName = "Wearing" end - data[parentName][configInstance.Name] = {} + local parentName, secondName = "Package", configInstance.Name + if attributes.wearing ~= 0 then + parentName = "Wearing" + secondName = "slot"..attributes.wearing + end + data[parentName][secondName] = {} for attributeKey, attributeValue in attributes do - data[parentName][configInstance.Name][attributeKey] = attributeValue + data[parentName][secondName][attributeKey] = attributeValue end - data[parentName][configInstance.Name].instance = configInstance - return data[parentName][configInstance.Name], parentName + data[parentName][secondName].instance = configInstance + return data[parentName][secondName], parentName end function ChaWindow:OnOpenWindow() @@ -125,9 +128,9 @@ function ChaWindow:OnOpenWindow() local addCon = DataFolder.ChildAdded:Connect(function(child) local data, parentName = self:AddInstanceData(child, data) if parentName == "Wearing" then - self.Variables["__listWeaing"]:AddData(data) + self.Variables["__listWeaing"]:AddData("slot"..data.wearing, data) else - self.Variables["__listWeaponPackage"]:AddData(data) + self.Variables["__listWeaponPackage"]:AddData(child.Name, data) end end) diff --git a/src/StarterPlayerScripts/UI/Windows/TipsWindow/init.luau b/src/StarterPlayerScripts/UI/Windows/TipsWindow/init.luau new file mode 100644 index 0000000..379d172 --- /dev/null +++ b/src/StarterPlayerScripts/UI/Windows/TipsWindow/init.luau @@ -0,0 +1,63 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +--> Dependencies +local UIWindow = require(ReplicatedStorage.Base.UIWindow) +local UIEnums = require(ReplicatedStorage.Base.UIEnums) +local Tween = require(ReplicatedStorage.Modules.Tween) + +--> Components + +--> Events +local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip + +-------------------------------------------------------------------------------- + +local TipsWindow = {} +TipsWindow.__index = TipsWindow +setmetatable(TipsWindow, {__index = UIWindow}) + +function TipsWindow:Init(UIManager: table, Data: table?) + local self = UIWindow:Init(UIManager, Data) + setmetatable(self, TipsWindow) + self.Variables = { + ["__goPanel1"] = 0, + } + self.UIRootName = "ui_w_tips" + self.UIParentName = UIEnums.UIParent.UIRoot + + return self +end + +function TipsWindow:ShowPanel1(text: string) + local newPanel = self.Variables["__goPanel1"]:Clone() + newPanel.Parent = self.UIRoot + newPanel.Visible = true + newPanel:FindFirstChild("_tmpContent").Text = text or "" + + -- 设置初始位置(向下偏移) + + -- 创建向上移动的tween动画 + local tween = Tween:Play(newPanel, {2, "Circular", "Out"}, { + Position = newPanel.Position + UDim2.new(0, 0, 0, -80) + }) + + -- 动画完成后自动销毁面板 + tween.Completed:Once(function() + task.delay(0.5, function() + newPanel:Destroy() + end) + end) +end + +function TipsWindow:OnOpenWindow() + UIWindow.OnOpenWindow(self) + + self.Variables["__goPanel1"].Visible = false + local con = RE_PlayerTip.OnClientEvent:Connect(function(data) + self:ShowPanel1(data) + end) + table.insert(self.Connections, con) +end + +return TipsWindow \ No newline at end of file