2025-01-04 23:00:19 +08:00

762 lines
26 KiB
Lua
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.

---@type FMiniGameManager
local MiniGameManager = {};
---@private string 这是玩家选择的地图,按从前往后开始游玩
MiniGameManager.ScriptPath = "Script.Blueprint.Mini.Script.Mini_";
---@type table<int32, FMiniGameMapIndex> 当前所有玩家选择的地图
MiniGameManager.SelectMaps = {};
---@type FMiniGameMapIndex 当前选择的地图
MiniGameManager.CurrSelectMap = nil;
---@type UGCGameState_C 默认是 GameSate如果不是可以在具体实例里面实现对应方法
MiniGameManager.Owner = nil;
---@type table<any> 游戏配置,对应着 MiniGameConfig[self.CurrSelectMap]
MiniGameManager.GameConfig = nil;
---@type MiniGameMode 当前小玩法的具体实现,统一入口出口管理
MiniGameManager.CurrMiniMode = nil;
---@type int32 目标小游戏数量,低于这个数量会自动添加到这个数量
MiniGameManager.TargetMiniGameCount = 1;
---@type MiniGameState 模式状态,可以在本实例和 CurrMiniMode 中获取
MiniGameManager.State = 0;
---@type table<PlayerKey, MiniGamePlayerDataItem> 玩家数据
MiniGameManager.PlayerData = {};
---@type table<int32, any> 小游戏需要同步的数据,会自动执行 OnRep_xxx 函数
MiniGameManager.MiniInfo = {};
----------------------------------- 主要函数 -----------------------------------
--- 这是游戏启动,做一些初始化的操作即可
function MiniGameManager:ReceiveBeginPlay(InOwner)
UGCLogSystem.Log("[MiniGameManager:ReceiveBeginPlay] 执行成功 self = %s", tostring(self));
self.Owner = InOwner;
self.GameConfig = require('Script.Blueprint.Mini.MiniGameConfig')
GlobalTickTool:AddTick(self, self.OnTick);
UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self)
if IsServer then
self:SetState(MiniGameState.SELECT_GAMES);
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
o:OnMiniGameTimeCount(t);
end, 1, MiniGameTimes.Active, self.OnGameStart);
else
-- 执行客户端逻辑
self:MakeCachedMiniInfo();
end
-- 组装一下具体函数
self:MakeRepProps();
end
function MiniGameManager:OnTick(InDeltaTime, InServerTime)
end
function MiniGameManager:MakeRepProps()
local Func = function(...) return { ... }; end
local Props = Func(self:GetReplicatedProperties());
if self.Props == nil then self.Props = {}; end
for i, v in pairs(Props) do
self.Props[v] = true;
end
UGCLogSystem.LogTree(string.format("[MiniGameManager:MakeRepProps] self.Props ="), self.Props);
end
function MiniGameManager:IsRepProp(InName)
return self.Props[InName] == true;
end
--- 本身需要同步的数据放进来
function MiniGameManager:GetReplicatedProperties()
return "State"
, "SelectMaps"
, "CurrSelectMap"
end
--- 客户端准备好了,此时开始有 ServerTime
function MiniGameManager:OnClientAlready()
-- 显示
if IsClient then
UGCLogSystem.Log("[MiniGameManager:OnGameBegin] 显示 UI")
--WidgetManager:ShowPanel(WidgetConfig.EUIType.SelectMap, false);
end
end
--- 可以改变任意时刻的时间
function MiniGameManager:ChangeTime(InTime)
GlobalTickTool:UpdateInternalCount(self, InTime);
end
--- 准备结束
function MiniGameManager:OnPrepareEnd()
if IsServer then
self:SetMiniInfo();
end
table.func(self.CurrMiniMode, "OnPrepareEnd")
self:OnMiniRoundPrepare();
end
function MiniGameManager:SendRPC(InRPCName, ...)
UGCLogSystem.Log("[MiniGameManager:SendRPC] InRPCName = %s", InRPCName);
self.Owner:SendMiniGameRPC(InRPCName, ...);
end
--- 当游戏激活之时
function MiniGameManager:OnGameActive()
-- 这个函数几乎是紧挨着 ReceiveBeginPlay 之后执行
end
--- 在游戏进行之前执行
---@param InTime int32 从游戏开始到游戏正式开始的倒计时
function MiniGameManager:OnBeforeGameStart(InTime)
UGCLogSystem.Log("[MiniGameManager:OnBeforeGameStart] InTime = %s", tostring(InTime));
if InTime == 2 then
-- 玩家死亡重生
GameState:BeforeReset(InTime);
end
end
--- 游戏正式开始
function MiniGameManager:OnGameStart()
UGCLogSystem.Log("[MiniGameManager:OnGameStart] 执行")
if IsServer then
-- 检查当前选择的地图是否小于对应数量,如果小于,那么就随机选择为选择的
-- 获取选择了的
if table.getCount(MiniGameConfig) == 1 then
for i, v in pairs(MiniGameConfig) do
table.insert(self.SelectMaps, i);
end
else
local SortTable = self.Owner:SortMapData();
for i, v in pairs(SortTable) do table.insert(self.SelectMaps, v.Index); end
end
local NeedCount = self.TargetMiniGameCount - table.getCount(self.SelectMaps);
if NeedCount > 0 then
for i = 1, NeedCount do table.insert(self.SelectMaps, math.random(table.getCount(MiniGameConfig))) end
end
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnGameStart] self.SelectMaps ="), self.SelectMaps)
-- 表示如果第一个加载不成,那么就依次完后加载,直到全部加载都不行
local bSuccess = false;
repeat bSuccess = self:LoadMiniGame() until bSuccess or table.isEmpty(self.SelectMaps);
if not bSuccess then self:OnGameEnd(); end
else
WidgetManager:ClosePanel(WidgetConfig.EUIType.SelectMap);
WidgetManager:ShowPanel(WidgetConfig.EUIType.Main, false);
end
end
function MiniGameManager:OnGameEnd()
UGCLogSystem.Log("[MiniGameManager:OnGameEnd] 游戏结束")
if IsServer then
self:SetState(MiniGameState.ENDED);
LuaQuickFireEvent("GameEnd", self.Owner);
else
-- 显示结算界面
WidgetManager:ShowPanel(WidgetConfig.EUIType.GameEnd, false);
end
end
---@param InMiniType MiniGameMapType Mini 游戏类型,只会在客户端存在
function MiniGameManager:LoadMiniGame(InMiniType)
if IsServer then
self:SetState(MiniGameState.MINI_PREPARE);
--LuaQuickFireEvent("AllPlayerReset", self.Owner);
self:AllPlayerRespawn();
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] 执行")
if table.isEmpty(self.SelectMaps) then return false; end
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] 开始执行流程")
self.CurrSelectMap = self.SelectMaps[1];
if self.CurrSelectMap == nil then return false; end
table.remove(self.SelectMaps, 1);
-- 加载 CurrMiniMode
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] 加载 Mini Mode")
self.CurrMiniMode = require(self.ScriptPath .. self.GameConfig[self.CurrSelectMap].Script);
if self.CurrMiniMode == nil then return false; end
if not table.func(self.CurrMiniMode, "Init", self, table.unpackTable(self.GameConfig[self.CurrSelectMap].Params)) then return false; end
GlobalMiniMode = self.CurrMiniMode;
self:LoadMap(self.CurrSelectMap);
-- 发送到客户端表示当前已经同步了
self.Owner:SelectMiniType(self.CurrSelectMap);
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] Mini Mode 加载成功")
self:CurrMiniModeInit();
if self.CurrMiniMode.RoundTimes == nil then self.CurrMiniMode.RoundTimes = 1; end
self:SetRoundTimes(self.CurrMiniMode.RoundTimes);
-- 这个是玩法的小局准备
local Times = self.GameConfig[self.CurrSelectMap].MiniGameTimes
local Time = 0;
if Times ~= nil and Times.Prepare ~= nil then
Time = Times.Prepare;
else
Time = MiniGameTimes.Prepare;
end
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] Time = %s", tostring(Time))
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] Time Internal = %s", tostring(t));
o:OnMiniGameTimeCount(t);
end, 1, Time, self.OnPrepareEnd);
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] 全部加载完成")
return true;
else
UGCLogSystem.Log("[MiniGameManager:LoadMiniGame] 客户端加载")
self.CurrSelectMap = InMiniType;
self.CurrMiniMode = require(self.ScriptPath .. self.GameConfig[self.CurrSelectMap].Script);
if self.CurrMiniMode == nil then return; end
table.func(self.CurrMiniMode, "Init", self, table.unpackTable(self.GameConfig[self.CurrSelectMap].Params))
self:CurrMiniModeInit();
end
end
--- 服务器客户端初始化的共同操作
function MiniGameManager:CurrMiniModeInit()
--- 默认设置一些变量供使用或者驱动
self.CurrMiniMode.Owner = self;
self.CurrMiniMode.MapIndex = self.CurrSelectMap;
self.CurrMiniMode.CreateTime = UE.GetServerTime();
self.CurrMiniMode.bGameEnd = false;
self.CurrMiniMode.RoundTimes = self.GameConfig[self.CurrSelectMap].RoundTimes;
self.CurrMiniMode.bCanRespawn = self.GameConfig[self.CurrSelectMap].bCanRespawn; -- 是否可以重生
for i, v in pairs(self.MiniInfo) do
if type(v) == 'table' then
self.CurrMiniMode[i] = TableHelper.DeepCopyTable(v);
else
self.CurrMiniMode[i] = v;
end
end
UGCLogSystem.Log("[MiniGameManager:CurrMiniModeInit] 开始加载地图")
-- 加载 Tick
GlobalTickTool:AddTick(self.CurrMiniMode, self.CurrMiniMode.OnTick, 0, function(o)
return not (o.bEnableTick == false);
end);
-- 进入准备
table.func(self.CurrMiniMode, "OnPrepare");
end
function MiniGameManager:UnLoadMiniGame()
-- 先取消上一个的
if IsServer then
if self.CurrMiniMode ~= nil then
GlobalTickTool:RemoveAll(self.CurrMiniMode);
-- 然后赶紧除去地图并且加载
self:UnLoadMap();
end
end
end
function MiniGameManager:OnMiniGameTimeCount(InVal)
--UGCLogSystem.Log("[MiniGameManager:OnMiniGameTimeCount] InVal = %s", tostring(InVal));
if IsServer then
InVal = math.floor(InVal);
--- 执行
self.Owner:OnGameProgress_Tick(InVal);
end
end
function MiniGameManager:OnMiniGameEnd()
UGCLogSystem.Log("[MiniGameManager:OnMiniGameEnd] ")
local Times = self.GameConfig[self.CurrSelectMap].MiniGameTimes;
local Time = 0;
if Times and Times.MiniGameEnd then
Time = Times.MiniGameEnd;
else
Time = MiniGameTimes.MiniGameEnd;
end
-- 从小局中取出来
self.MiniInfo.Scores = table.func(self.CurrMiniMode, "GetScore")
table.func(self.CurrMiniMode, "OnGameEnd", self.MiniInfo.Scores);
self:SetMiniInfo();
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
o:OnMiniGameTimeCount(t);
end, 1, Time, self.OnMiniGameSwitch);
self:SetState(MiniGameState.MINI_END);
end
--- 切换到下一个 MiniGame
function MiniGameManager:OnMiniGameSwitch()
-- 检查是否还有下一个了
if table.isEmpty(self.SelectMaps) then
self:OnGameEnd();
return;
end
self:UnLoadMiniGame();
self:LoadMiniGame();
end
function MiniGameManager:SetState(InState)
if IsServer then
self.State = InState;
self.MiniInfo.State = InState;
UGCLogSystem.Log("[MiniGameManager:SetState] CurrState = %s", TableHelper.printEnum(MiniGameState, self.State));
self:SetMiniInfo();
table.func(self.CurrMiniMode, 'SetState', InState);
if self.CurrMiniMode ~= nil then
self.CurrMiniMode.State = InState;
end
end
end
function MiniGameManager:SetRoundTimes(InTimes)
if IsServer then
self.MiniInfo.RoundTimes = InTimes;
self:SetMiniInfo();
if self.CurrMiniMode ~= nil then
self.CurrMiniMode.RoundTimes = InTimes;
end
end
end
function MiniGameManager:OnRep_RoundTimes(InOld)
if self.CurrMiniMode ~= nil then
self.CurrMiniMode.RoundTimes = self.MiniInfo.RoundTimes;
end
end
function MiniGameManager:OnRep_State(InOld)
UGCLogSystem.Log("[MiniGameManager:OnRep_State] self.State = %s, StateName = %s", tostring(self.MiniInfo.State), TableHelper.printEnum(MiniGameState, self.State));
self.State = self.MiniInfo.State;
UGCEventSystem.SendEvent(EventTypes.MiniStateChange, self.State);
if self.State == MiniGameState.MINI_PREPARE then
elseif self.State == MiniGameState.ROUND_PREPARE then
self:OnPrepareEnd();
elseif self.State == MiniGameState.ROUND_GAMING then
self:OnMiniRoundFormalStart();
elseif self.State == MiniGameState.ROUND_END then
self:OnMiniRoundEnd();
elseif self.State == MiniGameState.MINI_END then
self:OnMiniGameEnd();
elseif self.State == MiniGameState.ENDED then
self:OnGameEnd();
end
end
--- 设置同步 MiniInfo,
function MiniGameManager:SetMiniInfo()
self.Owner:SetMiniInfo(self.MiniInfo);
end
--- 设置游戏数据
---@vararg
function MiniGameManager:SetGameInfo(InName, InInfo, ...)
UGCLogSystem.LogTree(string.format("[MiniGameManager:SetGameInfo] InInfo ="), InInfo)
self.MiniInfo[InName] = InInfo;
self:SetMiniInfo();
end
----------------------------------- 地图函数 -----------------------------------
MiniGameManager.CurrLoadMapName = nil;
--- 加载地图
function MiniGameManager:LoadMap(InIndex)
-- 检查当前是什么东西,如果是随机的话
local MapNames = MiniGameConfig[InIndex].Map.MapName;
local LoadMap = "";
if type(MapNames) == 'table' then
local Total = 0;
local Maps = {};
for Name, Rate in pairs(MapNames) do
if type(Name) == 'string' then
Total = Total + Rate;
table.insert(Maps, {
Name = Name,
Rate = Rate,
});
elseif type(Name) == 'int32' then
table.insert(Maps, {
Name = Rate,
Rate = 1,
})
end
end
local MapCount = table.getCount(Maps);
if Total == 0 then
-- 从这两个中随机一个
LoadMap = Maps[math.random(MapCount)].Name;
else
local RandomNum = math.pop() * Total;
for i = 1, table.getCount(Maps) do
RandomNum = RandomNum - Maps[i].Rate;
if RandomNum <= 0 then
LoadMap = Maps[i].Name;
break;
end
end
end
elseif type(MapNames) == 'string' then
LoadMap = MapNames;
end
UGCLogSystem.Log("[MiniGameManager:LoadMap] 加载的地图:%s", LoadMap);
self.CurrLoadMapName = LoadMap;
self.Owner:LoadMap({ LoadMap });
end
--- 完成加载地图
function MiniGameManager:OnMapLoadComplete()
UGCLogSystem.Log("[MiniGameManager:OnMapLoadComplete] 地图加载完成")
if IsServer then
--self:AllPlayerRespawn()
LuaQuickFireEvent("AllPlayerReset", self.Owner);
end
self:OnMapLoaded();
end
--- 加载地图
function MiniGameManager:OnMapLoaded()
UGCLogSystem.Log("[MiniGameManager:OnMapLoaded] 加载地图成功")
table.func(self.CurrMiniMode, "OnAlready");
if IsClient then
-- 加载是否有 GodCamera
self.CurrMiniMode.GodCamera = UE.FindActorByClass(ObjectPath.BP_GodCamera)
else
-- 此时直接执行
UGCLogSystem.Log("[UGCGameState:OnGameStart] 开始准备刷毒圈")
PoisonManager:Toggle(true);
end
end
--- 卸载地图
function MiniGameManager:UnLoadMap()
-- 然后过一会再重新加载地图
self.Owner:UnloadMap({ self.CurrLoadMapName });
end
function MiniGameManager:OnMapUnLoadedComplete()
UGCLogSystem.Log("[MiniGameManager:OnMapUnLoadedComplete] 异步卸载地图完成")
end
--- 玩家选择地图
function MiniGameManager:OnPlayerSelectMap(InPlayer, InMapIndex)
if IsServer then
table.insert(self.SelectMaps, InMapIndex);
-- 发送 RPC
self:SendRPC("OnPlayerSelectMap", self.SelectMaps)
else
UGCEventSystem.SendEvent(EventTypes.MiniGame_SelectMap, self.SelectMaps);
end
end
----------------------------------- 回合函数 -----------------------------------
--- 开启小局
function MiniGameManager:OnMiniRoundPrepare()
-- 小局次数 - 1
if IsServer then
local Times = self.GameConfig[self.CurrSelectMap].MiniGameTimes;
local Time = (Times == nil or Times.Prepare == nil) and MiniGameTimes.RoundPrepare or Times.Prepare;
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
local InTime = t;
if Time > 0 then InTime = Time - t end
o:OnMiniGameTimeCount(InTime)
self:OnBeforeGameStart(t);
end, 1, Time, self.OnMiniRoundFormalStart);
self.CurrMiniMode.RoundTimes = self.CurrMiniMode.RoundTimes - 1;
self.CurrMiniMode.bGameEnd = false;
self:SetState(MiniGameState.ROUND_PREPARE);
self:SetRoundTimes(self.CurrMiniMode.RoundTimes);
else
-- 看看是否要执行什么
end
table.func(self.CurrMiniMode, "OnRoundStart", self:GetCurrRoundTimes());
end
--- 小局正式开始
function MiniGameManager:OnMiniRoundFormalStart()
-- 这是正式开启了
UGCLogSystem.Log("[MiniGameManager:OnMiniRoundFormalStart] 正式开始游戏")
if IsServer then
-- 启动计时,让小游戏有一个时限
local TotalTime = self.GameConfig[self.CurrSelectMap].GameTime;
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
local InTime = t;
if TotalTime > 0 then InTime = TotalTime - t end
o:OnMiniGameTimeCount(InTime);
end, 1., math.abs(TotalTime), self.OnMiniRoundEnd, function(o) return o.CurrMiniMode.bGameEnd; end);
self:SetState(MiniGameState.ROUND_GAMING);
-- 解除玩家封禁状态
self:SetAllPawnsCanMove(true);
else
-- 是否显示 “回合正式开始!”
end
table.func(self.CurrMiniMode, "OnRoundFormalStart", self:GetCurrRoundTimes());
end
function MiniGameManager:OnMiniRoundEnd()
-- 通知结束了
UGCLogSystem.Log("[MiniGameManager:OnMiniRoundEnd] 结束")
local Winner = 0;
if IsServer then
local Times = self.GameConfig[self.CurrSelectMap].MiniGameTimes;
local Time = 0;
if Times and Times.RoundEnd then
Time = Times.RoundEnd;
else
Time = MiniGameTimes.RoundEnd;
end
if self.CurrMiniMode.RoundTimes <= 0 then
UGCLogSystem.Log("[MiniGameManager:OnMiniRoundEnd] 回合结束")
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
o:OnMiniGameTimeCount(t);
end, 1, Time, self.OnMiniGameEnd);
else
-- 继续
-- 开始计时
UGCLogSystem.Log("[MiniGameManager:OnMiniRoundEnd] 下一小局开始")
GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t)
o:OnMiniGameTimeCount(t);
end, 1, Time, self.OnMiniRoundPrepare);
end
self.MiniInfo.RoundWinner = table.func(self.CurrMiniMode, "GetRoundWinner", self:GetCurrRoundTimes());
Winner = self.MiniInfo.RoundWinner;
self:SetState(MiniGameState.ROUND_END);
-- 检查是否需要关闭
self:SetAllPawnsCanMove(false);
else
-- 显示回合成功或者失败执行到此一定可以拿到Winner是谁
-- 直接获取 Winner
Winner = self.MiniInfo.RoundWinner
UGCLogSystem.Log("[MiniGameManager:OnMiniRoundEnd] RoundWinner = %s", tostring(Winner));
-- 显示 UI
end
table.func(self.CurrMiniMode, "OnRoundEnd", self:GetCurrRoundTimes(), Winner);
end
----------------------------------- 玩家函数 -----------------------------------
--- 当添加玩家的时候执行
function MiniGameManager:OnPlayerLogin(InPlayerKey)
UGCLogSystem.Log("[MiniGameManager:OnPlayerLogin] 玩家:%d 登录", InPlayerKey);
self.Owner.PlayerData[InPlayerKey] = {
PlayerKey = InPlayerKey,
Score = 0,
IsConnect = true,
MVPTimes = 0,
};
-- 如何发送到客户端呢?
DOREPONCE(self.Owner, "PlayerData")
end
---@param PlayerStartList table<TeamId, table<int32, APlayerStart>>
---@param Controller UGCPlayerController_C
function MiniGameManager:SelectPlayerStart(PlayerStartList, Controller)
return table.func(self.CurrMiniMode, 'SelectPlayerStart', PlayerStartList, Controller);
end
--- 当玩家退出的时候执行
function MiniGameManager:OnPlayerLeave(InPlayerKey)
UGCLogSystem.Log("[MiniGameManager:OnPlayerLeave] 玩家:%d 登出", InPlayerKey);
self.Owner.PlayerData[InPlayerKey].IsConnect = false;
DOREPONCE(self.Owner, "PlayerData");
end
--- S & C 玩家在加载好之后进行的初始化操作
function MiniGameManager:OnPawnInit(Pawn)
if IsServer then
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnPawnInit] self.GameConfig ="), self.GameConfig)
UGCLogSystem.Log("[MiniGameManager:OnPawnInit] self.CurrSelectMap = %s", tostring(self.CurrSelectMap))
if self.CurrSelectMap == nil then return; end
local Weapons = self.GameConfig[self.CurrSelectMap].InitWeapons;
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnPawnInit] Weapons ="), Weapons)
if not table.isEmpty(Weapons) then Pawn:AddInitItems(Weapons); end
end
end
--- 修改伤害函数
---@param DamagedActor UGCPlayerPawn_C
---@param Damage float
---@param DamageType EDamageType
---@param EventInstigator UGCPlayerController_C
function MiniGameManager:OnPlayerDamage(DamagedActor, Damage, DamageType, EventInstigator)
UGCLogSystem.Log("[MiniGameManager:OnPlayerDamage] DamagedActor = %s, Damage = %f", UE.GetName(DamagedActor), Damage);
local CalDamage = table.func(self.CurrMiniMode, 'OnPlayerTakeDamage', DamagedActor, Damage, DamageType, EventInstigator)
if CalDamage == nil then return Damage; end
return CalDamage;
end
--- S & C 接受到伤害函数
function MiniGameManager:BPReceiveDamage(DamagedActor, Damage, DamageType, InstigatedBy, DamageCauser)
if IsServer then
table.func(self.CurrMiniMode, 'BPReceiveDamage', DamagedActor, Damage, DamageType, InstigatedBy, DamageCauser)
end
end
--- 当玩家死亡
---@param DeadPlayerKey PlayerKey
---@param KillerPlayerKey PlayerKey
function MiniGameManager:OnPlayerDead(DeadPlayerKey, KillerPlayerKey)
table.func(self.CurrMiniMode, 'OnPlayerDead', DeadPlayerKey, KillerPlayerKey);
if IsServer then
-- 发送 RPC
self:SendRPC("OnPlayerDead", DeadPlayerKey, KillerPlayerKey);
end
end
function MiniGameManager:OnPlayerRespawn(InPlayerKey)
table.func(self.CurrMiniMode, "OnPlayerRespawn", InPlayerKey)
if LocalPlayerKey == InPlayerKey then
UGCLogSystem.Log("[MiniGameManager:OnPlayerRespawn] 执行")
--UGCEventSystem.SetTimer(self.Owner, function()
-- self.Owner:LoadMinimap(self.CurrLoadMapName);
--end, 1);
self.Owner:LoadMinimap(self.CurrLoadMapName);
end
end
function MiniGameManager:OnPlayerPossessed(Pawn, NewController)
-- 检查是否有初始武器,如果有,那么直接添加
if self.CurrSelectMap == nil or self.CurrMiniMode == nil then return; end
if self.GameConfig[self.CurrSelectMap].IsPlayerStunPrepare then
NewController:SetCanMove(false);
end
table.func(self.CurrMiniMode, "OnPlayerPossessed", Pawn, NewController);
end
--- 服务器/客户端收到伤害数据
---@param DamagedPawn UGCPlayerPawn_C
---@param Damage float
---@param DamageType UDamageType
---@param InstigatedBy UGCPlayerController_C
---@param DamageCauser AActor
function MiniGameManager:ReceiveDamage(DamagedPawn, Damage, DamageType, InstigatedBy, DamageCauser)
UGCLogSystem.Log("[MiniGameManager:ReceiveDamage] 收到伤害")
table.func(self.CurrMiniMode, "ReceiveDamage", DamagedPawn, Damage, DamageType, InstigatedBy, DamageCauser);
end
---@param InPawn UGCPlayerPawn_C
---@param Weapon ASTExtraWeapon
function MiniGameManager:OnPlayerGetWeapon(InPawn, Weapon)
if self.CurrMiniMode then
table.func(self.CurrMiniMode, "OnPlayerGetWeapon", InPawn, Weapon);
end
end
------------------------------------ 获取函数 ------------------------------------
--- 获取当前模式
function MiniGameManager:GetCurrentMode() return self.CurrMiniMode; end
--- 获取当前地图名
function MiniGameManager:GetCurrLevel() return self.GameConfig[self.CurrSelectMap].Map.MapName; end
--- 获取当前显示地图名称
function MiniGameManager:GetShowName() return self.GameConfig[self.CurrSelectMap].Map.ShowName; end
--- 获取当前是第几回合
function MiniGameManager:GetCurrRoundTimes()
if table.isEmpty(self.GameConfig) or self.CurrSelectMap == nil or table.isEmpty(self.GameConfig[self.CurrSelectMap]) then
return 1;
end
if self.GameConfig[self.CurrSelectMap].RoundTimes == nil then
return 1;
else
return self.GameConfig[self.CurrSelectMap].RoundTimes - self.CurrMiniMode.RoundTimes;
end
end
------------------------------------ 给予函数 ------------------------------------
--- 所有玩家死亡
function MiniGameManager:AllPlayerDead()
for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do
if v:IsAlive() then v:K2_DestroyActor(); end
end
end
--- 所有玩家重生
function MiniGameManager:AllPlayerRespawn(InTime)
UGCEventSystem.SetTimer(self.Owner, function()
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
UE.RespawnPlayer(v.PlayerKey);
end
end, InTime);
end
---@param InPawn UGCPlayerPawn_C
---@param InState EPawnState
function MiniGameManager:SetPawnState(InPawn, InState, IsSet)
if IsSet then
UGCPawnSystem.EnterPawnState(InPawn, InState)
else
UGCPawnSystem.LeavePawnState(InPawn, InState)
end
end
function MiniGameManager:SetAllPawnsCanMove(IsCan)
if self.CurrSelectMap == nil then return; end
if table.isEmpty(self.GameConfig) then return; end
if table.isEmpty(self.GameConfig[self.CurrSelectMap]) then return; end
if not self.GameConfig[self.CurrSelectMap].IsPlayerStunPrepare then return; end
for i, v in pairs(UGCGameSystem.GetAllPlayerController()) do v:SetCanMove(IsCan); end
end
--- 这个需要放在 GameState 中进行更改
function MiniGameManager:DOREPONCE(k, v)
self.Owner[k] = v;
DOREPONCE(self.Owner, k);
end
MiniGameManager.CachedMiniInfo = {};
--- 缓存一份
function MiniGameManager:MakeCachedMiniInfo()
if self.CachedMiniInfo.State == nil then
self.CachedMiniInfo.State = MiniGameState.NON_START;
end
end
--- 属性同步,对比是否不同,只有不同的会进行 OnRep_ 否则就不会进行。
function MiniGameManager:OnRep_MiniInfo(InOld)
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnRep_MiniInfo] self.MiniInfo ="), self.MiniInfo)
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnRep_MiniInfo] self.CachedMiniInfo Begin ="), self.CachedMiniInfo)
self.State = self.MiniInfo.State;
for i, v in pairs(self.MiniInfo) do
-- 如果发生改变再执行对应的 OnRep
if type(v) == 'table' then
-- 比较一下这两者有什么不同
if not table.compare(v, self.CachedMiniInfo[i]) then
-- 更新一下
if self:IsRepProp(tostring(i)) then
table.func(self, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]);
end
if self.CurrMiniMode ~= nil then
self.CurrMiniMode[i] = TableHelper.DeepCopyTable(v);
table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]);
end
end
else
if self.CachedMiniInfo[i] ~= v then
if self:IsRepProp(tostring(i)) then
table.func(self, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]);
end
if self.CurrMiniMode ~= nil then
self.CurrMiniMode[i] = v;
table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]);
end
end
end
self.CachedMiniInfo[i] = nil;
end
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnRep_MiniInfo] self.CachedMiniInfo End ="), self.CachedMiniInfo)
-- 检查是否有多余的
for i, v in pairs(self.CachedMiniInfo) do
if self:IsRepProp(tostring(i)) then
table.func(self, "OnRep_" .. tostring(i), v);
end
if self.CurrMiniMode ~= nil then
self.CurrMiniMode[i] = nil;
table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), v);
end
end
-- 设置上去进行缓存
self.CachedMiniInfo = TableHelper.DeepCopyTable(self.MiniInfo);
UGCLogSystem.LogTree(string.format("[MiniGameManager:OnRep_MiniInfo] self.CachedMiniInfo Final ="), self.CachedMiniInfo)
end
--- 获取内部数据
function MiniGameManager:GetMiniInfo(InName)
if self.CurrMiniMode then
local Item = table.func(self.CurrMiniMode, "GetMiniInfo", InName);
if Item ~= nil then return Item; end
return self.CurrMiniMode[InName];
end
return nil;
end
return MiniGameManager;