MiniManager = {}; ---@private string 这是玩家选择的地图,按从前往后开始游玩 MiniManager.ScriptPath = "Script.Global.Mini.Script.Mini_"; ---@type table 当前所有玩家选择的地图 MiniManager.SelectMaps = {}; ---@type FMiniGameMapIndex 当前选择的地图 MiniManager.CurrSelectMap = nil; ---@type UGCGameState_C 默认是 GameSate,如果不是可以在具体实例里面实现对应方法 MiniManager.Owner = nil; ---@type MiniGameMode 当前小玩法的具体实现,统一入口出口管理 MiniManager.CurrMiniMode = nil; ---@type int32 目标小游戏数量,低于这个数量会自动添加到这个数量 MiniManager.TargetMiniGameCount = 1; ---@type MiniGameState 模式状态,可以在本实例和 CurrMiniMode 中获取 MiniManager.State = 0; ---@type table 玩家数据 MiniManager.PlayerData = {}; ---@type table 小游戏需要同步的数据,会自动执行 OnRep_xxx 函数 MiniManager.MiniInfo = {}; MiniManager.TimerHandlers = nil; ----------------------------------- 主要函数 ----------------------------------- --- 这是游戏启动,做一些初始化的操作即可 function MiniManager:Init(InOwner) UGCLogSystem.Log("[MiniManager:ReceiveBeginPlay] 执行成功 self = %s", tostring(self)); self.Owner = InOwner; if MiniGameConfig == nil then require('Script.Global.Mini.MiniGameConfig'); UGCLogSystem.LogTree(string.format("[MiniManager:Init] MiniGameConfig ="), MiniGameConfig); end if DefaultSettings.EnableTest then for i, v in pairs(MiniGameConfig) do v.RoundTimes = 1; end MiniGameTimes.RoundGameTime = -500; end 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 MiniManager: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("[MiniManager:MakeRepProps] self.Props ="), self.Props); end function MiniManager:IsRepProp(InName) if self.Props == nil then self.Props = {}; end return self.Props[InName] == true; end --- 本身需要同步的数据放进来 function MiniManager:GetReplicatedProperties() return "State" , "SelectMaps" , "CurrSelectMap" end --- 客户端准备好了,此时开始有 ServerTime function MiniManager:OnClientAlready() -- 显示 if IsClient then UGCLogSystem.Log("[MiniManager:OnGameBegin] 显示 UI") end table.func(self.CurrMiniMode, "OnClientAlready") end --- UI已经准备好了 function MiniManager:OnUIAlready() table.func(self.CurrMiniMode, "OnUIAlready") end --- 准备结束 function MiniManager:OnPrepareEnd() if IsServer then UGCLogSystem.Log("[MiniManager:OnPrepareEnd] 执行") self:SetMiniInfo(); UGCGameSystem.SendModeCustomEvent("CheckPlayers"); end table.func(self.CurrMiniMode, "OnPrepareEnd") self:OnMiniRoundPrepare(); end function MiniManager:SendRPC(InRPCName, ...) UGCLogSystem.Log("[MiniManager:SendRPC] InRPCName = %s", InRPCName); self.Owner:SendMiniGameRPC(InRPCName, ...); end --- 在游戏进行之前执行 ---@param InTime int32 从游戏开始到游戏正式开始的倒计时 function MiniManager:OnBeforeGameStart(InTime) UGCLogSystem.Log("[MiniManager:OnBeforeGameStart] InTime = %s", tostring(InTime)); if InTime == 1 then -- 玩家死亡重生 UE.ResetGame1(0.5, function() GameState:ResetKill(); end); end end --- 游戏正式开始 function MiniManager:OnGameStart() UGCLogSystem.Log("[MiniManager:OnGameStart] 执行") if IsServer then -- 检查当前选择的地图是否小于对应数量,如果小于,那么就随机选择为选择的 -- 获取选择了的 for i, v in pairs(MiniGameConfig) do table.insert(self.SelectMaps, i); end UGCLogSystem.LogTree(string.format("[MiniManager:OnGameStart] SelectMaps ="), self.SelectMaps) -- 表示如果第一个加载不成,那么就依次完后加载,直到全部加载都不行 local bSuccess = false; repeat bSuccess = self:LoadMiniGame() until bSuccess or table.isEmpty(self.SelectMaps); if not bSuccess then UGCLogSystem.Log("[MiniManager:OnGameStart] 游戏结束") self:OnGameEnd(); end else WidgetManager:ShowPanel(WidgetConfig.EUIType.Main, false); end end function MiniManager:OnGameEnd() UGCLogSystem.Log("[MiniManager:OnGameEnd] 游戏结束") if IsServer then self:SetState(MiniGameState.ENDED); LuaQuickFireEvent("GameEnd", GameState); else -- 显示结算界面 UGCLogSystem.Log("[MiniManager:OnGameEnd] GameWinner = %s", tostring(self.MiniInfo.GameWinner)); UGCLogSystem.LogTree(string.format("[MiniManager:OnGameEnd] RoundWinners ="), self.MiniInfo.RoundWinners) SoloKingGameWinner = self.MiniInfo.GameWinner; SoloKingRoundWinner = self.MiniInfo.RoundWinners; UGCLogSystem.Log("[MiniManager:OnGameEnd] 显示 GameEnd 界面"); if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.GameEnd) then WidgetManager:ShowPanel(WidgetConfig.EUIType.GameEnd, false, self.MiniInfo.GameWinner, self.MiniInfo.RoundWinners); WidgetManager:ClosePanel(WidgetConfig.EUIType.Main); end end end ---@param InMiniType MiniGameMapType Mini 游戏类型,只会在客户端存在 function MiniManager:LoadMiniGame(InMiniType) if MiniGameConfig == nil then require('Script.Global.Mini.MiniGameConfig'); end if IsServer then self:SetState(MiniGameState.MINI_PREPARE); self:AllPlayerDead(); UGCLogSystem.Log("[MiniManager:LoadMiniGame] 执行") if table.isEmpty(self.SelectMaps) then return false; end UGCLogSystem.Log("[MiniManager:LoadMiniGame] 开始执行流程") self.CurrSelectMap = self.SelectMaps[1]; if self.CurrSelectMap == nil then return false; end table.remove(self.SelectMaps, 1); -- 加载 CurrMiniMode UGCLogSystem.Log("[MiniManager:LoadMiniGame] 加载 Mini Mode") self.CurrMiniMode = require(self.ScriptPath .. MiniGameConfig[self.CurrSelectMap].Script); if self.CurrMiniMode == nil then return false; end if not table.func(self.CurrMiniMode, "Init", self) then return false; end -- 发送到客户端表示当前已经同步了 self.Owner:SelectMiniType(self.CurrSelectMap); UGCLogSystem.Log("[MiniManager:LoadMiniGame] Mini Mode 加载成功") self:CurrMiniModeInit(); if self.CurrMiniMode.RoundTimes == nil then self.CurrMiniMode.RoundTimes = 1; end self:SetRoundTimes(self.CurrMiniMode.RoundTimes); -- 这个是玩法的小局准备 local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes local Time = 0; if Times ~= nil and Times.Prepare ~= nil then Time = Times.Prepare; else Time = MiniGameTimes.Prepare; end UGCLogSystem.Log("[MiniManager:LoadMiniGame] Time = %s", tostring(Time)) self.TimerHandlers = GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) UGCLogSystem.Log("[MiniManager:LoadMiniGame] Time Internal = %s", tostring(t)); o:OnMiniGameTimeCount(t); end, 1, Time, self.OnPrepareEnd); UGCLogSystem.Log("[MiniManager:LoadMiniGame] 全部加载完成") return true; else UGCLogSystem.Log("[MiniManager:LoadMiniGame] 客户端加载") self.CurrSelectMap = InMiniType; self.CurrMiniMode = require(self.ScriptPath .. MiniGameConfig[self.CurrSelectMap].Script); if self.CurrMiniMode == nil then return ; end table.func(self.CurrMiniMode, "Init", self); self:CurrMiniModeInit(); -- 检查是否有数据啊 if UGCGameSystem.GameState then UGCGameSystem.GameState:OnRep_MiniInfo(); end end end --- 服务器客户端初始化的共同操作 function MiniManager:CurrMiniModeInit() --- 默认设置一些变量供使用或者驱动 self.CurrMiniMode.Owner = self; self.CurrMiniMode.MapIndex = self.CurrSelectMap; self.CurrMiniMode.CreateTime = UE.GetServerTime(); self.CurrMiniMode.bGameEnd = false; self.CurrMiniMode.bRoundEnd = false; self.CurrMiniMode.RoundTimes = MiniGameConfig[self.CurrSelectMap].RoundTimes; -- 当前回合数 self.CurrMiniMode.TotalRoundTimes = MiniGameConfig[self.CurrSelectMap].RoundTimes; -- 总回合数 self.CurrMiniMode.bCanRespawn = MiniGameConfig[self.CurrSelectMap].bCanRespawn; -- 是否可以重生 GlobalMiniType = self.CurrSelectMap; GlobalMiniMode = self.CurrMiniMode 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 if not table.isEmpty(MiniGameConfig[self.CurrSelectMap].Params) then for i, v in pairs(MiniGameConfig[self.CurrSelectMap].Params) do self.CurrMiniMode[i] = v; end end UGCLogSystem.Log("[MiniManager:CurrMiniModeInit] 开始加载地图") -- 加载 Tick GlobalTickTool:AddTick(self.CurrMiniMode, self.CurrMiniMode.OnTick, nil, function(o) return not (o.bEnableTick == false); end); -- 进入准备 table.func(self.CurrMiniMode, "OnPrepare"); end function MiniManager:UnLoadMiniGame() -- 先取消上一个的 if IsServer then if self.CurrMiniMode ~= nil then GlobalTickTool:RemoveTickByOwner(self.CurrMiniMode); -- 然后赶紧除去地图并且加载 self:UnLoadMap(); end end end function MiniManager:OnMiniGameTimeCount(InVal) if IsServer then if InVal == nil then InVal = 0; end InVal = math.floor(InVal); --- 执行 GameState:OnGameProgress_Tick(InVal); end if self.CurrMiniMode then self.CurrMiniMode.CurrTimeCount = InVal; end table.func(self.CurrMiniMode, "OnCountTime", InVal) end function MiniManager:OnMiniGameEnd() UGCLogSystem.Log("[MiniManager:OnMiniGameEnd] ") local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes; local Time = 0; if Times and Times.MiniGameEnd then Time = Times.MiniGameEnd; else Time = MiniGameTimes.MiniGameEnd; end -- 从小局中取出来 GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) o:OnMiniGameTimeCount(t); end, 1, Time, self.OnMiniGameSwitch); self:SetState(MiniGameState.MINI_END); self.MiniInfo.Scores = table.func(self.CurrMiniMode, "GetScore") self.MiniInfo.Winner = self.CurrMiniMode.GameWinner; table.func(self.CurrMiniMode, "OnGameEnd", self.MiniInfo.Scores); self:SetMiniInfo(); end function MiniManager:ClearMiniMode() UGCLogSystem.Log("[MiniManager:ClearMiniMode] 执行销毁") self.PlayerData = nil; self.SelectMaps = nil; end --- 切换到下一个 MiniGame function MiniManager:OnMiniGameSwitch() -- 检查是否还有下一个了 UGCLogSystem.Log("[MiniManager:OnMiniGameSwitch] 执行") if table.isEmpty(self.SelectMaps) then self:OnGameEnd(); return ; end self:UnLoadMiniGame(); self:LoadMiniGame(); end function MiniManager:SetState(InState) if IsServer then UGCLogSystem.Log("[MiniManager:SetState] CurrState = %s", TableHelper.printEnum(MiniGameState, InState)); self.State = InState; self.MiniInfo.State = InState; self:SetMiniInfo(); table.func(self.CurrMiniMode, 'SetState', InState); if self.CurrMiniMode ~= nil then self.CurrMiniMode.State = InState; end GameState:SetMiniState(InState); end -- 全局的状态 GlobalMiniState = self.State; end function MiniManager:SetRoundTimes(InTimes) if IsServer then self.MiniInfo.RoundTimes = InTimes; self:SetMiniInfo(); if self.CurrMiniMode ~= nil then self.CurrMiniMode.RoundTimes = InTimes; end end end function MiniManager:OnRep_RoundTimes(InOld) if self.CurrMiniMode ~= nil then self.CurrMiniMode.RoundTimes = self.MiniInfo.RoundTimes; end end function MiniManager:OnRep_State(InOld) UGCLogSystem.Log("[MiniManager:OnRep_State] self.State = %s, StateName = %s", tostring(self.MiniInfo.State), TableHelper.printEnum(MiniGameState, self.State)); self.State = self.MiniInfo.State; --if self.CurrMiniMode then -- self.CurrMiniMode.State = self.State; --end 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 GlobalMiniState = self.State; end --- 设置同步 MiniInfo, function MiniManager:SetMiniInfo() self.Owner:SetMiniInfo(self.MiniInfo); end --- 设置游戏数据 ---@vararg function MiniManager:SetGameInfo(InName, InInfo) UGCLogSystem.LogTree(string.format("[MiniManager:SetGameInfo] InInfo ="), InInfo) if type(InInfo) == 'table' then self.MiniInfo[InName] = TableHelper.DeepCopyTable(InInfo); else self.MiniInfo[InName] = InInfo; end self:SetMiniInfo(); end -- 给予子模块的数据同步 function MiniManager:DOREPONCE(Name) if self.CurrMiniMode then self:SetGameInfo(Name, self.CurrMiniMode[Name]); end end ----------------------------------- 地图函数 ----------------------------------- MiniManager.CurrLoadMapName = nil; function MiniManager:RandomSelectMap() local MapNames = MiniGameConfig[self.CurrSelectMap].Map.MapName; local MapName = ""; 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 Total = Total + 1; table.insert(Maps, { Name = Rate, Rate = 1, }) end end local MapCount = table.getCount(Maps); if Total == 0 then -- 从这两个中随机一个 MapName = Maps[math.random(MapCount)].Name; else local Num = KismetMathLibrary.RandomFloat() local RandomNum = Num * Total; for i = 1, table.getCount(Maps) do RandomNum = RandomNum - Maps[i].Rate; if RandomNum <= 0 then MapName = Maps[i].Name; break ; end end end elseif type(MapNames) == 'string' then MapName = MapNames; end return MapName; end --- 加载地图 function MiniManager:LoadMap(InIndex) UGCLogSystem.Log("[MiniManager:LoadMap] 执行") if InIndex == nil then InIndex = self.CurrSelectMap end if self.HadLoadMap == InIndex then return ; end -- 检查当前是什么东西,如果是随机的话 local MapName = table.func(self.CurrMiniMode, "SelectMapName", InIndex); if MapName == nil or string.len(MapName) == 0 then MapName = self:RandomSelectMap(); end UGCLogSystem.Log("[MiniManager:LoadMap] LoadMap = %s", MapName); self.CurrLoadMapName = MapName; UGCLogSystem.Log("[MiniManager:LoadMap] 执行 END"); self.Owner:LoadMap(MapName); self.HadLoadMap = InIndex; end --- 完成加载地图 function MiniManager:OnMapLoadComplete() UGCLogSystem.Log("[MiniManager:OnMapLoadComplete] 地图加载完成") if IsServer then UE.ResetGame(0.5); end self:OnMapLoaded(); end --- 加载地图 function MiniManager:OnMapLoaded() UGCLogSystem.Log("[MiniManager:OnMapLoaded] 加载地图成功") table.func(self.CurrMiniMode, "OnAlready"); end --- 卸载地图 function MiniManager:UnLoadMap() -- 然后过一会再重新加载地图 self.Owner:UnloadMap({ self.CurrLoadMapName }); self.HadLoadMap = nil; end function MiniManager:OnMapUnLoadedComplete() UGCLogSystem.Log("[MiniManager:OnMapUnLoadedComplete] 异步卸载地图完成") end --- 玩家选择地图 function MiniManager: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 MiniManager:OnMiniRoundPrepare() -- 小局次数 - 1 if IsServer then self:LoadMap(self.CurrSelectMap); local Times = MiniGameConfig[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.bRoundEnd = false; self:SetState(MiniGameState.ROUND_PREPARE); self:SetRoundTimes(self.CurrMiniMode.RoundTimes); else -- 看看是否要执行什么 end table.func(self.CurrMiniMode, "OnRoundStart", self:GetCurrRoundTimes()); if self.CurrMiniMode then self.CurrMiniMode.RoundEndTime = 0; end end --- 小局正式开始 function MiniManager:OnMiniRoundFormalStart() -- 这是正式开启了 UGCLogSystem.Log("[MiniManager:OnMiniRoundFormalStart] 正式开始游戏") if self.CurrMiniMode then self.CurrMiniMode.RoundStartTime = UE.GetServerTime(); end if IsServer then -- 启动计时,让小游戏有一个时限 local TotalTime = MiniGameTimes.RoundGameTime; 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 or o.CurrMiniMode.bRoundEnd; end); self:SetState(MiniGameState.ROUND_GAMING); -- 解除玩家封禁状态 UE.ClearSceneObjects(); else -- 是否显示 “回合正式开始!” end table.func(self.CurrMiniMode, "OnRoundFormalStart", self:GetCurrRoundTimes(), self.CurrMiniMode.RoundStartTime); end function MiniManager:OnMiniRoundEnd() if self.State == MiniGameState.ROUND_GAMING then if self.CurrMiniMode.bGameEnd == false and self.CurrMiniMode.bRoundEnd == false then table.func(self.CurrMiniMode, "OnTimeExhausted", self.State) end end -- 通知结束了 UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 结束") self.CurrMiniMode.RoundEndTime = UE.GetServerTime(); local Winner = 0; if IsServer then local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes; local Time = 0; if Times and Times.RoundEnd then Time = Times.RoundEnd; else Time = MiniGameTimes.RoundEnd; end UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] RoundTimes = %d", self.CurrMiniMode.RoundTimes) UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] bGameEnd = %s", tostring(self.CurrMiniMode.bGameEnd)) if self.CurrMiniMode.RoundTimes <= 0 or self.CurrMiniMode.bGameEnd then UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 回合结束") GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) o:OnMiniGameTimeCount(t); end, 1, Time, self.OnMiniGameEnd); else -- 继续 -- 开始计时 UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 下一小局开始") GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) o:OnMiniGameTimeCount(t); end, 1, Time, self.OnMiniRoundPrepare); end if table.hasFunc(self.CurrMiniMode, 'GetRoundWinner') then self.MiniInfo.RoundWinner = table.func(self.CurrMiniMode, "GetRoundWinner", self:GetCurrRoundTimes()); end Winner = self.MiniInfo.RoundWinner; table.func(self.CurrMiniMode, "OnRoundEnd", self:GetCurrRoundTimes(), Winner, self.CurrMiniMode.RoundEndTime - self.CurrMiniMode.RoundStartTime); UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] Winner = %s", tostring(Winner)) self:SetState(MiniGameState.ROUND_END); else -- 显示回合成功或者失败,执行到此一定可以拿到Winner是谁 -- 直接获取 Winner Winner = self.MiniInfo.RoundWinner UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] RoundWinner = %s", tostring(Winner)); table.func(self.CurrMiniMode, "OnRoundEnd", self:GetCurrRoundTimes(), Winner, self.CurrMiniMode.RoundEndTime - self.CurrMiniMode.RoundStartTime); end end ----------------------------------- 玩家函数 ----------------------------------- --- 当添加玩家的时候执行 function MiniManager:OnPlayerLogin(InPlayerKey) UGCLogSystem.Log("[MiniManager:OnPlayerLogin] 玩家:%d 登录", InPlayerKey); table.func(self.CurrMiniMode, "OnPlayerLogin", InPlayerKey); -- 获取玩家的排位分 UGCRankSystem.GetUGCRank(InPlayerKey); end function MiniManager:OnPlayerLeave(InPlayerKey) UGCLogSystem.Log("[MiniManager:OnPlayerLeave] 玩家:%d 登出", InPlayerKey); table.func(self.CurrMiniMode, "OnPlayerLeave", InPlayerKey); end ---@param PlayerStartList table> ---@param Controller UGCPlayerController_C function MiniManager:SelectPlayerStart(PlayerStartList, Controller) return table.func(self.CurrMiniMode, 'SelectPlayerStart', PlayerStartList, Controller); end --- S & C 玩家在加载好之后进行的初始化操作 function MiniManager:OnPawnInit(Pawn) if IsServer then --UGCLogSystem.LogTree(string.format("[MiniManager:OnPawnInit] GameConfig ="), MiniGameConfig); UGCLogSystem.Log("[MiniManager:OnPawnInit] self.CurrSelectMap = %s", tostring(self.CurrSelectMap)) if self.CurrSelectMap == nil then return ; end local InitArmors = MiniGameConfig[self.CurrSelectMap].InitArmors; local InitMedication = MiniGameConfig[self.CurrSelectMap].InitMedication; table.func(self.CurrMiniMode, 'OnPawnInit', Pawn, InitArmors, InitMedication); else table.func(self.CurrMiniMode, 'OnPawnInit', Pawn); end end --- 当玩家死亡 ---@param DeadPlayerKey PlayerKey ---@param KillerPlayerKey PlayerKey function MiniManager:OnPlayerDead(DeadPlayerKey, KillerPlayerKey) table.func(self.CurrMiniMode, 'OnPlayerDead', DeadPlayerKey, KillerPlayerKey); if IsServer then -- 发送 RPC self:SendRPC("OnPlayerDead", DeadPlayerKey, KillerPlayerKey); end end function MiniManager:OnPlayerRespawn(InPlayerKey) table.func(self.CurrMiniMode, "OnPlayerRespawn", InPlayerKey) end function MiniManager:OnPlayerPossessed(Pawn, NewController) -- 检查是否有初始武器,如果有,那么直接添加 UGCLogSystem.Log("[MiniManager:OnPlayerPossessed] 执行") table.func(self.CurrMiniMode, "OnPlayerPossessed", Pawn, NewController); end --- 仅在服务器存在 function MiniManager:OnPlayerInjury(PlayerKey, CauserKey, DamageInfo) UGCLogSystem.LogTree(string.format("[MiniManager:OnPlayerInjury] DamageInfo ="), DamageInfo) table.func(self.CurrMiniMode, "OnPlayerInjury", PlayerKey, CauserKey, DamageInfo); end ---@param InPawn UGCPlayerPawn_C ---@param Weapon ASTExtraWeapon function MiniManager:OnPlayerGetWeapon(InPawn, Weapon) if self.CurrMiniMode then table.func(self.CurrMiniMode, "OnPlayerGetWeapon", InPawn, Weapon); end end --- 射击导致子弹数量发生改变 ---@param PlayerKey PlayerKey 玩家 Key ---@param WeaponID int32 武器 ID ---@param PreCount int32 射击前数量 ---@param CurrCount int32 当前数量 function MiniManager:OnBulletNumChange(PlayerKey, WeaponID, PreCount, CurrCount) table.func(self.CurrMiniMode, "OnBulletNumChange", PlayerKey, WeaponID, PreCount, CurrCount); end ------------------------------------ 获取函数 ------------------------------------ --- 获取当前模式 function MiniManager:GetCurrentMode() return self.CurrMiniMode; end --- 获取当前地图名 function MiniManager:GetCurrLevel() return MiniGameConfig[self.CurrSelectMap].Map.MapName; end --- 获取当前显示地图名称 function MiniManager:GetShowName() return MiniGameConfig[self.CurrSelectMap].Map.ShowName; end --- 获取当前是第几回合 function MiniManager:GetCurrRoundTimes() if table.isEmpty(MiniGameConfig) or self.CurrSelectMap == nil or table.isEmpty(MiniGameConfig[self.CurrSelectMap]) then return 1; end if MiniGameConfig[self.CurrSelectMap].RoundTimes == nil then return 1; else return MiniGameConfig[self.CurrSelectMap].RoundTimes - self.CurrMiniMode.RoundTimes; end end --- 获取总的回合数 function MiniManager:GetTotalRoundTimes() if table.isEmpty(MiniGameConfig) or self.CurrSelectMap == nil or table.isEmpty(MiniGameConfig[self.CurrSelectMap]) then return 1; end if MiniGameConfig[self.CurrSelectMap].RoundTimes == nil then return 1; else return MiniGameConfig[self.CurrSelectMap].RoundTimes end end ------------------------------------ 给予函数 ------------------------------------ --- 所有玩家死亡 function MiniManager:AllPlayerDead() for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do if v:IsAlive() then v:K2_DestroyActor(); end end end --- 所有玩家重生 function MiniManager:AllPlayerRespawn(InTime) self:AllPlayerDead(); UGCEventSystem.SetTimer(self.Owner, function() for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do UGCGameSystem.RespawnPlayer(v.PlayerKey); end end, InTime); end ---@param InPawn UGCPlayerPawn_C ---@param InState EPawnState function MiniManager:SetPawnState(InPawn, InState, IsSet) if IsSet then UGCPawnSystem.EnterPawnState(InPawn, InState) else UGCPawnSystem.LeavePawnState(InPawn, InState) end end --- 这个需要放在 GameState 中进行更改 function MiniManager:DOREPONCE(k, v) self.Owner[k] = v; DOREPONCE(self.Owner, k); end MiniManager.CachedMiniInfo = {}; --- 缓存一份 function MiniManager:MakeCachedMiniInfo() if self.CachedMiniInfo.State == nil then self.CachedMiniInfo.State = MiniGameState.NON_START; end end --- 属性同步,对比是否不同,只有不同的会进行 OnRep_ 否则就不会进行。 function MiniManager:OnRep_MiniInfo(InOld) --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.MiniInfo ="), self.MiniInfo) --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo Begin ="), self.CachedMiniInfo) for i, v in pairs(self.MiniInfo) do -- 如果发生改变再执行对应的 OnRep if type(v) == 'table' then -- 比较一下这两者有什么不同 if not table.compare(v, self.CachedMiniInfo[i]) then -- 更新一下 UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 相同变量 Index = %s", tostring(i)); if self:IsRepProp(tostring(i)) then self[i] = v; 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 self[i] = v; 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 UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] Index = %s", i); self.CachedMiniInfo[i] = nil; --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo ="), self.CachedMiniInfo) end --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo End ="), self.CachedMiniInfo) -- 检查是否有多余的 for i, v in pairs(self.CachedMiniInfo) do if self.MiniInfo[i] == nil then if self:IsRepProp(tostring(i)) then self[tostring(i)] = nil; table.func(self, "OnRep_" .. tostring(i), v); end if self.CurrMiniMode ~= nil then self.CurrMiniMode[tostring(i)] = nil; table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), v); end UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 执行冗余的 Index = %s", tostring(i)); end UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 冗余的 Index = %s", tostring(i)); end -- 设置上去进行缓存 self.CachedMiniInfo = TableHelper.DeepCopyTable(self.MiniInfo); --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo Final ="), self.CachedMiniInfo) end --- 获取内部数据 function MiniManager: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 function MiniManager:UpdateInternalCount(InCount) UGCLogSystem.Log("[MiniManager:UpdateInternalCount] self.TimerHandlers = %s", tostring(self.TimerHandlers)); GlobalTickTool:UpdateInternalCountByHandle(self.TimerHandlers, InCount); end