2025-07-07 23:52:31 +08:00
|
|
|
|
-- 玩家循环代理
|
|
|
|
|
local PlayerFightProxy = {}
|
|
|
|
|
|
|
|
|
|
--> Services
|
|
|
|
|
local Players = game:GetService("Players")
|
|
|
|
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
|
|
|
local ServerStorage = game:GetService("ServerStorage")
|
|
|
|
|
|
|
|
|
|
--> Variables
|
|
|
|
|
local Character = require(ServerStorage.Base.Character)
|
|
|
|
|
local Utils = require(ReplicatedStorage.Tools.Utils)
|
|
|
|
|
local LevelProxy = require(ServerStorage.Proxy.LevelProxy)
|
|
|
|
|
|
|
|
|
|
--> Json
|
|
|
|
|
local JsonCharacter = require(ReplicatedStorage.Json.Character)
|
2025-07-15 01:12:05 +08:00
|
|
|
|
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
2025-07-07 23:52:31 +08:00
|
|
|
|
|
|
|
|
|
--> Dependencies
|
|
|
|
|
local LevelLoop = require(script.LevelLoop)
|
|
|
|
|
local PlayerAI = require(script.PlayerAI)
|
2025-07-12 05:06:14 +08:00
|
|
|
|
local Communicate = require(ServerStorage.Modules.Tools.Communicate)
|
|
|
|
|
|
|
|
|
|
--> Events
|
|
|
|
|
local RE_CleanPlayerPerformance = ReplicatedStorage.Events.RE_CleanPlayerPerformance
|
2025-07-16 00:45:20 +08:00
|
|
|
|
local RE_AbilityPerformance = ReplicatedStorage.Events.RE_AbilityPerformance
|
2025-07-07 23:52:31 +08:00
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
local function WaitForCharacter(Player: Player)
|
|
|
|
|
while not Player.Character or not Player.Character.Parent do
|
|
|
|
|
Player.CharacterAdded:Wait()
|
|
|
|
|
end
|
|
|
|
|
return Player.Character
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
local PlayerRole = {}
|
2025-07-09 02:01:45 +08:00
|
|
|
|
PlayerRole.__index = PlayerRole
|
|
|
|
|
setmetatable(PlayerRole, {__index = Character})
|
2025-07-07 23:52:31 +08:00
|
|
|
|
|
|
|
|
|
function PlayerRole.new(Player: Player, CharacterId: number)
|
|
|
|
|
local playerCharacter = WaitForCharacter(Player)
|
|
|
|
|
|
2025-07-15 01:12:05 +08:00
|
|
|
|
-- 获取玩家初始数据(临时初始化使用,不是真属性配置部分)
|
2025-07-07 23:52:31 +08:00
|
|
|
|
local CharacterData = Utils:GetIdDataFromJson(JsonCharacter, CharacterId)
|
|
|
|
|
if not CharacterData then warn("CharacterId Data not found", CharacterId) return end
|
|
|
|
|
|
2025-07-15 01:12:05 +08:00
|
|
|
|
-- 补充默认没设置的属性,暂时不添加特殊属性,因为特殊属性是系统调用的,添加也没啥用
|
|
|
|
|
for _, AttributeData in JsonCharacter do
|
|
|
|
|
if AttributeData.id < 50 then
|
|
|
|
|
if not CharacterData[AttributeData.name] then CharacterData[AttributeData.name] = 0 end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2025-07-07 23:52:31 +08:00
|
|
|
|
-- 调用父类Character的new方法,初始化通用属性
|
|
|
|
|
local self = Character.new(Player, playerCharacter, CharacterData)
|
|
|
|
|
setmetatable(self, PlayerRole)
|
2025-07-12 05:06:14 +08:00
|
|
|
|
|
2025-07-15 01:12:05 +08:00
|
|
|
|
self.CharacterId = CharacterId
|
|
|
|
|
|
2025-07-12 05:06:14 +08:00
|
|
|
|
-- 玩家放到Character目录下
|
|
|
|
|
playerCharacter.Parent = game.Workspace.Characters
|
2025-07-07 23:52:31 +08:00
|
|
|
|
return self
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PlayerRole:Died()
|
|
|
|
|
self:ChangeState("Died", true)
|
2025-07-09 23:59:56 +08:00
|
|
|
|
self.Humanoid.WalkSpeed = 0
|
2025-07-07 23:52:31 +08:00
|
|
|
|
LevelProxy:ChallengeEnd(self.Player, false)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PlayerRole:Respawn()
|
|
|
|
|
self:ChangeState("Died", false)
|
2025-07-09 23:59:56 +08:00
|
|
|
|
self.Humanoid.WalkSpeed = self.Config.walkSpeed
|
2025-07-09 02:01:45 +08:00
|
|
|
|
self:ChangeAttributeValue("hp", self.Config.maxhp)
|
2025-07-15 01:12:05 +08:00
|
|
|
|
-- TODO: 重置玩家位置
|
2025-07-07 23:52:31 +08:00
|
|
|
|
|
2025-07-15 01:12:05 +08:00
|
|
|
|
PlayerFightProxy:UpdatePlayerFightData(self.Player)
|
2025-07-07 23:52:31 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
function PlayerFightProxy:InitPlayer(Player: Player)
|
|
|
|
|
if not PlayerFightProxy.pData then PlayerFightProxy.pData = {} end
|
|
|
|
|
if not PlayerFightProxy.pData[Player.UserId] then
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId] = {}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 生成玩家状态
|
|
|
|
|
local PlayerRole = PlayerRole.new(Player, 1)
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerRole = PlayerRole
|
|
|
|
|
|
|
|
|
|
-- 生成关卡循环
|
|
|
|
|
local LevelLoop = LevelLoop.new(Player, PlayerRole)
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].LevelLoop = LevelLoop
|
|
|
|
|
|
|
|
|
|
-- 生成玩家AI
|
|
|
|
|
local PlayerAI = PlayerAI.new(Player, PlayerRole)
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI = PlayerAI
|
2025-07-15 01:12:05 +08:00
|
|
|
|
|
|
|
|
|
-- 更新玩家战斗数据
|
|
|
|
|
self:UpdatePlayerFightData(Player)
|
2025-07-07 23:52:31 +08:00
|
|
|
|
end
|
|
|
|
|
|
2025-07-09 02:01:45 +08:00
|
|
|
|
function PlayerFightProxy:GetPlayerRole(Player: Player)
|
|
|
|
|
return PlayerFightProxy.pData[Player.UserId].PlayerRole
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PlayerFightProxy:GetPlayerAI(Player: Player)
|
|
|
|
|
return PlayerFightProxy.pData[Player.UserId].PlayerAI
|
|
|
|
|
end
|
2025-07-07 23:52:31 +08:00
|
|
|
|
|
2025-07-15 01:12:05 +08:00
|
|
|
|
-- 更新玩家战斗数据(所有变动全部从这调用)
|
|
|
|
|
function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
|
|
|
|
|
local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy)
|
|
|
|
|
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
|
|
|
|
|
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
|
|
|
|
|
local GemProxy = require(ServerStorage.Proxy.GemProxy)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local AttributesData = {}
|
|
|
|
|
|
|
|
|
|
-- 计算角色基础属性值 + 装备属性值 + 宝石属性值,赋值属性
|
|
|
|
|
local PlayerInfoAttributes = PlayerInfoProxy:GetPlayerAttributes(Player)
|
|
|
|
|
AttributesData = Utils:MergeTable(AttributesData, PlayerInfoAttributes)
|
|
|
|
|
|
|
|
|
|
local EquipmentAttributes = EquipmentProxy:GetPlayerAttributes(Player)
|
|
|
|
|
AttributesData = Utils:MergeTable(AttributesData, EquipmentAttributes)
|
|
|
|
|
|
|
|
|
|
local GemAttributes = GemProxy:GetPlayerAttributes(Player)
|
|
|
|
|
AttributesData = Utils:MergeTable(AttributesData, GemAttributes)
|
|
|
|
|
|
|
|
|
|
-- 角色基础数据
|
|
|
|
|
local PlayerRole = self:GetPlayerRole(Player)
|
|
|
|
|
local CharacterData = Utils:GetIdDataFromJson(JsonCharacter, PlayerRole.CharacterId)
|
|
|
|
|
if not CharacterData then warn("CharacterId Data not found", PlayerRole.CharacterId) return end
|
|
|
|
|
-- 如果玩家装备的武器里面有了攻击速度属性,就不用默认的攻击属性进行配置
|
|
|
|
|
local ExceptAttributes = {"id", "name"}
|
|
|
|
|
if AttributesData.atkSpeed then table.insert(ExceptAttributes, "atkSpeed") end
|
|
|
|
|
|
|
|
|
|
for AttributeName, AttributeValue in CharacterData do
|
|
|
|
|
if not table.find(ExceptAttributes, AttributeName) then
|
|
|
|
|
Utils:TableSafeAddValue(AttributesData, AttributeName, AttributeValue)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 根据汇总更新玩家属性——————实际生效计算部分
|
|
|
|
|
local PlayerRole = self:GetPlayerRole(Player)
|
|
|
|
|
|
|
|
|
|
-- 针对百分比特殊属性直接进行计算修改
|
|
|
|
|
if AttributesData["hpRate"] then
|
|
|
|
|
AttributesData["hp"] = math.floor(AttributesData["hp"] * AttributesData["hpRate"] / 100)
|
|
|
|
|
end
|
|
|
|
|
if AttributesData["atkRate"] then
|
|
|
|
|
AttributesData["atk"] = math.floor(AttributesData["atk"] * AttributesData["atkRate"] / 100)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 更新玩家属性
|
|
|
|
|
for AttributeName, AttributeValue in AttributesData do
|
|
|
|
|
-- TODO:这里可能涉及到战斗时更换装备的属性处理,还需要再函数内部再根据剩余百分比数值变化
|
|
|
|
|
PlayerRole:ChangeAttributeValue(AttributeName, AttributeValue)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 根据技能添加玩家AI行为
|
|
|
|
|
local abilityIdList, behaviourNameList = AbilityProxy:GetPlayerWearingAbilityData(Player)
|
|
|
|
|
local playerAI = PlayerFightProxy:GetPlayerAI(Player)
|
|
|
|
|
|
|
|
|
|
-- TODO:设置AI行为(临时清除所有行为,添加新的玩家行为)
|
|
|
|
|
playerAI:ClearAllBehaviour()
|
|
|
|
|
for _, behaviourName in behaviourNameList do
|
|
|
|
|
playerAI:AddBehaviour(behaviourName)
|
|
|
|
|
end
|
|
|
|
|
playerAI:AddBehaviour("Move")
|
|
|
|
|
playerAI:AddBehaviour("SwordWave")
|
2025-07-16 00:45:20 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- 给前端发送技能信息
|
|
|
|
|
Communicate:SendToClient(RE_AbilityPerformance, "Ability", Player, playerAI:GetClientBehaviourList())
|
2025-07-15 01:12:05 +08:00
|
|
|
|
end
|
|
|
|
|
|
2025-07-07 23:52:31 +08:00
|
|
|
|
-- 重置玩家状态,但是不删除
|
|
|
|
|
function PlayerFightProxy:CleanPlayer(Player: Player)
|
|
|
|
|
-- 玩家角色重生
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerRole:Respawn()
|
|
|
|
|
-- AI重新生成
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI:Destroy()
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI = nil
|
|
|
|
|
|
|
|
|
|
local PlayerAI = PlayerAI.new(PlayerRole)
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI = PlayerAI
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PlayerFightProxy:OnPlayerRemoving(Player: Player)
|
2025-07-12 05:06:14 +08:00
|
|
|
|
-- 玩家离开时,通知其他客户端销毁玩家表现内容
|
|
|
|
|
Communicate:SendToClientFree(RE_CleanPlayerPerformance, Player)
|
|
|
|
|
-- 正常清除玩家该模块下数据
|
2025-07-07 23:52:31 +08:00
|
|
|
|
if not PlayerFightProxy.pData[Player.UserId] then warn("PlayerFight Remove Data not found", Player.Name) return end
|
2025-07-18 01:11:49 +08:00
|
|
|
|
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI:Destroy()
|
|
|
|
|
PlayerFightProxy.pData[Player.UserId].PlayerAI = nil
|
|
|
|
|
|
2025-07-07 23:52:31 +08:00
|
|
|
|
PlayerFightProxy.pData[Player.UserId] = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Players.PlayerRemoving:Connect(function(Player: Player)
|
|
|
|
|
PlayerFightProxy:OnPlayerRemoving(Player)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
return PlayerFightProxy
|