---@class UGCGameState_C:BP_UGCGameState_C ---@field SciFiAnim FVehCharAnimData --Edit Below-- ---@type UGCGameState_C UGCGameSystem.UGCRequire('Script.Global.Global') UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom') local UGCGameState = { WaitPlayerJoinTime = 0; GameStateType = CustomEnum.EGameState.Waiting; GameTime = 0; -- 游戏倒计时时间 PlayerPersonalInfos = {}; -- 玩家信息{PlayerKey = {UID, PlayerKey, TeamID, IsOffline, PlayerName, Gender, IconURL, AchievementScore, IsSelectTeam}, ...} PlayerScoreDatas = {}; -- 玩家得分信息{[PlayerKey] = {Kill = int32, Dead = int32, Assist = int32, Score = float, TechnicalScore = float}...} PlayerRankDatas = {}; -- 玩家排行信息{[TeamID] = {{PlayerKey = uint}, ... } PlayerJoinNum = 0; -- 玩家加入的数量作为个人TeamID PlayerSaveWeaponSelect = {}; -- 玩家存档中的武器选择 {[PlayerKey] = {WeaponID = int32, PropID = int32}} PlayerArchiveInfos = {}; -- 玩家存档{[PlayerKey] = ArchiveData} ControllerInitializationEndedPlayer = {}; -- 控制器初始化完成的玩家{PlayerKey} PlayerIsFirstTimePlayingCache = {}; -- 客户端需执行首次登录函数的玩家{PlayerKey} TeamScore = {}; -- 队伍得分信息 { TeamID = Score, ... } RoundNum = 0; -- 回合数 TempAllPlayerScores = {}; -- 临时玩家隐藏分 TeamPlayerAlive = {}; -- 队伍玩家存活信息 [TeamID] = {PlayerKey = bAlive} KeyOwner = -1; -- 钥匙拥有者 PlayerSelectMiniGameTypes = {}; -- 玩家选择游戏玩法 {PlayerKey = MiniG啊meType, ..} NowMiniGameIndex = 1; -- 当前游戏玩法的索引 MiniGameList = {}; -- 小玩法列表 PlayerIsReady = {}; -- 小玩法玩家已准备 ---@type MoveActorManager = nil; -- 旋转管理器 ClientGameTimeDifference = 0.; -- 客户端与服务器的游戏时间差时间差 GameTimeCalibrationCycle = 3; -- 校准客户端GameTime的周期 RoundStartTime = 0.; -- 回合开始时间 -- 互斥UI参数 {UIType, ShowParam = {}} MutuallyExclusiveUIInfo = {UIType = -1, ShowParams = {}}; MiniGameScore = {}; -- 玩家小玩法内得分 -- 小玩法局内回合 MiniGameInternalRound = 0; IsReadyState = false; -- 是否为准备状态 }; function UGCGameState:GetReplicatedProperties() return "GameTime", "PlayerPersonalInfos", "WaitPlayerJoinTime", "GameStateType", "PlayerSaveWeaponSelect", "PlayerScoreDatas", "PlayerRankDatas", "TeamScore", "RoundNum", "TeamPlayerAlive", "KeyOwner", "PlayerSelectMiniGameTypes", "NowMiniGameIndex", "MiniGameList", "PlayerIsReady", "MutuallyExclusiveUIInfo", "MiniGameScore", "MiniGameInternalRound", ArchiveDataConfig.GetAllReplicatedPropertiesName() end function UGCGameState:ReceiveBeginPlay() UGCLogSystem.Log("[UGCGameState:ReceiveBeginPlay]") --屏蔽死亡盒子 -- self.IsShowDeadBox = false; -- 开启滑铲State部分 self.bIsOpenShovelingAbility = true -- 全局逻辑初始化 GlobalInit.Init() -- 注册存档 ArchiveDataConfig.Register(self) -- 初始化RPC系统 UGCSendRPCSystem.InitUGCSendRPCSystem(self, "UGCSendRPCSystemFunc") -- 绑定事件 self:AddBind() self.MoveActorManager = require('Script.Blueprint.MiniLevelActor.JumpAndCrouch.MovingActorsManager') self.MoveActorManager:Init(self); if UGCGameSystem.IsServer() then -- 第一人称模式 --if GlobalConfigs.GameModeSetting.bIsFPP then -- UGCSystemLibrary.SetFPPMode() --end self.GameTimeCalibrationHandle = UGCEventSystem.SetTimerLoop(self, self.CalibrationServerGameTime, self.GameTimeCalibrationCycle) end end function UGCGameState:ReceiveEndPlay() self:RemoveBind() end function UGCGameState:AddBind() if self:HasAuthority() then UGCEventSystem.AddListener(EventEnum.PlayerLogin, self.PlayerLogin, self) UGCEventSystem.AddListener(EventEnum.PlayerExit, self.PlayerExit, self) UGCEventSystem.AddListener(EventEnum.PlayerDeathInfo, self.PlayerDeadInfo, self) UGCEventSystem.AddListener(EventEnum.PlayerPossessed, self.PlayerPossessed, self) else end end function UGCGameState:RemoveBind() if self:HasAuthority() then UGCEventSystem.RemoveListener(EventEnum.PlayerLogin, self.PlayerLogin, self) UGCEventSystem.RemoveListener(EventEnum.PlayerExit, self.PlayerExit, self) UGCEventSystem.RemoveListener(EventEnum.PlayerDeathInfo, self.PlayerDeadInfo, self) if self.UpdateScoreTimeHandle then UGCEventSystem.StopTimer(self.UpdateScoreTimeHandle) self.UpdateScoreTimeHandle = nil end if self.GameTimeCalibrationHandle then UGCEventSystem.StopTimer(self.GameTimeCalibrationHandle) self.GameTimeCalibrationHandle = nil end else end end function UGCGameState:PlayerLogin(PlayerPawn, PlayerKey) self:UpdatePlayerTeam(PlayerKey) self:GetUserInfo(PlayerKey) self:UpdatePlayerJoin() self:UpdateAllPlayerScoreDatas() self:GetPlayerArchiveInfos(PlayerKey) -- self:InitPlayerGradient(PlayerKey) -- self:UpdatePlayerRankDatas(PlayerKey, self:GetPlayerTeamIDByPlayerKey(PlayerKey)) self:UpdateTeamPlayerAlive() end function UGCGameState:PlayerExit(PlayerPawn, PlayerKey) self:UpdatePlayerJoin() self:UpdateAllPlayerScoreDatas() self:UpdateTeamPlayerAlive() end function UGCGameState:PlayerDeadInfo(DeadPlayerKey) self:UpdateTeamPlayerAlive() end --- 根据游戏队伍模式更新玩家队伍 ---@param PlayerKey uint function UGCGameState:UpdatePlayerTeam(PlayerKey) if GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.PersonalWarfare or GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.PartyMode then local NewTeamID = self:GetNewTeamID() UGCTeamSystem.ChangePlayerTeamID(PlayerKey, NewTeamID) UGCLogSystem.Log("[UGCGameState_UpdatePlayerTeam] NewTeamID:%s", tostring(NewTeamID)) end end --- 玩家登录获取玩家数据 ---@param PlayerKey uint function UGCGameState:GetUserInfo(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] then return self.PlayerPersonalInfos[PlayerKey] end local UserInfo = UGCPlayerStateSystem.GetPlayerAccountInfo(PlayerKey) if UserInfo then --- UID,PlayerName,TeamID,Gender,PlatformGender,PlayerLevel,SegmentLevel,IconURL local UserInfoCpy = UserInfo:Copy() UGCLogSystem.Log("[UGCGameState_GetUserInfo] PlayerName:%s", UserInfoCpy.PlayerName) local CustomUserInfo = { UID = UserInfoCpy.UID, PlayerKey = PlayerKey, TeamID = UserInfoCpy.TeamID, IsOffline = false, PlayerName = UserInfoCpy.PlayerName, Gender = UserInfoCpy.PlatformGender, IconURL = UserInfoCpy.IconURL, IsSelectTeam = false, } self.PlayerPersonalInfos[PlayerKey] = CustomUserInfo UGCLogSystem.LogTree("[UGCGameState_GetUserInfo] CustomUserInfo:", CustomUserInfo) return CustomUserInfo else UGCLogSystem.LogError("[UGCGameState_GetUserInfo] UserInfo Error PlayerKey:%s", tostring(PlayerKey)) end end --- 对玩家在队伍中进行排序 function UGCGameState:SortPlayerRankDatas() if #self.PlayerRankDatas < 1 then return end for i, v in pairs(self.PlayerRankDatas) do table.sort(self.PlayerRankDatas[i], function(a, b) -- local aScore = self.PlayerScoreDatas[a].Score + self.PlayerScoreDatas[a].TechnicalScore * GlobalConfigs.GameSetting.TechnicalScoreProportion -- local bScore = self.PlayerScoreDatas[b].Score + self.PlayerScoreDatas[b].TechnicalScore * GlobalConfigs.GameSetting.TechnicalScoreProportion return self:GetPlayerScore(a) > self:GetPlayerScore(b) end) end end --- 更新玩家排序信息 function UGCGameState:UpdatePlayerRankDatas(PlayerKey, TeamID) if self.PlayerRankDatas[TeamID] == nil then self.PlayerRankDatas[TeamID] = {} end self.PlayerRankDatas[TeamID][#self.PlayerRankDatas[TeamID] + 1] = PlayerKey for TempTeamID, PlayerKeys in pairs(self.PlayerRankDatas) do for i, TempPlayerKey in pairs(PlayerKeys) do if UGCGameSystem.GetPlayerControllerByPlayerKey(TempPlayerKey) == nil then self.PlayerRankDatas[TempTeamID][TempPlayerKey] = nil end end end --self:SortPlayerRankDatas() end function UGCGameState:GetPlayerRankByPlayerKey(PlayerKey) local TeamID = self:GetPlayerTeamIDByPlayerKey(PlayerKey) if self.PlayerRankDatas[TeamID] == nil then return 0 end return table.FindKey(self.PlayerRankDatas[TeamID], PlayerKey) end function UGCGameState:OnRep_PlayerRankDatas() UGCEventSystem.SendEvent(EventEnum.UpdatePlayerRank) end function UGCGameState:GetPlayerRank() return self.PlayerRankDatas end --- 获取存档 function UGCGameState:GetPlayerArchiveInfos(PlayerKey) self.PlayerArchiveInfos[PlayerKey] = UGCPlayerStateSystem.GetPlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID) if self.PlayerArchiveInfos[PlayerKey] then self.PlayerSaveWeaponSelect[PlayerKey] = self.PlayerArchiveInfos[PlayerKey].PlayerSaveWeaponSelect end end --- 获取存档信息 ---@param PlayerKey function UGCGameState:GetPlayerArchiveInfosFromArchiveType(PlayerKey, ArchiveType) if self.PlayerArchiveInfos[PlayerKey] == nil then if self.PlayerPersonalInfos[PlayerKey] then self.PlayerArchiveInfos[PlayerKey] = UGCPlayerStateSystem.GetPlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID) else UGCLogSystem.LogError("[UGCGameState_GetPlayerArchiveInfosFromArchiveType] PlayerPersonalInfos[%s] is nil", tostring(PlayerKey)) end end if ArchiveType == nil then return self.PlayerArchiveInfos[PlayerKey] elseif type(ArchiveType) == "table" then local Res = nil for i, v in pairs(ArchiveType) do if Res == nil then Res = self.PlayerArchiveInfos[PlayerKey][v] else Res = Res[v] end if Res == nil then return nil end end return Res else return self.PlayerArchiveInfos[PlayerKey][ArchiveType] end end function UGCGameState:OnRep_PlayerSaveWeaponSelect() UGCEventSystem.SendEvent(EventEnum.PlayerSaveWeaponChange) end -- 玩家已选择队伍 function UGCGameState:PlayerHasSelectedTeam(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] == nil or self.PlayerPersonalInfos[PlayerKey].IsSelectTeam == false then return false end return true end ---@param PlayerKey int32 ---@param AddScore float ---@return bool Succeed function UGCGameState:AddScore(PlayerKey, AddScore) local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey) if UE.IsValid(TargetPlayerState) then TargetPlayerState:SetScore(TargetPlayerState:GetScore() + AddScore) self.PlayerScoreDatas[PlayerKey].Score = TargetPlayerState:GetScore() --DOREPONCE(self, "PlayerScoreDatas") self:SortPlayerRankDatas() if GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.TeamSports then self:AddTeamScore(self:GetPlayerTeamIDByPlayerKey(PlayerKey), AddScore) end return true end return false end function UGCGameState:GetTeamScore(TeamID) return (self.TeamScore[TeamID] and self.TeamScore[TeamID] or 0) end function UGCGameState:ResetTeamScore() self.TeamScore = {} end function UGCGameState:AddTeamScore(TeamID, Score) self.TeamScore[TeamID] = self:GetTeamScore(TeamID) + Score end ---@param PlayerKey int32 ---@param AddTechnicalScore float ---@return bool Succeed function UGCGameState:AddTechnicalScore(PlayerKey, AddTechnicalScore) local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey) if UE.IsValid(TargetPlayerState) then TargetPlayerState:SetTechnicalScore(TargetPlayerState:GetTechnicalScore() + AddTechnicalScore) self.PlayerScoreDatas[PlayerKey].TechnicalScore = TargetPlayerState:GetTechnicalScore() self:SortPlayerRankDatas() return true end return false end -- 更新返回所有玩家得分 function UGCGameState:UpdateAllPlayerScoreDatas() local AllPlayerState = UGCGameSystem.GetAllPlayerState(false) local ResScoreDatas = {} if AllPlayerState then for _, PlayerState in pairs(AllPlayerState) do if UE.IsValid(PlayerState) and self.PlayerPersonalInfos[PlayerState.PlayerKey] and self.PlayerPersonalInfos[PlayerState.PlayerKey].IsOffline == false then if GlobalConfigs.GameSetting.EnablePlayerJoin then ResScoreDatas[PlayerState.PlayerKey] = table.DeepCopy(PlayerState.ScoreData) else self.PlayerScoreDatas[PlayerState.PlayerKey] = table.DeepCopy(PlayerState.ScoreData) end end end end if GlobalConfigs.GameSetting.EnablePlayerJoin then self.PlayerScoreDatas = ResScoreDatas end self:SortPlayerRankDatas() return self.PlayerScoreDatas end --- 获取在线人数 function UGCGameState:GetNumberOfOnlineUsers() return table.getCount(self.PlayerScoreDatas) end function UGCGameState:OnRep_PlayerScoreDatas() if self:HasAuthority() then return end UGCEventSystem.SendEvent(EventEnum.UpdatePlayerScoreData) end function UGCGameState:OnRep_PlayerPersonalInfos() if self:HasAuthority() then return end UGCEventSystem.SendEvent(EventEnum.UpdatePlayerScoreData) UGCLogSystem.LogTree("[UGCGameState_OnRep_PlayerPersonalInfos]", self.PlayerPersonalInfos) end function UGCGameState:GetPlayerScoreData() return self.PlayerScoreDatas end function UGCGameState:GetGameStateType() return self.GameStateType end function UGCGameState:SetGameStateType(NewGameStateType) if not self:HasAuthority() then return end if self.GameStateType ~= NewGameStateType then self.GameStateType = NewGameStateType UGCEventSystem.SendEvent(EventEnum.GameStateChange, self.GameStateType) end end function UGCGameState:OnRep_GameStateType() if self:HasAuthority() then return end UGCEventSystem.SendEvent(EventEnum.GameStateChange, self.GameStateType) end function UGCGameState:GameWillBeginNotify() UnrealNetwork.CallUnrealRPC_Multicast(self, "MulticastRPC_GameWillBeginNotify") end function UGCGameState:MulticastRPC_GameWillBeginNotify() UGCEventSystem.SendEvent(EventEnum.GameWillBegin) end function UGCGameState:GameFinish() self:SetGameStateType(CustomEnum.EGameState.End) end -- 更新申请玩家加入 function UGCGameState:UpdatePlayerJoin() if not GlobalConfigs.GameSetting.EnablePlayerJoin then return end if self.GameStateType == CustomEnum.EGameState.End or self.GameStateType == CustomEnum.EGameState.InsufficientNumberOfPeople then return end local NeedPlayerNum = GlobalConfigs.GameModeSetting.TeamNeedPlayerNum - #UGCGameSystem.GetAllPlayerState() UGCGameSystem.StopPlayerJoin() if NeedPlayerNum > 0 then UGCGameSystem.OpenPlayerJoin() UGCGameSystem.ApplyPlayerJoin(1, 1) UGCLogSystem.Log("[UGCGameState_UpdatePlayerJoin] NeedPlayerNum: %d", NeedPlayerNum) end end function UGCGameState:GetNewTeamID() -- body self.PlayerJoinNum = self.PlayerJoinNum + 1 return self.PlayerJoinNum end function UGCGameState:Client_SaveSelectWeaponCallBack(SelectSucceed) if self:HasAuthority() then return end UGCEventSystem.SendEvent(EventEnum.SaveSelectWeaponCallBack, SelectSucceed) end function UGCGameState:GetPlayerNameByPlayerKey(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] then return self.PlayerPersonalInfos[PlayerKey].PlayerName else return "" end end function UGCGameState:GetPlayerTeamIDByPlayerKey(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] then return self.PlayerPersonalInfos[PlayerKey].TeamID else return -1 end end function UGCGameState:GetHeadIconByPlayerKey(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] then return self.PlayerPersonalInfos[PlayerKey].IconURL else return "" end end function UGCGameState:GetScoreDataByPlayerKey(PlayerKey) return self.PlayerScoreDatas[PlayerKey] end function UGCGameState:GetPlayerPersonalKeys() return table.getKeys(self.PlayerPersonalInfos) end --------------------------------------------- RoundFun --------------------------------------------- function UGCGameState:NewRound() self:ResetRoundData() self.RoundNum = self.RoundNum + 1 end function UGCGameState:GetRoundNum() return self.RoundNum end function UGCGameState:SetWinner(TeamID) if self.WinnerTeam > 0 then return end self.WinnerTeam = TeamID self:AddTeamScore(TeamID, 1) end function UGCGameState:GetWinner() return self.WinnerTeam end function UGCGameState:GetMVPPlayer() local AllPC = UGCGameSystem.GetAllPlayerController() local ResPlayer = -1 local TempScore = 0. for i, v in pairs(AllPC) do local NowScore = self:GetPlayerScore(v.PlayerKey) local ScoreDiff = 0 if self.TempAllPlayerScores[v.PlayerKey] then ScoreDiff = NowScore - self.TempAllPlayerScores[v.PlayerKey] else ScoreDiff = NowScore end if ResPlayer < 0 or TempScore < ScoreDiff then ResPlayer = v.PlayerKey TempScore = ScoreDiff end end return ResPlayer end function UGCGameState:GetPlayerScore(PlayerKey) local PlayerScoreInfo = self.PlayerScoreDatas[PlayerKey] if PlayerScoreInfo then return PlayerScoreInfo.Kill * 2 + PlayerScoreInfo.Assist + self:GetPlayerHoldsTheKeyTime(PlayerKey) * GlobalConfigs.GameSetting.HoldsTheKeyTimeToScore else return 0 end end --- 记录玩家当前隐藏分 function UGCGameState:RecordPlayerScore() local AllPC = UGCGameSystem.GetAllPlayerController() self.TempAllPlayerScores = {} for i, v in pairs(AllPC) do self.TempAllPlayerScores[v.PlayerKey] = self:GetPlayerScore(v.PlayerKey) end end function UGCGameState:ResetRoundData() self.WinnerTeam = -1 end --- 启用各队伍基地阻挡物,准备阶段防止玩家走出房间 function UGCGameState:EnableHouseBlock(IsBlock) if IsBlock then else end end --- 准备时间结束 function UGCGameState:ReadyTimeFinish() end function UGCGameState:RoundStart() self.RoundStartTime = UGCSystemLibrary.GetGameTime() end --- 是否在准备时间 function UGCGameState:IsReadyTime() return UGCSystemLibrary.GetGameTime() - self.RoundStartTime < GlobalConfigs.GameModeSetting.RoundReadyTime end --- 获取准备时间 Server function UGCGameState:GetReadyTime() return GlobalConfigs.GameModeSetting.RoundReadyTime - (UGCSystemLibrary.GetGameTime() - self.RoundStartTime) end ------------------------------------------- RoundFun End ------------------------------------------- ---------------------------------------------- Buy End ----------------------------------------------- -------------------------------------------- Update Team Player Alive -------------------------------------------- function UGCGameState:PlayerPossessed() if self.DelayUpdateTeamPlayerAliveHandle then UGCEventSystem.StopTimer(self.DelayUpdateTeamPlayerAliveHandle) end self.DelayUpdateTeamPlayerAliveHandle = UGCEventSystem.SetTimer(self, self.UpdateTeamPlayerAlive, 0.3) end --- 更新玩家存活信息 function UGCGameState:UpdateTeamPlayerAlive() self.TeamPlayerAlive = {} for i, TeamID in pairs(UGCTeamSystem.GetTeamIDs()) do self.TeamPlayerAlive[TeamID] = {} for _, PlayerKey in pairs(UGCTeamSystem.GetPlayerKeysByTeamID(TeamID)) do self.TeamPlayerAlive[TeamID][PlayerKey] = UGCPlayerStateSystem.IsAlive(PlayerKey) end end self.DelayUpdateTeamPlayerAliveHandle = nil end function UGCGameState:OnRep_TeamPlayerAlive() UGCEventSystem.SendEvent(EventEnum.TeamPlayerAliveChange, self.TeamPlayerAlive) end -------------------------------------------- Update Team Player Alive End -------------------------------------------- ---------------------------------------------------- MiniGame ---------------------------------------------------- function UGCGameState:PlayerSelectMiniGame(MiniGameType, PlayerKey) if self.PlayerSelectMiniGameTypes[PlayerKey] then return elseif table.hasValue(self.PlayerSelectMiniGameTypes, MiniGameType) then UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMiniGameCallBack, false, MiniGameType, PlayerKey) elseif MiniGameConfig.MiniGameInfo[MiniGameType] then self.PlayerSelectMiniGameTypes[PlayerKey] = MiniGameType UGCSendRPCSystem.RPCEvent(nil, EventEnum.SelectMiniGameCallBack, true, MiniGameType, PlayerKey) else UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMiniGameCallBack, false, MiniGameType, PlayerKey) end end function UGCGameState:SelectedMiniGameCount() return table.getCount(self.PlayerSelectMiniGameTypes) end function UGCGameState:OnRep_PlayerSelectMiniGameTypes() UGCEventSystem.SendEvent(EventEnum.UpdatePlayerSelectMiniMapType, self.PlayerSelectMiniGameTypes) end function UGCGameState:GetPlayerSelectMiniGameTypes() return self.PlayerSelectMiniGameTypes end --- 设置最终小玩法投票结果,未满足最大玩法数则随机补充 function UGCGameState:SettlementMiniGameList() self.MiniGameList = {} local TempAllGameList = table.getValues(MiniGameConfig.MiniGameType) for i, v in pairs(self.PlayerSelectMiniGameTypes) do self.MiniGameList[#self.MiniGameList + 1] = v table.removeValue(TempAllGameList, v) end -- table.Shuffle(self.MiniGameList) table.Shuffle(TempAllGameList) for i = 1, GlobalConfigs.GameSetting.MiniGameNum - #self.MiniGameList do if TempAllGameList[i] then self.MiniGameList[#self.MiniGameList + 1] = TempAllGameList[i] end end UGCLogSystem.LogTree("[UGCGameState_SettlementMiniGameList]", self.MiniGameList) UGCSendRPCSystem.RPCEvent(nil, EventEnum.NewMiniGame, self:GetNowMiniGameType()) end --- 获取当前回合的玩法类型 function UGCGameState:GetNowMiniGameType() return self:GetMiniGameTypeFromMiniGameIndex(self.NowMiniGameIndex) end function UGCGameState:GetMiniGameTypeFromMiniGameIndex(MiniGameIndex) return self.MiniGameList[MiniGameIndex] end --- 获取当前小玩法回合 function UGCGameState:GetNowMiniGameIndex() return self.NowMiniGameIndex end --- 新回合调用 function UGCGameState:NewMiniGame() self.NowMiniGameIndex = self.NowMiniGameIndex + 1 UGCSendRPCSystem.RPCEvent(nil, EventEnum.NewMiniGame, self:GetNowMiniGameType()) end --- 玩家准备完成 function UGCGameState:PlayerMiniGameReady(PlayerKey) if table.hasValue(self.PlayerIsReady, PlayerKey) then return end self.PlayerIsReady[#self.PlayerIsReady + 1] = PlayerKey UGCLogSystem.LogTree("[UGCGameState_PlayerMiniGameReady]", self.PlayerIsReady) UGCEventSystem.SendEvent(EventEnum.UpdatePlayerIsReady, self.PlayerIsReady) end function UGCGameState:ResetPlayerMiniGameReady() self.PlayerIsReady = {} end function UGCGameState:OnRep_PlayerIsReady() UGCLogSystem.LogTree("[UGCGameState_OnRep_PlayerIsReady]", self.PlayerIsReady) UGCEventSystem.SendEvent(EventEnum.UpdatePlayerIsReady, self.PlayerIsReady) end function UGCGameState:CheckAllPlayerIsReady() local AllPC = UGCGameSystem.GetAllPlayerController() for i, PC in pairs(AllPC) do if not table.hasValue(self.PlayerIsReady, PC.PlayerKey) then return false end end return true end --- return PlayerRankInfo = {{PlayerKey, Score, RankNum}} function UGCGameState:GetMiniGameScoreRank() local PlayerRankInfo = {} for i, v in pairs(self.PlayerScoreDatas) do PlayerRankInfo[#PlayerRankInfo + 1] = {PlayerKey = i, Score = v.Score} end table.sort(PlayerRankInfo, function(a, b) return a.Score > b.Score end) local LastScore = nil local LastRank = 1 for i, v in pairs(PlayerRankInfo) do if v.Score == LastScore then PlayerRankInfo[i].RankNum = LastRank else LastRank = i PlayerRankInfo[i].RankNum = LastRank LastScore = v.Score end end return PlayerRankInfo end ------------------------------------------ MiniGameInternalRound ------------------------------------------ function UGCGameState:SetMiniGameInternalRound(NewRound) self.MiniGameInternalRound = NewRound end function UGCGameState:AddMiniGameInternalRound() self:SetMiniGameInternalRound(self:GetMiniGameInternalRound() + 1) end function UGCGameState:GetMiniGameInternalRound() return self.MiniGameInternalRound end ---------------------------------------- MiniGameInternalRound End ---------------------------------------- ------------------------------------------ MiniGameScore ------------------------------------------ function UGCGameState:ResetMiniGameScore() local AllPC = UGCGameSystem.GetAllPlayerController() for i, PC in pairs(AllPC) do self.MiniGameScore[PC.PlayerKey] = 0 end for i, v in pairs(self.MiniGameScore) do self.MiniGameScore[i] = 0 end UGCSendRPCSystem.RPCEvent(nil, EventEnum.UpdateMiniGameAllPlayerScore, self.MiniGameScore) end function UGCGameState:GetMiniGameScore() return table.DeepCopy(self.MiniGameScore) end function UGCGameState:PlayerAddMiniGameScore(PlayerKey, AddScore) if self.MiniGameScore[PlayerKey] then self.MiniGameScore[PlayerKey] = self.MiniGameScore[PlayerKey] + AddScore else self.MiniGameScore[PlayerKey] = AddScore end -- UGCSendRPCSystem.RPCEvent(nil, EventEnum.UpdateMiniGameAllPlayerScore, self.MiniGameScore) end function UGCGameState:SetPlayerMiniGameScore(ScoreList) if type(ScoreList) == "table" then self.MiniGameScore = ScoreList end -- UGCSendRPCSystem.RPCEvent(nil, EventEnum.UpdateMiniGameAllPlayerScore, self.MiniGameScore) end function UGCGameState:GetPlayerMiniGameScore(PlayerKey) if self.MiniGameScore[PlayerKey] == nil then self.MiniGameScore[PlayerKey] = 0 end return self.MiniGameScore[PlayerKey] end function UGCGameState:OnRep_MiniGameScore() UGCEventSystem.SendEvent(EventEnum.UpdateMiniGameAllPlayerScore, self.MiniGameScore) end function UGCGameState:GetPlayerMiniGameAddScore() local PlayerScoreInfo = {} for i, v in pairs(self.MiniGameScore) do PlayerScoreInfo[#PlayerScoreInfo + 1] = {PlayerKey = i, Score = v} end local MiniGamePlayerAddScore = {} table.sort(PlayerScoreInfo, function(a, b) return a.Score > b.Score end) local LastScore = nil local LastAddScore = 4 for i, v in pairs(PlayerScoreInfo) do if v.Score == LastScore then MiniGamePlayerAddScore[v.PlayerKey] = LastAddScore else LastAddScore = 5 - i MiniGamePlayerAddScore[v.PlayerKey] = LastAddScore LastScore = v.Score end end local AllPC = UGCGameSystem.GetAllPlayerController() for i, v in pairs(AllPC) do if MiniGamePlayerAddScore[v.PlayerKey] == nil then MiniGamePlayerAddScore[v.PlayerKey] = 1 end end return MiniGamePlayerAddScore end ---------------------------------------- MiniGameScore End ---------------------------------------- -------------------------------------------------- MiniGame End -------------------------------------------------- function UGCGameState:GetGameTime() return self.GameTime end function UGCGameState:SetGameTime(NewTime) if UGCGameSystem.IsServer() then self.GameTime = NewTime end end function UGCGameState:ShowControlPanel() local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C") MainControlPanel:SetVisibility(ESlateVisibility.SelfHitTestInvisible) end --- 校准服务器时间 function UGCGameState:CalibrationServerGameTime(ServerGameTime) if UGCGameSystem.IsServer() then UGCSendRPCSystem.ActorRPCNotify(nil, self, "CalibrationServerGameTime", self:GetServerGameTime()) else self.ClientGameTimeDifference = UGCSystemLibrary.GetGameTime() - ServerGameTime end end --- 获取校准后的服务器时间 function UGCGameState:GetServerGameTime() if UGCGameSystem.IsServer() then return UGCSystemLibrary.GetGameTime() else return UGCSystemLibrary.GetGameTime() - self.ClientGameTimeDifference end end function UGCGameState:GetIsReadyState() return self.IsReadyState end function UGCGameState:SetIsReadyState(InIsReadyState) if self.IsReadyState ~= InIsReadyState then self.IsReadyState = InIsReadyState local AllPlayerPawn = UGCGameSystem.GetAllPlayerPawn() for i, v in pairs(AllPlayerPawn) do v:SetCanActionable(not self.IsReadyState) end end end ------------------------------------------------ GameState Abstract RPC ------------------------------------------------ function UGCGameState:UGCSendRPCSystemFunc(...) UGCSendRPCSystem.RPCFunc(...) end ---------------------------------------------- GameState Abstract RPC End ---------------------------------------------- function UGCGameState:GetAvailableServerRPCs() return "MulticastRPC_SpawnParticleAttachPlayer", "UGCSendRPCSystemFunc", "SendMovingActorsManagerRPC", "ClientMovingActorManagerSendRPC" end function UGCGameState:ReceiveTick(DeltaTime) if self.MoveActorManager ~= nil then self.MoveActorManager:Tick(DeltaTime); end end ---@param function UGCGameState:SendMovingActorsManagerRPC(FuncName, ...) if self:HasAuthority() then UnrealNetwork.CallUnrealRPC_Multicast(self, "SendMovingActorsManagerRPC", FuncName, ...); else if self.MoveActorManager == nil then self.MoveActorManager = require('Script.Blueprint.MiniLevelActor.JumpAndCrouch.MovingActorsManager') self.MoveActorManager:Init(self); end if self.MoveActorManager[FuncName] ~= nil and type(self.MoveActorManager[FuncName]) == 'function' then self.MoveActorManager[FuncName](self.MoveActorManager, ...); end end end function UGCGameState:ClientMovingActorManagerSendRPC(FuncName, ...) if self:HasAuthority() then if self.MoveActorManager[FuncName] ~= nil and type(self.MoveActorManager[FuncName]) == 'function' then self.MoveActorManager[FuncName](self.MoveActorManager, ...); end else local PC = STExtraGameplayStatics.GetFirstPlayerController(self) UnrealNetwork.CallUnrealRPC(PC, self, "ClientMovingActorManagerSendRPC", FuncName, ...); end end function UGCGameState:OnRep_MutuallyExclusiveUIInfo() for i, v in pairs(WidgetConfig.MutuallyExclusiveUI) do if v == self.MutuallyExclusiveUIInfo.UIType then WidgetManager:ShowPanel(v, false, table.unpack(self.MutuallyExclusiveUIInfo.ShowParams)) else WidgetManager:ClosePanel(v) end end end function UGCGameState:SetMutuallyExclusiveUI(UIType, Params) if Params == nil then Params = {} end if UIType ~= self.MutuallyExclusiveUIInfo.UIType or not table.isTablesEqual(Params, self.MutuallyExclusiveUIInfo.ShowParams) then self.MutuallyExclusiveUIInfo = {UIType = UIType, ShowParams = Params} end end --- 获取玩家总星星数 function UGCGameState:GetPlayerStar(InPlayerKey) local PlayerStarCount = ArchiveDataConfig.GetPlayerArchiveDataFromType(InPlayerKey, ArchiveDataConfig.EArchiveType.MapStar) local SumMapStar = 0 if PlayerStarCount then for i, v in pairs(PlayerStarCount) do SumMapStar = SumMapStar + v end end return SumMapStar end --- 获取玩家单关卡的星星数 function UGCGameState:GetPlayerStarFromMapType(InPlayerKey, InMapType) local PlayerStarCount = ArchiveDataConfig.GetPlayerArchiveDataFromType(InPlayerKey, ArchiveDataConfig.EArchiveType.MapStar) if PlayerStarCount and PlayerStarCount[InMapType] then return PlayerStarCount[InMapType] end return 0 end --- 设置玩家地图星星数 function UGCGameState:SetPlayerStarFromMapType(InPlayerKey, InMapType, MapStarCount, bShouldAddTip) local PlayerStarCount = ArchiveDataConfig.GetPlayerArchiveDataFromType(InPlayerKey, ArchiveDataConfig.EArchiveType.MapStar) local LastStarCount = 0 if PlayerStarCount == nil then PlayerStarCount = {} end if PlayerStarCount[InMapType] then LastStarCount = PlayerStarCount[InMapType] end if MapStarCount > LastStarCount then PlayerStarCount[InMapType] = MapStarCount ArchiveDataConfig.SavePlayerArchiveData(InPlayerKey, ArchiveDataConfig.EArchiveType.MapStar, PlayerStarCount) if bShouldAddTip then UGCSendRPCSystem.RPCEvent(InPlayerKey, EventEnum.AddTip, TipConfig.TipType.UnlockStar, MapStarCount) end self:UpdatePlayerAchievementProgress(InPlayerKey) end end --- 刷新玩家徽章 function UGCGameState:UpdatePlayerAchievementProgress(InPlayerKey) local PlayerStarCount = ArchiveDataConfig.GetPlayerArchiveDataFromType(InPlayerKey, ArchiveDataConfig.EArchiveType.MapStar) if PlayerStarCount == nil then PlayerStarCount = {} end local StarCountSum = 0 local PerfectMapCount = 0 for MiniMapType, StarCount in pairs(PlayerStarCount) do --UGCAchievementSystem.AddAchievementProgress(InPlayerKey, MiniMapType + MiniGameConfig.MapAchievementProgressAddID, StarCount) AchievementProgressConfig.SetAchievementProgress(InPlayerKey, MiniMapType + MiniGameConfig.MapAchievementProgressAddID, StarCount) StarCountSum = StarCountSum + StarCount if StarCount == 3 then PerfectMapCount = PerfectMapCount + 1 end end --UGCAchievementSystem.AddAchievementProgress(InPlayerKey, MiniGameConfig.StarCountAchievementID, StarCountSum) --UGCAchievementSystem.AddAchievementProgress(InPlayerKey, MiniGameConfig.PerfectMapCountAchievementID, PerfectMapCount) AchievementProgressConfig.SetAchievementProgress(InPlayerKey, MiniGameConfig.StarCountAchievementID, StarCountSum) end return UGCGameState;