217 lines
8.1 KiB
Plaintext
217 lines
8.1 KiB
Plaintext
-- 玩家循环代理
|
||
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)
|
||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||
|
||
--> Dependencies
|
||
local LevelLoop = require(script.LevelLoop)
|
||
local PlayerAI = require(script.PlayerAI)
|
||
local Communicate = require(ServerStorage.Modules.Tools.Communicate)
|
||
|
||
--> Events
|
||
local RE_CleanPlayerPerformance = ReplicatedStorage.Events.RE_CleanPlayerPerformance
|
||
local RE_AbilityPerformance = ReplicatedStorage.Events.RE_AbilityPerformance
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
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 = {}
|
||
PlayerRole.__index = PlayerRole
|
||
setmetatable(PlayerRole, {__index = Character})
|
||
|
||
function PlayerRole.new(Player: Player, CharacterId: number)
|
||
local playerCharacter = WaitForCharacter(Player)
|
||
|
||
-- 获取玩家初始数据(临时初始化使用,不是真属性配置部分)
|
||
local CharacterData = Utils:GetIdDataFromJson(JsonCharacter, CharacterId)
|
||
if not CharacterData then warn("CharacterId Data not found", CharacterId) return end
|
||
|
||
-- 补充默认没设置的属性,暂时不添加特殊属性,因为特殊属性是系统调用的,添加也没啥用
|
||
for _, AttributeData in JsonCharacter do
|
||
if AttributeData.id < 50 then
|
||
if not CharacterData[AttributeData.name] then CharacterData[AttributeData.name] = 0 end
|
||
end
|
||
end
|
||
|
||
|
||
-- 调用父类Character的new方法,初始化通用属性
|
||
local self = Character.new(Player, playerCharacter, CharacterData)
|
||
setmetatable(self, PlayerRole)
|
||
|
||
self.CharacterId = CharacterId
|
||
|
||
-- 玩家放到Character目录下
|
||
playerCharacter.Parent = game.Workspace.Characters
|
||
return self
|
||
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)
|
||
-- TODO: 重置玩家位置
|
||
|
||
PlayerFightProxy:UpdatePlayerFightData(self.Player)
|
||
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
|
||
|
||
-- 更新玩家战斗数据
|
||
self:UpdatePlayerFightData(Player)
|
||
end
|
||
|
||
function PlayerFightProxy:GetPlayerRole(Player: Player)
|
||
return PlayerFightProxy.pData[Player.UserId].PlayerRole
|
||
end
|
||
|
||
function PlayerFightProxy:GetPlayerAI(Player: Player)
|
||
return PlayerFightProxy.pData[Player.UserId].PlayerAI
|
||
end
|
||
|
||
-- 更新玩家战斗数据(所有变动全部从这调用)
|
||
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)
|
||
if PlayerInfoAttributes.UpgradeAttributes then
|
||
Utils:TableSafeAddTableValue(AttributesData, PlayerInfoAttributes.UpgradeAttributes)
|
||
end
|
||
|
||
local EquipmentAttributes = EquipmentProxy:GetPlayerAttributes(Player)
|
||
if EquipmentAttributes then
|
||
Utils:TableSafeAddTableValue(AttributesData, EquipmentAttributes)
|
||
end
|
||
|
||
local GemAttributes = GemProxy:GetPlayerAttributes(Player)
|
||
if GemAttributes.GemWearingAttributes then
|
||
Utils:TableSafeAddTableValue(AttributesData, GemAttributes.GemWearingAttributes)
|
||
end
|
||
|
||
-- 角色基础数据
|
||
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")
|
||
|
||
|
||
-- 给前端发送技能信息
|
||
Communicate:SendToClient(RE_AbilityPerformance, "Ability", Player, playerAI:GetClientBehaviourList())
|
||
end
|
||
|
||
-- 重置玩家状态,但是不删除
|
||
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)
|
||
-- 玩家离开时,通知其他客户端销毁玩家表现内容
|
||
Communicate:SendToClientFree(RE_CleanPlayerPerformance, Player)
|
||
-- 正常清除玩家该模块下数据
|
||
if not PlayerFightProxy.pData[Player.UserId] then warn("PlayerFight Remove Data not found", Player.Name) return end
|
||
|
||
PlayerFightProxy.pData[Player.UserId].PlayerAI:Destroy()
|
||
PlayerFightProxy.pData[Player.UserId].PlayerAI = nil
|
||
|
||
PlayerFightProxy.pData[Player.UserId] = nil
|
||
end
|
||
|
||
Players.PlayerRemoving:Connect(function(Player: Player)
|
||
PlayerFightProxy:OnPlayerRemoving(Player)
|
||
end)
|
||
|
||
return PlayerFightProxy |