This commit is contained in:
Ggafrik 2025-07-09 23:59:56 +08:00
parent f1728a045b
commit c1c22aa963
18 changed files with 296 additions and 47 deletions

Binary file not shown.

View File

@ -0,0 +1,13 @@
[
{"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":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},
{"id":10,"type":2,"effectAttribute":"wearNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":4},
{"id":11,"type":2,"effectAttribute":"skillNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":12,"type":2,"effectAttribute":"extraAttributeNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":13,"type":2,"effectAttribute":"elementNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":14,"type":2,"effectAttribute":"elementDefNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":15,"type":2,"effectAttribute":"gemNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3}
]

View File

@ -40,22 +40,21 @@ end
-- 检查当前状态是否可执行
function Behaviour:CheckStat()
if not self.Character then warn("Behaviour Character not found") return false end
if not self.Character then return true end
-- 死亡检查
if self.Character:GetState("Died") then return false end
if self.Character:GetState("Died") then return true end
-- 执行状态中检查
local ExecutingState = self.PlayerAI.ExecutingState
-- 其他内容执行中就false
if ExecutingState == true then return false end
return true
if ExecutingState == true then return true end
return false
end
-- 改变当前执行状态标记
function Behaviour:ChangeExecutingState(State: boolean)
if not self.Character then warn("Behaviour Character not found") return end
local ExecutingState = self.PlayerAI.ExecutingState
ExecutingState.Value = State
self.PlayerAI.ExecutingState = State
end
-- 销毁

View File

@ -20,6 +20,7 @@ function Character.new(Player: Player, CharacterModel: Model, CharacterData: tab
self.Root = HumanoidRootPart
self.Humanoid = mobHumanoid
self.Origin = HumanoidRootPart:GetPivot()
self.Player = Player
self.TargetPlayerUserID = Player.UserId
self.Connections = {}
self.Stats = {}

View File

@ -12,6 +12,7 @@ local MobsProxy = require(ServerStorage.Proxy.MobsProxy)
local Move = {}
Move.__index = Move
setmetatable(Move, {__index = Behaviour})
function Move:Init(PlayerAI, Character: TypeList.Character, Player: Player)
local self = Behaviour:Init(PlayerAI, Character)
@ -24,7 +25,7 @@ function Move:Check(CheckInfo: table)
if Behaviour.CheckStat(self) then return -1, self.CheckData end
local PlayerMobs = MobsProxy:GetPlayerMobs(self.Player)
if not PlayerMobs then warn("PlayerMobs not found") return end
if not PlayerMobs then return end
local closestMob, minDistance = nil, math.huge
for _, Mob in PlayerMobs do
@ -50,7 +51,7 @@ end
function Move:Execute()
self.ExeTask = task.spawn(function ()
self:ChangeExecutingState(true)
self.Character.Humanoid.WalkToPart.CFrame = self.CheckData["ClosestCharacter"].Instance.PrimaryPart.CFrame
self.Character.Humanoid:MoveTo(self.CheckData["ClosestCharacter"].Instance:GetPivot().Position)
task.wait(0.5)
self:ChangeExecutingState(false)
end)

View File

@ -31,6 +31,12 @@ function ArchiveProxy:IsPlayerDataLoaded(Player: Player)
return true -- 成功加载
end
function ArchiveProxy:CleanPlayerData(Player: Player)
if not ArchiveProxy.pData[Player.UserId] then warn('CleanPlayerData: ', Player.Name, '数据不存在') return end
ArchiveProxy.pData[Player.UserId] = {}
print("清除数据成功")
end
--------------------------------------------------------------------------------
local PlayerData = Instance.new("Configuration")

View File

@ -57,6 +57,7 @@ function DamageProxy:TakeDamage(Caster: TypeList.Character, Victim: TypeList.Cha
-- 伤害计算
local VictimHealth = Victim:GetAttributeValue("hp")
Victim:ChangeAttributeValue("hp", math.max(0, VictimHealth - Damage))
print("伤害数据打印", Damage, VictimHealth)
end
end

View File

@ -0,0 +1,24 @@
local HelpProxy = {}
--> Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--> Events
local RE_PlayerHelper = ReplicatedStorage.Events.RE_PlayerHelper
function HelpProxy:CleanPlayerData(Player: Player)
local ArchiveProxy = require(script.Parent.ArchiveProxy)
ArchiveProxy:CleanPlayerData(Player)
end
RE_PlayerHelper.OnServerEvent:Connect(function(Player: Player, EventName: string, EventData: any)
if EventName == "CleanPlayerData" then
HelpProxy:CleanPlayerData(Player)
elseif EventName == "AddItem" then
local PlayerInfoProxy = require(script.Parent.PlayerInfoProxy)
PlayerInfoProxy:ChangeItemCount(Player, EventData[1], EventData[2])
print("添加物品成功", PlayerInfoProxy:GetItemCount(Player, EventData[1]))
end
end)
return HelpProxy

View File

@ -15,6 +15,9 @@ local TypeList = require(ServerStorage.Base.TypeList)
--> Json
local JsonLevel = require(ReplicatedStorage.Json.Level)
--> Events
local BD_ChallengeEnd = ReplicatedStorage.Events.BD_ChallengeEnd
--> Constants
local STORE_NAME = "Level"
local ENUM_LEVEL_TYPE = {
@ -84,7 +87,7 @@ end
local function OnMobDied(Player: Player, Mob: TypeList.Character)
for _, mob in LevelProxy.pData[Player.UserId].Mobs do
if mob ~= Mob then continue end
table.remove(LevelProxy.pData[Player.UserId].Mobs, mob)
table.remove(LevelProxy.pData[Player.UserId].Mobs, table.find(LevelProxy.pData[Player.UserId].Mobs, mob))
-- 怪物清除判断
local LevelData = Utils:GetJsonData(JsonLevel, LevelProxy.pData[Player.UserId].LevelId)
@ -149,8 +152,6 @@ function LevelProxy:InitPlayer(Player: Player)
if key == "Task" or key == "Mobs" then continue end
CreateLevelInstance(Player, ChallengeFolder, key, value)
end
-- self:ChallengeLevel(Player, 1)
end
-- 挑战关卡(挑战副本用另一个函数)
@ -165,7 +166,7 @@ function LevelProxy:ChallengeLevel(Player: Player, LevelId: number)
local LevelFolder = GetPlayerLevelWorkspaceFolder(Player.UserId)
local ChallengeFolder = LevelFolder:FindFirstChild("Challenge")
if not ChallengeFolder then warn("ChallengeFolder not found") return end
local levelTask = task.defer(function()
local levelTask = task.spawn(function()
ChangeValue(Player, ChallengeFolder, "IsBoss", LevelData.type == 2 and true or false)
ChangeValue(Player, ChallengeFolder, "LevelId", LevelId)
ChangeValue(Player, ChallengeFolder, "Time", 0)
@ -218,7 +219,7 @@ function LevelProxy:ChallengeLevel(Player: Player, LevelId: number)
end
end
end)
ChangeValue(Player, ChallengeFolder, "Task", levelTask)
LevelProxy.pData[Player.UserId].Task = levelTask
end
-- 挑战结束
@ -226,8 +227,15 @@ function LevelProxy:ChallengeEnd(Player: Player, result: boolean)
local pData = Utils:GetPlayerDataFolder(Player)
local LevelFolder = Utils:CreateFolder(STORE_NAME, pData)
local ProgressFolder = Utils:CreateFolder("Progress", LevelFolder)
-- 停止关卡循环
if LevelProxy.pData[Player.UserId].Task then
task.cancel(LevelProxy.pData[Player.UserId].Task)
LevelProxy.pData[Player.UserId].Task = nil
end
-- 清除剩余怪物
for _, mob in LevelProxy.pData[Player.UserId].Mobs do mob:Died() end
for _, mob in LevelProxy.pData[Player.UserId].Mobs do mob:Died(true) end
LevelProxy.pData[Player.UserId].Mobs = {}
-- 判断玩家是否通关
@ -239,6 +247,7 @@ function LevelProxy:ChallengeEnd(Player: Player, result: boolean)
ChangeValue(Player, ProgressFolder, "BossFail", LevelProxy.pData[Player.UserId].LevelId)
end
end
BD_ChallengeEnd:Fire(Player, LevelProxy.pData[Player.UserId].LevelId, result)
end
function LevelProxy:OnPlayerRemoving(Player: Player)
@ -249,7 +258,7 @@ function LevelProxy:OnPlayerRemoving(Player: Player)
end
-- 关卡存储数据清除
if LevelProxy.pData[Player.UserId].Task then
LevelProxy.pData[Player.UserId].Task:Cancel()
task.cancel(LevelProxy.pData[Player.UserId].Task)
end
LevelProxy.pData[Player.UserId] = nil
end

View File

@ -20,33 +20,27 @@ function AI:GetModelDistance(Unit1: Model, Unit2: Model): number
end
function AI:GetClosestPlayer(Mob: TypeList.Character): (Player?, number?)
local Closest = {Player = nil, Magnitude = math.huge}
local Closest = {PlayerRole = nil, Magnitude = math.huge, Player = nil}
local ActivePlayer -- We retain a reference to this, so they have to get further away from the mob to stop following, instead of the usual distance.
if Mob.Humanoid.WalkToPart then
local Player = Players:GetPlayerFromCharacter(Mob.Humanoid.WalkToPart.Parent)
if Player then
ActivePlayer = Player
end
end
-- 临时的
local PlayerRole = Mob.PlayerRole
local Character = PlayerRole.Instance
if Character == nil then warn("AI:GetClosestPlayer Character not found", Mob.Name) return end
for _, Player in Players:GetPlayers() do
if Mob.TargetPlayerUserID == Player.UserId then
local Character = Player.Character
if not Character then continue end
local Magnitude = (Character:GetPivot().Position - Mob.Instance:GetPivot().Position).Magnitude
local MaxDistance = (ActivePlayer == Player and (Mob.Config.FollowDistance or 32) * 2) or Mob.Config.FollowDistance or 32
if Magnitude <= MaxDistance and Magnitude < Closest.Magnitude then
Closest.Player = Player
Closest.Magnitude = Magnitude
end
Closest.Player = Player
end
end
local Magnitude = (Character:GetPivot().Position - Mob.Instance:GetPivot().Position).Magnitude
-- 最大距离暂时设置大值
local MaxDistance = Mob.Config.FollowDistance or 10000
if Magnitude <= MaxDistance and Magnitude < Closest.Magnitude then
Closest.PlayerRole = PlayerRole
Closest.Magnitude = Magnitude
end
return Closest.Player, Closest.Player and Closest.Magnitude
return Closest.Player, Closest.PlayerRole, Closest.PlayerRole and Closest.Magnitude
end
-- Adds the mob to the ActiveMobs table. This table runs a few times per second and updates follow & jump code for active mobs.
@ -66,7 +60,10 @@ task.defer(function()
for MobInstance, Mob in ActiveMobs do
task.spawn(function()
if not Mob.Stats.Died then
local Player, distance = AI:GetClosestPlayer(Mob)
-- 执行其他内容就停止
if Mob.ExecutingState then return end
local Player, PlayerRole, distance = AI:GetClosestPlayer(Mob)
local Enemy = Mob.Humanoid
-- Simulation
@ -79,16 +76,22 @@ task.defer(function()
end
-- Tracking
if Player and Enemy then
if Player and Enemy and PlayerRole then
if PlayerRole.Stats.Died then return end
if distance > 5 then
Enemy:MoveTo(Player.Character:GetPivot().Position, Player.Character.PrimaryPart)
else
Mob.ExecutingState = true
-- 停止移动
Enemy:MoveTo(MobInstance:GetPivot().Position)
-- 触发攻击逻辑
task.wait(Mob.Config.attackSpeed)
-- 攻击间隔后再次判断状态
if Mob.Stats.Died then return end
if not Player then return end
if PlayerRole.Stats.Died then return end
if AI:GetModelDistance(MobInstance, Player.Character) <= 5 then
-- 调用伤害模块
DamageProxy:TakeDamage(Mob, Mob.PlayerRole, {
@ -99,6 +102,7 @@ task.defer(function()
}
})
end
Mob.ExecutingState = false
end
end
else

View File

@ -62,6 +62,7 @@ function Mob.new(Player: Player, MobId: number, OnMobDied: ((Player: Player, Mob
setmetatable(self, Mob) -- 继承Mob方法
local PlayerFightProxy = require(ServerStorage.Proxy.PlayerFightProxy)
self.PlayerRole = PlayerFightProxy:GetPlayerRole(Player)
self.ExecutingState = false
-- 放入关卡中
newMobModel.Parent = playerMobsFolder
@ -80,9 +81,11 @@ function Mob.new(Player: Player, MobId: number, OnMobDied: ((Player: Player, Mob
return self
end
function Mob:Died()
function Mob:Died(IsSkinOnDied: boolean?)
MobsProxy:RemoveMob(self.Player, self.Instance)
if self.OnDied then self.OnDied(self.Player, self) end
if not IsSkinOnDied then
if self.OnDied then self.OnDied(self.Player, self) end
end
Character.Died(self)
end
@ -93,8 +96,8 @@ function MobsProxy:CreateMob(Player: Player, MobId: number, AtkBonus: number?, H
local Mob = Mob.new(Player, MobId, OnMobDied)
AI:StartTracking(Mob)
-- 关卡系数
-- if AtkBonus then Mob:ChangeAttributeValue("attack", math.floor(Mob.Config.attack * (AtkBonus / 1000))) end
-- if HpBonus then Mob:ChangeAttributeValue("hp", math.floor(Mob.Config.hp * (HpBonus / 1000))) end
if AtkBonus then Mob:ChangeAttributeValue("attack", math.floor(Mob.Config.attack * (AtkBonus / 1000))) end
if HpBonus then Mob:ChangeAttributeValue("hp", math.floor(Mob.Config.hp * (HpBonus / 1000))) end
MobsProxy.pData[Player.UserId][Mob.Instance] = Mob
return Mob
end

View File

@ -20,12 +20,12 @@ local JsonLevel = require(ReplicatedStorage.Json.Level)
local LevelLoop = {}
LevelLoop.__index = LevelLoop
function LevelLoop.new(Player: Player, Character: TypeList.Character)
function LevelLoop.new(Player: Player, PlayerRole: TypeList.Character)
print("LevelLoop:Init")
local self = {}
setmetatable(self, LevelLoop)
self.Player = Player
self.Character = Character
self.PlayerRole = PlayerRole
self.TaskAutoChallenge = nil
self.ConChallengeEnd = BD_ChallengeEnd.Event:Connect(function(Player: Player, LevelId: number)
@ -38,7 +38,9 @@ function LevelLoop.new(Player: Player, Character: TypeList.Character)
end
function LevelLoop:AutoChallenge()
print("AutoChallenge")
-- 重置玩家状态(先临时调用角色复活,之后复杂的内容再说)
self.PlayerRole:Respawn()
local LevelFolder = game.Workspace:WaitForChild("Level"):WaitForChild(self.Player.UserId)
local ProgressFolder = LevelFolder:FindFirstChild("Progress")
@ -51,7 +53,7 @@ function LevelLoop:AutoChallenge()
LevelProxy:ChallengeLevel(self.Player, LevelId)
end
function LevelLoop:OnChallengeEnd(Player: Player, LevelId: number)
function LevelLoop:OnChallengeEnd(Player: Player, LevelId: number, result: boolean)
self.TaskAutoChallenge = task.defer(function()
task.wait(3)
self:AutoChallenge()

View File

@ -5,10 +5,14 @@ PlayerAI.__index = PlayerAI
--> Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--> Dependencies
local TypeList = require(ServerStorage.Base.TypeList)
--> Events
local RE_PlayerAI = ReplicatedStorage.Events.RE_PlayerAI
--> Variables
local DamageProxy = require(ServerStorage.Proxy.DamageProxy)
local ActivePlayers = {}
@ -42,14 +46,21 @@ function PlayerAI.new(Player: Player, PlayerRole: TypeList.Character)
self.Character = PlayerRole
self.Player = Player
self.ExecutingState = false
self.PlayerControling = false
self.BehaviourList = {}
self.LoopTask = task.spawn(function()
while task.wait(0.25) do
if self.Character.Stats.Died then continue end
if self.PlayerControling then continue end
self:Update()
end
end)
self.PlayerControlCon = RE_PlayerAI.OnServerEvent:Connect(function(Player: Player, ControlState: boolean)
if Player ~= self.Player then return end
self.PlayerControling = ControlState
end)
return self
end

View File

@ -48,11 +48,13 @@ end
function PlayerRole:Died()
self:ChangeState("Died", true)
self.Humanoid.WalkSpeed = 0
LevelProxy:ChallengeEnd(self.Player, false)
end
function PlayerRole:Respawn()
self:ChangeState("Died", false)
self.Humanoid.WalkSpeed = self.Config.walkSpeed
self:ChangeAttributeValue("hp", self.Config.maxhp)
-- 重置玩家位置

View File

@ -12,6 +12,11 @@ local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
--> Json
local JsonPlayerLv = require(ReplicatedStorage.Json.PlayerLv)
local JsonItem = require(ReplicatedStorage.Json.ItemProp)
local JsonAttributesUpgrade = require(ReplicatedStorage.Json.AttributesUpgrade)
--> Events
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes
--> Constants
local STORE_NAME = "PlayerInfo"
@ -34,7 +39,7 @@ local function GetPlayerInfoFolder(Player: Player)
end
-- 创建玩家信息实例
local function CreateInfoInstance(Player: Player, Folder: any, StateKey: string, StateType: string, StateValue: any)
local function CreateInfoInstance(Player: Player, Folder: any, StateKey: string, StateType: string, StateValue: any?)
if not Player and not Folder and not StateKey and not StateType then
warn('创建玩家信息实例失败: ' , Player.Name, Folder.Name, StateKey, StateType, StateValue)
return
@ -81,21 +86,83 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
local PlayerInfoFolder = Utils:CreateFolder("PlayerInfo", pData)
local StatsFolder = Utils:CreateFolder("Stats", PlayerInfoFolder)
local ItemsFolder = Utils:CreateFolder("Items", PlayerInfoFolder)
local AttributesUpgradeFolder = Utils:CreateFolder("AttributesUpgrade", PlayerInfoFolder)
-- 新玩家数据初始化
if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then
ArchiveProxy.pData[Player.UserId][STORE_NAME] = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Items = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade = {}
end
-- 放在外面是为了以后系统新增内容方便(同时不用在初始化数据是做写入了)
ExtraAddPlayerStats(Player, ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats)
-- 创建玩家信息实例
for ItemId, ItemValue in ArchiveProxy.pData[Player.UserId][STORE_NAME].Items do
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)
end
for AttributeId, AttributeLv in ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade do
CreateInfoInstance(Player, AttributesUpgradeFolder, AttributeId, "NumberValue", AttributeLv)
end
end
-- 玩家属性升级
function PlayerInfoProxy:UpgradeAttribute(Player: Player, AttributeId: number)
if not Player or not AttributeId then warn('升级属性失败: ', Player.Name, AttributeId) return end
local AttributesUpgradeFolder = GetPlayerInfoFolder(Player):FindFirstChild("AttributesUpgrade")
local upgradeTable = ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade
local nowLv = upgradeTable[AttributeId]
if nowLv == nil then nowLv = 0 end
local attributeData = Utils:GetIdDataFromJson(JsonAttributesUpgrade, AttributeId)
local requireBattleValue, requireMoney
if nowLv == 0 then
requireMoney = attributeData["cost"][2]
requireBattleValue = attributeData["battleValueLimit"][1]
else
requireMoney = attributeData["cost"][2] + (nowLv - 1) * attributeData["cost"][3]
requireBattleValue = attributeData["battleValueLimit"][1] + (nowLv - 1) * attributeData["battleValueLimit"][2]
end
-- TODO 判断战力是否足够(暂无战力计算)
-- 判断是否到达等级上限
print(nowLv, attributeData["maxLv"])
if attributeData["maxLv"] ~= nil then
if nowLv >= attributeData["maxLv"] then
local tip = '升级属性失败: ' .. AttributeId .. ' 已到达等级上限'
RE_PlayerTip:FireClient(Player, tip)
return
end
end
-- 判断钱是否足够
if not self:HasEnoughItem(Player, attributeData["cost"][1], requireMoney) then
local tip = '升级属性失败: ' .. AttributeId .. ' 钱不够'
RE_PlayerTip:FireClient(Player, tip)
return
end
-- 扣钱
self:ChangeItemCount(Player, 1, -requireMoney)
-- 升级
if nowLv == 0 then
-- 首次生成属性
upgradeTable[AttributeId] = 1
CreateInfoInstance(Player, AttributesUpgradeFolder, AttributeId, "NumberValue", upgradeTable[AttributeId])
else
-- 更新属性显示
upgradeTable[AttributeId] = nowLv + 1
ChangeInfoInstance(Player, AttributesUpgradeFolder, AttributeId, upgradeTable[AttributeId])
end
end
-- 添加经验
@ -161,6 +228,29 @@ function PlayerInfoProxy:GetItemCount(Player: Player, ItemId: number)
return playerInfoData[ItemId]
end
--------------------------------------------------------------------------------
-- 获取升级加点属性
function PlayerInfoProxy:GetPlayerUpgradeAttributes(Player: Player)
if not Player then warn('获取玩家属性失败: ', Player.Name) return end
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME]
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]
end
return attributes
end
-- 获取玩家属性
function PlayerInfoProxy:GetPlayerAttributes(Player: Player)
local attributesList = {}
attributesList.UpgradeAttributes = self:GetPlayerUpgradeAttributes(Player)
return attributesList
end
--------------------------------------------------------------------------------
function PlayerInfoProxy:OnPlayerRemoving(Player: Player)
end
@ -169,4 +259,9 @@ ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(Player: Player)
PlayerInfoProxy:OnPlayerRemoving(Player)
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

View File

@ -0,0 +1,32 @@
local Helper = {}
--> Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--> Events
local RE_PlayerHelper = ReplicatedStorage.Events.RE_PlayerHelper
local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
if input.KeyCode == Enum.KeyCode.H then
RE_PlayerHelper:FireServer("CleanPlayerData")
elseif input.KeyCode == Enum.KeyCode.J then
print("添加物品")
RE_PlayerHelper:FireServer("AddItem", {1, 100})
elseif input.KeyCode == Enum.KeyCode.K then
RE_UpgradeAttributes:FireServer(1)
elseif input.KeyCode == Enum.KeyCode.L then
RE_UpgradeAttributes:FireServer(2)
elseif input.KeyCode == Enum.KeyCode.M then
RE_UpgradeAttributes:FireServer(3)
elseif input.KeyCode == Enum.KeyCode.N then
RE_UpgradeAttributes:FireServer(4)
end
end
end)
return Helper

View File

@ -0,0 +1,31 @@
local UserInputService = game:GetService("UserInputService")
local PlayerControl = {}
-- 监听按键按下
function PlayerControl.ListenMoveKeyDown(onKeyDown)
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
local key = input.KeyCode
if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
onKeyDown(key)
end
end
end)
end
-- 监听按键松开
function PlayerControl.ListenMoveKeyUp(onKeyUp)
UserInputService.InputEnded:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
local key = input.KeyCode
if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
onKeyUp(key)
end
end
end)
end
return PlayerControl

View File

@ -19,6 +19,11 @@ local PlayerGui = Player:WaitForChild("PlayerGui")
local FormatNumber = require(ReplicatedStorage.Modules.FormatNumber)
local Tween = require(ReplicatedStorage.Modules.Tween)
local SFX = require(ReplicatedStorage.Modules.SFX)
local PlayerControl = require(script.PlayerControl)
local Helper = require(script.Helper)
--> Events
local RE_PlayerAI = ReplicatedStorage.Events.RE_PlayerAI
--> Variables
local Random = Random.new()
@ -28,6 +33,16 @@ local ClientMainPrefabs = Player.PlayerScripts.ClientMainPrefabs
--------------------------------------------------------------------------------
PlayerControl.ListenMoveKeyDown(function(key)
-- print("按下了: ", key.Name)
RE_PlayerAI:FireServer(true)
end)
PlayerControl.ListenMoveKeyUp(function(key)
-- print("松开了: ", key.Name)
RE_PlayerAI:FireServer(false)
end)
-- Initially require client-sided modules
for _, Item in script:GetChildren() do
if Item:IsA("ModuleScript") then