2025-07-23 01:04:27 +08:00

217 lines
8.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 玩家循环代理
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