---@type FMiniGameManager local MiniGameManager = {}; ---@private string 这是玩家选择的地图,按从前往后开始游玩 MiniGameManager.ScriptPath = "Script.Blueprint.Mini.Script.Mini_"; ---@type table 当前所有玩家选择的地图 MiniGameManager.SelectMaps = {}; ---@type FMiniGameMapIndex 当前选择的地图 MiniGameManager.CurrSelectMap = nil; ---@type UGCGameState_C 默认是 GameSate,如果不是可以在具体实例里面实现对应方法 MiniGameManager.Owner = nil; ---@type table 游戏配置,对应着 MiniGameConfig[self.CurrSelectMap] MiniGameManager.GameConfig = nil; ---@type MiniGameMode 当前小玩法的具体实现,统一入口出口管理 MiniGameManager.CurrMiniMode = nil; ---@type int32 目标小游戏数量,低于这个数量会自动添加到这个数量 MiniGameManager.TargetMiniGameCount = 1; ---@type MiniGameState 模式状态,可以在本实例和 CurrMiniMode 中获取 MiniGameManager.State = 0; ---@type table 玩家数据 MiniGameManager.PlayerData = {}; ---@type table 小游戏需要同步的数据,会自动执行 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> ---@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;