---@class UGCGameState_C:BP_UGCGameState_C --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} PlayerWeaponGradient = {}; -- 玩家的武器梯度 {PlayerKey = {WeaponID = uint, ..}} PlayerGradientGrade = {}; -- 玩家的武器梯度等级 {PlayerKey = Grade} PlayerDefaultMeleeWeapon = {}; -- 玩家选择的默认近战武器{PlayerKey = WeaponID} MapSelectionResult = nil; -- 地图选择结果 MapSelectionFinalResult = nil; -- 地图选择最终结果(包括随机之后的结果) PlayerSelectMapList = {}; -- 玩家选择的地图{PlayerKey = Enum.SelectMap} SelectMapInfo = {}; -- 选择地图的数量{Enum.SelectMap = uint} TeamScore = {}; -- 队伍得分信息 { TeamID = Score, ... } TeamHoldsTheKeyTime = {}; -- 队伍维持钥匙时间 PlayerHoldsTheKeyTime = {}; -- 玩家维持钥匙总时间 RoundNum = 0; -- 回合数 PlayerCoin = {}; -- 玩家拥有的钱 [PlayerKey] = uint RoundAlivePlayerBackpackInfo = {}; -- 回合内存活玩家背包的武器及配件信息 TempAllPlayerScores = {}; -- 临时玩家隐藏分 TeamPlayerAlive = {}; -- 队伍玩家存活信息 [TeamID] = {PlayerKey = bAlive} KeyOwner = -1; -- 钥匙拥有者 PlayerPurchasedWeapon = {}; -- 用于校验玩家购买的武器,仅校验一把 SpectateHandle = {}; -- 玩家观战的定时器 EnablePlayerSkillList = {}; -- 玩家的技能开关 }; function UGCGameState:GetReplicatedProperties() return "GameTime", "PlayerPersonalInfos", "WaitPlayerJoinTime", "GameStateType", "PlayerSaveWeaponSelect", "PlayerScoreDatas", "PlayerWeaponGradient", "PlayerGradientGrade", "PlayerDefaultMeleeWeapon", "PlayerRankDatas", "TeamScore", "MapSelectionResult", "SelectMapInfo", "MapSelectionFinalResult", "TeamHoldsTheKeyTime", "PlayerHoldsTheKeyTime", "RoundNum", "PlayerCoin", "TeamPlayerAlive", "KeyOwner", "EnablePlayerSkillList" end function UGCGameState:ReceiveBeginPlay() --屏蔽死亡盒子 -- self.IsShowDeadBox = false; self:AddBind() GlobalInit.Init() -- 开启滑铲State部分 self.bIsOpenShovelingAbility = true UGCSendRPCSystem.InitUGCSendRPCSystem(self, "UGCSendRPCSystemFunc") if UGCGameSystem.IsServer() then for i, v in pairs(CustomEnum.EPlayerSkill) do self.EnablePlayerSkillList[v] = 1; end -- 第一人称模式 if GlobalConfigs.GameModeSetting.bIsFPP then UGCSystemLibrary.SetFPPMode() end else UGCLogSystem.Log("[UGCGameState_ReceiveBeginPlay]") UGCLogSystem.SetEnableLog(false) end end function UGCGameState:ReceiveTick(DeltaTime) --UGCLogSystem.Log("[UGCGameState_ReceiveTick] ModeID:%s", tostring(UGCMultiMode.GetModeID())) 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) UGCEventSystem.AddListener(EventEnum.PlayerDeathInfo, self.PlayerDelaySpectate, self) self.CheckPlayerPurchasedWeaponHandle = UGCEventSystem.SetTimerLoop(self, self.CheckPlayerPurchasedWeapon, 1.) 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) UGCEventSystem.RemoveListener(EventEnum.PlayerDeathInfo, self.PlayerDelaySpectate, self) --UGCEventSystem.StopTimer(self.UpdateScoreTimeHandle) --self.UpdateScoreTimeHandle = nil if self.CheckPlayerPurchasedWeaponHandle then UGCEventSystem.StopTimer(self.CheckPlayerPurchasedWeaponHandle) end self.CheckPlayerPurchasedWeaponHandle = nil else end end function UGCGameState:PlayerLogin(PlayerPawn, PlayerKey) self:UpdatePlayerTeam(PlayerKey) self:GetUserInfo(PlayerKey) self:UpdatePlayerJoin() self:UpdateAllPlayerScoreDatas() self:GetPlayerArchiveInfos(PlayerKey) self:CheckFirstTimePlaying(PlayerKey) -- self:InitPlayerGradient(PlayerKey) self:UpdatePlayerRankDatas(PlayerKey, self:GetPlayerTeamIDByPlayerKey(PlayerKey)) self:UpdateTeamPlayerAlive() end function UGCGameState:PlayerExit(PlayerPawn, PlayerKey) self:UpdatePlayerJoin() self:UpdateAllPlayerScoreDatas() self:UpdateTeamPlayerAlive() -- self:InspectPlayerRankDatas() end function UGCGameState:PlayerDeadInfo(DeadPlayerKey) self:CheckKeyOwnerDead(DeadPlayerKey) self:UpdateTeamPlayerAlive() end --- 根据游戏队伍模式更新玩家队伍 ---@param PlayerKey uint function UGCGameState:UpdatePlayerTeam(PlayerKey) if GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.PersonalWarfare then local NewTeamID = self:GetNewTeamID() UGCTeamSystem.ChangePlayerTeamID(PlayerKey, NewTeamID) UGCLogSystem.Log("[UGCGameState_UpdatePlayerTeam] NewTeamID:%s", tostring(NewTeamID)) else --local TeamID = UGCPlayerStateSystem.GetTeamID(PlayerKey) --UGCLogSystem.Log("[UGCGameState_UpdatePlayerTeam] TeamID:%s", tostring(TeamID)) --UGCTeamSystem.ChangePlayerTeamID(PlayerKey, TeamID) 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 if not table.hasValue(self.PlayerRankDatas[TeamID], PlayerKey) then self.PlayerRankDatas[TeamID][#self.PlayerRankDatas[TeamID] + 1] = PlayerKey end -- self:InspectPlayerRankDatas() --self:SortPlayerRankDatas() end --- 检验RankDatas function UGCGameState:InspectPlayerRankDatas() --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 for TempTeamID, PlayerKeys in pairs(self.PlayerRankDatas) do for i = #PlayerKeys, 1, -1 do if UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKeys[i]) == nil then self.PlayerRankDatas[TempTeamID][i] = nil end end end 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:SavePlayerWeaponSelectArchiveData(PlayerKey) if self.PlayerArchiveInfos[PlayerKey] == nil then self.PlayerArchiveInfos[PlayerKey] = {} end self.PlayerArchiveInfos[PlayerKey].PlayerSaveWeaponSelect = self.PlayerSaveWeaponSelect[PlayerKey] UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID, self.PlayerArchiveInfos[PlayerKey]) end function UGCGameState:OnRep_PlayerSaveWeaponSelect() UGCEventSystem.SendEvent(EventEnum.PlayerSaveWeaponChange) end --- 判断玩家是否为第一次进入游戏 function UGCGameState:CheckFirstTimePlaying(PlayerKey) if self.PlayerArchiveInfos[PlayerKey] == nil then self.PlayerArchiveInfos[PlayerKey] = {} end if self.PlayerArchiveInfos[PlayerKey].PlayedTimes == nil then self.PlayerArchiveInfos[PlayerKey].PlayedTimes = 1 self:PlayerIsFirstTimePlaying(PlayerKey) else self.PlayerArchiveInfos[PlayerKey].PlayedTimes = 1 + self.PlayerArchiveInfos[PlayerKey].PlayedTimes end UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID, self.PlayerArchiveInfos[PlayerKey]) end function UGCGameState:PlayerIsFirstTimePlaying(PlayerKey) UGCEventSystem.SendEvent(EventEnum.PlayerFirstTimePlaying, PlayerKey) if table.hasValue(self.ControllerInitializationEndedPlayer, PlayerKey) then local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, TargetController, "Client_PlayerIsFirstTimePlaying") else UGCLogSystem.LogError("[UGCGameState_PlayerIsFirstTimePlaying] TargetController is nil") end else self.PlayerIsFirstTimePlayingCache[#self.PlayerIsFirstTimePlayingCache + 1] = PlayerKey end UGCLogSystem.Log("[UGCGameState_PlayerIsFirstTimePlaying]") 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 Succeed bool 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 Succeed bool 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 ResScoreDatas[PlayerState.PlayerKey] = table.DeepCopy(PlayerState.ScoreData) end end end self.PlayerScoreDatas = ResScoreDatas self:SortPlayerRankDatas() return ResScoreDatas 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:Server_ControllerInitFinish(PlayerKey) self.ControllerInitializationEndedPlayer[#self.ControllerInitializationEndedPlayer + 1] = PlayerKey UGCLogSystem.Log("[UGCGameState_Server_ControllerInitFinish]") -- 首次登录 if table.hasValue(self.PlayerIsFirstTimePlayingCache, PlayerKey) then -- self.PlayerIsFirstTimePlayingCache[PlayerKey] = nil table.removeValue(self.PlayerIsFirstTimePlayingCache, PlayerKey, true) local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) if UE.IsValid(TargetController) then -- UnrealNetwork.CallUnrealRPC(TargetController, TargetController, "Client_PlayerIsFirstTimePlaying") UGCSendRPCSystem.ActorRPCNotify(PlayerKey, TargetController, "Client_PlayerIsFirstTimePlaying") else UGCLogSystem.LogError("[UGCGameState_Server_ControllerInitFinish] TargetController is nil") end end end ------------------------------------------------ GameState WeaponGradient ------------------------------------------------ --- 初始化玩家武器梯度 function UGCGameState:InitPlayerGradient(PlayerKey) self.PlayerWeaponGradient[PlayerKey] = WeaponGradientManager.GetPlayerGradient(PlayerKey) UGCLogSystem.LogTree("[UGCGameState_InitPlayerGradient] " .. PlayerKey .. " PlayerWeaponGradient:", self.PlayerWeaponGradient[PlayerKey] ) DOREPONCE(self, "PlayerWeaponGradient") self:SetPlayerWeaponGrade(PlayerKey, 1, false) end function UGCGameState:GetPlayerWeaponGradientByPlayerKey(PlayerKey) return self.PlayerWeaponGradient[PlayerKey] end --- 获取玩家梯度等级 function UGCGameState:GetPlayerWeaponGrade(PlayerKey) return (self.PlayerGradientGrade[PlayerKey] and self.PlayerGradientGrade[PlayerKey] or 1) end --- 设置玩家梯度等级 ---@param PlayerKey uint ---@param NewGrade uint 新的玩家等级 ---@param bUpdateWeapon bool 是否刷新玩家武器 function UGCGameState:SetPlayerWeaponGrade(PlayerKey, NewGrade, bUpdateWeapon) self.PlayerGradientGrade[PlayerKey] = NewGrade DOREPONCE(self, "PlayerGradientGrade") if bUpdateWeapon then local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) local DefaultWeaponID = self:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey) WeaponGradientManager.UpdatePlayerGradientWeaponMatching(PlayerKey, NewGrade, DefaultWeaponID) if self.PlayerWeaponGradient[PlayerKey][NewGrade] < 0 then if UGCBackPackSystem.GetItemCount(PlayerPawn, DefaultWeaponID) <= 0 then UGCBackPackSystem.AddItem(PlayerPawn, DefaultWeaponID, 1) end UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MeleeWeapon, false) UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.AddTip, TipConfig.TipType.UseMeleeToKill) else UGCEventSystem.SetTimer(UGCGameSystem.GameState, function() PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if UE.IsValid(PlayerPawn) then UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MainShootWeapon1, false) end end, 0.5 ) end end end --- 根据玩家等级刷新玩家武器 function UGCGameState:RefreshPlayerWeapons(PlayerKey) local Grade = self:GetPlayerWeaponGrade(PlayerKey) WeaponGradientManager.UpdatePlayerGradientWeaponMatching(PlayerKey, Grade, self:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey)) UGCLogSystem.LogTree("[UGCGameState_RefreshPlayerWeapons]", self.PlayerWeaponGradient) if self.PlayerWeaponGradient[PlayerKey][Grade] < 0 then local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MeleeWeapon, true) end end function UGCGameState:GetPlayerNextWeaponID(PlayerKey) if self.PlayerWeaponGradient[PlayerKey] then return self.PlayerWeaponGradient[PlayerKey][self:GetPlayerWeaponGrade(PlayerKey) + 1] end return nil end --- 重置所有玩家的玩家等级,用于游戏开始阶段 function UGCGameState:ResetAllPlayerGrade() for PlayerKey, v in pairs(self.PlayerPersonalInfos) do self:SetPlayerWeaponGrade(PlayerKey, 1, true) end end --- 玩家增加等级 function UGCGameState:PlayerAddWeaponGrade(PlayerKey, AddGrade) local WeaponGradient = WeaponGradientManager.GetPlayerGradient(PlayerKey) local PlayerLastGrade = self:GetPlayerWeaponGrade(PlayerKey) if PlayerLastGrade == #WeaponGradient then self.PlayerWeaponGradient[PlayerKey] = WeaponGradientManager.UpdatePlayerNextGradient(PlayerKey) DOREPONCE(self, "PlayerWeaponGradient") self:SetPlayerWeaponGrade(PlayerKey, 1, true) self:AddScore(PlayerKey, GlobalConfigs.GameSetting.FullGradientAddScore) UGCLogSystem.LogTree("[UGCGameState_PlayerAddWeaponGrade] " .. PlayerKey .. " PlayerWeaponGradient:", self.PlayerWeaponGradient[PlayerKey]) UGCSendRPCSystem.RPCEvent(nil, EventEnum.AddTip, TipConfig.TipType.PlayerCompleteGradient, PlayerKey) else self:SetPlayerWeaponGrade(PlayerKey, math.clamp(AddGrade + PlayerLastGrade, 1, #WeaponGradient), true) end end --- 获取玩家选择的默认近战武器 function UGCGameState:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey) return self.PlayerDefaultMeleeWeapon[PlayerKey] and self.PlayerDefaultMeleeWeapon[PlayerKey] or GlobalConfigs.GameSetting.DefaultMeleeWeapon end ---------------------------------------------- GameState WeaponGradient End ---------------------------------------------- --------------------------------------------- SelectMap --------------------------------------------- function UGCGameState:SetMapSelectionResult(NewMapType) self.MapSelectionResult = NewMapType if self.MapSelectionResult == MapConfig.MapType.Random then self.MapSelectionFinalResult = table.Rand(self:GetEnableMapExcludeRandom()) else self.MapSelectionFinalResult = self.MapSelectionResult end DOREPONCE(self, "MapSelectionFinalResult") DOREPONCE(self, "MapSelectionResult") end --- 获取当前已选择好的地图Type ---@return MapSelectionResult MapConfig.MapType 若未选择则返回nil function UGCGameState:GetMapSelectionResult(bMustObtain) if bMustObtain and self.MapSelectionResult == nil then local MapTypes = self:GetMaxSameVotesMap() self:SetMapSelectionResult(table.Rand(MapTypes)) end return self.MapSelectionResult end function UGCGameState:GetMaxSameVotesMap() local MaxType = self:GetMaxAndSecondMapType() local Res = {} for i, v in pairs(self.SelectMapInfo) do if v == self.SelectMapInfo[MaxType] and MapConfig.GetMultiModeMapEnable()[i] then Res[#Res + 1] = i end end return Res end function UGCGameState:GetEnableMapExcludeRandom() local Res = {} for i, v in pairs(MapConfig.GetMultiModeMapEnable()) do if v and (i ~= MapConfig.MapType.Random) then Res[#Res + 1] = i end end return Res end function UGCGameState:GetMapSelectionFinalResult() return self.MapSelectionFinalResult end function UGCGameState:GetPlayerSelectMapList() return self.PlayerSelectMapList end ---@param MapType MapConfig.MapType function UGCGameState:PlayerSelectMap(PlayerKey, MapType) UGCLogSystem.Log("[UGCGameState_PlayerSelectMap] Begin") if self.PlayerSelectMapList[PlayerKey] == nil and table.hasValue(MapConfig.MapType, MapType) then self.PlayerSelectMapList[PlayerKey] = MapType if #self.SelectMapInfo == 0 then self:InitSelectMapInfo() end self.SelectMapInfo[MapType] = self.SelectMapInfo[MapType] + 1 DOREPONCE(self, "SelectMapInfo") local MaxSelectMap, SecondSelectMap = self:GetMaxAndSecondMapType() local SelectMapNum = self:GetSelectMapNum() local MaxSelectMapNum = self.SelectMapInfo[MaxSelectMap] local SecondSelectMapNum = (SecondSelectMap and self.SelectMapInfo[SecondSelectMap] or 0) if (MaxSelectMapNum - SecondSelectMapNum) > (GlobalConfigs.GameModeSetting.MaxPlayerNum - SelectMapNum) or (SelectMapNum == GlobalConfigs.GameModeSetting.MaxPlayerNum) then -- self:SetMapSelectionResult(MaxSelectMap) local MapTypes = self:GetMaxSameVotesMap() self:SetMapSelectionResult(table.Rand(MapTypes)) end UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, true, MapType) UGCLogSystem.Log("[UGCGameState_PlayerSelectMap] Finish") UGCLogSystem.LogTree("[UGCGameState_PlayerSelectMap] ", self.SelectMapInfo) else UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, false, MapType) end end function UGCGameState:InitSelectMapInfo() if #self.SelectMapInfo == 0 then for i, v in pairs(MapConfig.MapType) do self.SelectMapInfo[v] = 0 end end end function UGCGameState:GetSelectMapNumFromMapType(SelectMapType) return (self.SelectMapInfo[SelectMapType] and self.SelectMapInfo[SelectMapType] or 0) end function UGCGameState:GetSelectMapNum() local Sum = 0 for i, v in pairs(self.SelectMapInfo) do Sum = Sum + v end return Sum end function UGCGameState:GetMaxAndSecondMapType() local AllSelectType = {} if #self.SelectMapInfo == 0 then self:InitSelectMapInfo() end for i, v in pairs(self.SelectMapInfo) do AllSelectType[#AllSelectType + 1] = {MapType = i, Num = v} end table.sort(AllSelectType, function(a, b) return a.Num > b.Num end) UGCLogSystem.LogTree("[UGCGameState_GetMaxAndSecondMapType] AllSelectType", AllSelectType) return AllSelectType[1].MapType, AllSelectType[2].MapType end function UGCGameState:OnRep_MapSelectionFinalResult() self:LoadNowMiniMap() end function UGCGameState:LoadNowMiniMap(MapType) UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap]") if self:HasAuthority() or self.MapSelectionFinalResult == nil then UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap] self.MapSelectionFinalResult is nil") return end local MiniMapInfo if MapType then MiniMapInfo = MapConfig.GetMultiModeMapInfo()[MapType].MiniMapInfo else MiniMapInfo = MapConfig.GetMultiModeMapInfo()[self.MapSelectionFinalResult].MiniMapInfo end UGCLogSystem.LogTree("[UGCGameState_LoadNowMiniMap]", MiniMapInfo) UGCWidgetManagerSystem.ChangeMap(MiniMapInfo.MapPath, MiniMapInfo.MapCentre, MiniMapInfo.MapSize, MiniMapInfo.MapScale) UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap] Finish") end function UGCGameState:PlayerSelectDefaultWeapon(PlayerKey, WeaponID) if table.hasValue(WeaponGradientTable.DefaultWeapon, WeaponID) then self.PlayerDefaultMeleeWeapon[PlayerKey] = WeaponID UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectDefaultWeaponCallBack, true, WeaponID) else UGCLogSystem.LogError("[UGCGameState_PlayerSelectDefaultWeapon] PlayerKey:%s, 默认武器表内没有武器:%s", tostring(PlayerKey), tostring(WeaponID)) UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectDefaultWeaponCallBack, false, WeaponID) end end ------------------------------------------- SelectMap End ------------------------------------------- --------------------------------------------- PlayerPickKey --------------------------------------------- function UGCGameState:LoopUpdateTeamKeyTime() if self.UpdateTeamKeyTimeHandle == nil then self.UpdateTeamKeyTimeHandle = UGCEventSystem.SetTimerLoop(self, self.UpdateTeamKeyTime, 1) end end function UGCGameState:StopUpdateTeamKeyTime() if self.UpdateTeamKeyTimeHandle then self.UpdateTeamKeyTimeHandle = UGCEventSystem.StopTimer(self.UpdateTeamKeyTimeHandle) self.UpdateTeamKeyTimeHandle = nil -- 为维持精确数值 self:UpdateTeamKeyTime() end end function UGCGameState:ResetHoldsTheKeyTime() self.TeamHoldsTheKeyTime = {} -- self.PlayerHoldsTheKeyTime = {} end function UGCGameState:AddTeamHoldsTheKeyTime(PlayerKey, Time) local PlayerTeam = UGCPlayerStateSystem.GetTeamID(PlayerKey) if self.TeamHoldsTheKeyTime[PlayerTeam] == nil then self.TeamHoldsTheKeyTime[PlayerTeam] = Time else self.TeamHoldsTheKeyTime[PlayerTeam] = self.TeamHoldsTheKeyTime[PlayerTeam] + Time end if self.PlayerHoldsTheKeyTime[PlayerKey] == nil then self.PlayerHoldsTheKeyTime[PlayerKey] = Time else self.PlayerHoldsTheKeyTime[PlayerKey] = self.PlayerHoldsTheKeyTime[PlayerKey] + Time end end function UGCGameState:GetPlayerHoldsTheKeyTime(PlayerKey) return (self.PlayerHoldsTheKeyTime[PlayerKey] and self.PlayerHoldsTheKeyTime[PlayerKey] or 0) end function UGCGameState:OnRep_PlayerHoldsTheKeyTime() UGCEventSystem.SendEvent(EventEnum.PlayerHoldsTheKeyTimeUpdate) end function UGCGameState:OnRep_TeamHoldsTheKeyTime() UGCEventSystem.SendEvent(EventEnum.TeamHoldsTheKeyTimeUpdate, self.TeamHoldsTheKeyTime) end function UGCGameState:GetTeamHoldsTheKeyTimeFormTeamID(TeamID) if self:GetKeyOwner() > 0 and UGCPlayerStateSystem.GetTeamID(self:GetKeyOwner()) == TeamID then local NowTime = UGCSystemLibrary.GetGameTime() local AddTime = math.max(NowTime - self.KeyOwnerChangeTime, 0) if self.TeamHoldsTheKeyTime[TeamID] then return self.TeamHoldsTheKeyTime[TeamID] + AddTime else return AddTime end end return (self.TeamHoldsTheKeyTime[TeamID] and self.TeamHoldsTheKeyTime[TeamID] or 0) end function UGCGameState:GetKeyOwner() return self.KeyOwner and self.KeyOwner or -1 end function UGCGameState:SetKeyOwner(NewOwner) self.KeyOwner = NewOwner UGCEventSystem.SendEvent(EventEnum.KeyOwnerChange, self:GetKeyOwner()) UGCSendRPCSystem.RPCEvent(nil, EventEnum.KeyOwnerChange, self:GetKeyOwner(), UGCPlayerStateSystem.GetTeamID(self:GetKeyOwner())) end function UGCGameState:UpdateTeamKeyTime() if self:GetKeyOwner() < 0 then return end local TargetPlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self:GetKeyOwner()) local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self:GetKeyOwner()) if UE.IsValid(TargetPlayerState) and UE.IsValid(TargetPlayerPawn) and TargetPlayerPawn:IsAlive() then local NowTime = UGCSystemLibrary.GetGameTime() local AddTime = math.max(NowTime - self.KeyOwnerChangeTime, 0) self:AddTeamHoldsTheKeyTime(self:GetKeyOwner(), AddTime) self.KeyOwnerChangeTime = NowTime self.OwnerPlayerPos = TargetPlayerPawn:K2_GetActorLocation() -- 更新排行榜 self:SortPlayerRankDatas() else self:LeaveBehindKey(self.OwnerPlayerPos) UGCLogSystem.Log("[UGCGameState_UpdateTeamKeyTime] LeaveBehindKey") end end --- 判断Key拥有者是否死亡,死亡则掉落Key function UGCGameState:CheckKeyOwnerDead(DeadPlayerKey) if self:GetKeyOwner() > 0 and self:GetKeyOwner() == DeadPlayerKey then self:ShiftOutKeyFormOwnerPlayer(self.OwnerPlayerPos) end end --- 从拥有者身上移出到目标位置,作用于玩家死亡或玩家手动丢出 function UGCGameState:ShiftOutKeyFormOwnerPlayer(TargetPos) if self:GetKeyOwner() > 0 then local NowTime = UGCSystemLibrary.GetGameTime() local AddTime = math.max(NowTime - self.KeyOwnerChangeTime, 0) self:AddTeamHoldsTheKeyTime(self:GetKeyOwner(), AddTime) self.KeyOwnerChangeTime = NowTime self:LeaveBehindKey(TargetPos) end end function UGCGameState:UpdateKeyOwner(NewPlayerKey) self:UpdateTeamKeyTime() self.KeyOwnerChangeTime = UGCSystemLibrary.GetGameTime() self:SetKeyOwner(NewPlayerKey) local AllKey = GameplayStatics.GetAllActorsOfClass(self, ObjectPathTable.Key_Class, {}); for i, Key in pairs(AllKey) do if Key:GetbEnableKeyPickup() and not Key:GetIsRealKey() then Key:EnableKeyPickup(false) UGCSendRPCSystem.ActorRPCNotify(nil, Key, "SetTargetWidgetVis", false) end end end function UGCGameState:ResetKey() self:SetKeyOwner(-1) UGCEventSystem.SendEvent(EventEnum.ResetKey) self:ResetReadKey() end function UGCGameState:ResetReadKey() local AllKey = GameplayStatics.GetAllActorsOfClass(self, ObjectPathTable.Key_Class, {}); local RandomReadKey = KismetMathLibrary.RandomInteger(#AllKey) for i, v in pairs(AllKey) do v:SetIsRealKey(RandomReadKey == (i - 1)) end end function UGCGameState:LeaveBehindKey(TargetPos) self:SetKeyOwner(-1) UGCEventSystem.SendEvent(EventEnum.KeyOwnerDead, TargetPos) end function UGCGameState:PlayerDiscardsKey(PlayerKey) if PlayerKey == self:GetKeyOwner() and self:GetKeyOwner() > 0 then local OwnerPlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if OwnerPlayerPawn then -- UGCLogSystem.Log("[UGCGameState_PlayerDiscardsKey]") local ForwardDir = OwnerPlayerPawn:GetActorForwardVector() local AddDir = VectorHelper.MulNumber(ForwardDir, OwnerPlayerPawn.CapsuleComponent.CapsuleRadius + 120) local CenterPos = VectorHelper.Add(OwnerPlayerPawn:K2_GetActorLocation(), AddDir) local ObjectTypes = { ECollisionChannel.ECC_WorldStatic, ECollisionChannel.ECC_Pawn, }; CenterPos.Z = CenterPos.Z + 50 local bSucceed, HitRes = TraceManager.SphereTraceSingleForObjects(self, CenterPos, CenterPos, 100, ObjectTypes, UGCGameSystem.GetAllPlayerPawn(), false) if bSucceed then UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.AddTip, TipConfig.TipType.DiscardsKeyFailure) else CenterPos.Z = CenterPos.Z - 50 self:LeaveBehindKey(CenterPos) end end else UGCLogSystem.LogError("[UGCGameState_PlayerDiscardsKey] PlayerKey:%s ~= KeyOwner:%s", tostring(PlayerKey), tostring(self:GetKeyOwner())) end end ------------------------------------------- PlayerPickKey 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:GetReadyTime() return GlobalConfigs.GameModeSetting.RoundReadyTime - (GlobalConfigs.GameModeSetting.RoundTime - self:GetGameTime()) end ------------------------------------------- RoundFun End ------------------------------------------- --------------------------------------------- PlayerCoin --------------------------------------------- function UGCGameState:GetPlayerCoin(PlayerKey) if self.PlayerCoin[PlayerKey] then return self.PlayerCoin[PlayerKey] end return GlobalConfigs.GameSetting.BeginCoin end function UGCGameState:SetPlayerCoin(PlayerKey, Coin) if Coin > 0 then self.PlayerCoin[PlayerKey] = Coin else self.PlayerCoin[PlayerKey] = 0 end end function UGCGameState:AddPlayerCoin(PlayerKey, AddCoin) self:SetPlayerCoin(PlayerKey, self:GetPlayerCoin(PlayerKey) + AddCoin) end function UGCGameState:ResetAllPlayerGoldCoin() self.PlayerCoin = {} DOREPONCE(self, "PlayerCoin") end function UGCGameState:OnRep_PlayerCoin() UGCEventSystem.SendEvent(EventEnum.PlayerGoldCoinChange) end function UGCGameState:RoundFinishAddCoin() local Winner = self:GetWinner() local Round = self:GetRoundNum() local AllPlayer = UGCGameSystem.GetAllPlayerController() for i, PC in pairs(AllPlayer) do local PlayerKey = PC.PlayerKey self:AddPlayerCoin(PlayerKey, GlobalConfigs.RoundFinishAddCoin(Round, (Winner == UGCPlayerStateSystem.GetTeamID(PlayerKey)))) end end ------------------------------------------- PlayerCoin End ------------------------------------------- ------------------------------------------------ Buy ------------------------------------------------- --- 玩家购买 ---@param PlayerKey uint ---@param ItemID uint ---@param ItemCount uint function UGCGameState:PlayerBuy(PlayerKey, ItemID, ItemCount) local ItemPrice = ItemTable.GetItemPrice(ItemID) * ItemCount if self:GetPlayerCoin(PlayerKey) >= ItemPrice then local TargetPlayer = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if TargetPlayer then UGCBackPackSystem.AddItem(TargetPlayer, ItemID, ItemCount) self:AddPlayerCoin(PlayerKey, -ItemPrice) UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.PlayerBuyCallBack, true) end else UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.PlayerBuyCallBack, false) end end --- 玩家购买武器装备 ---@param PlayerKey uint ---@param ItemID uint ---@param ItemCount uint function UGCGameState:PlayerBuyWeapon(PlayerKey, ItemID, IsProps) UGCLogSystem.Log("[UGCGameState_PlayerBuyWeapon] PlayerKey:%s, ItemID:%s, IsProps:%s", tostring(PlayerKey), tostring(ItemID), tostring(IsProps)) local TargetPlayer = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if not UE.IsValid(TargetPlayer) then UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.PlayerBuyCallBack, false) return end local ItemPrice = 0 local PropIDs = {} local AddItems = {} local IsWeapon = ItemID > 100000 and ItemID < 200000 and table.hasKey(WeaponShopTable.WeaponKillRewards, ItemID) if IsWeapon then if IsProps then PropIDs = WeaponTable.GetRecommendedWeaponParts(ItemID) ItemPrice = WeaponShopTable.GetPropsPrice(PropIDs) AddItems = PropIDs else ItemPrice = WeaponShopTable.ItemPrice[ItemID] AddItems = {ItemID} if self:GetPlayerCoin(PlayerKey) >= ItemPrice then self.PlayerPurchasedWeapon[PlayerKey] = ItemID end end else ItemPrice = WeaponShopTable.GetNonWeaponPrice(ItemID) end if self:GetPlayerCoin(PlayerKey) >= ItemPrice then self:AddPlayerCoin(PlayerKey, -ItemPrice) for i, v in pairs(AddItems) do UGCBackPackSystem.AddItem(TargetPlayer, v, 1) end UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.PlayerBuyCallBack, true) UGCEventSystem.SetTimer(self, function() UGCSystemLibrary.FullAllWeaponBullet(TargetPlayer) end, 1) else UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.PlayerBuyCallBack, false) end end --- 检查玩家购买的武器 function UGCGameState:CheckPlayerPurchasedWeapon() if table.getCount(self.PlayerPurchasedWeapon) > 0 then local PurchasedKeys = table.getKeys(self.PlayerPurchasedWeapon) for i, PlayerKey in pairs(PurchasedKeys) do local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if PlayerPawn then local WeaponID = self.PlayerPurchasedWeapon[PlayerKey] if UGCBackPackSystem.GetItemCount(PlayerPawn, WeaponID) >= 1 then self.PlayerPurchasedWeapon[PlayerKey] = nil else UGCBackPackSystem.AddItem(PlayerPawn, WeaponID, 1) end else self.PlayerPurchasedWeapon[PlayerKey] = nil end end end end ---------------------------------------------- Buy End ----------------------------------------------- ---------------------------------------------- Buy End ----------------------------------------------- ---------------------------------------------- Record player backpack info ---------------------------------------------- function UGCGameState:RecordPlayerBackpackInfo() self.RoundAlivePlayerBackpackInfo = {} local AllPawn = UGCGameSystem.GetAllPlayerPawn() for i, TempPawn in pairs(AllPawn) do if TempPawn:IsAlive() and TempPawn.PlayerKey then local RecordInfo = {} local AllItemDatas = UGCBackPackSystem.GetAllItemData(TempPawn) -- ItemID,InstanceID,Count,Type,SubType,IsAvatar for _, ItemData in pairs(AllItemDatas) do if ItemData.ItemID < 300000 and ItemData.ItemID > 100000 and not self:CheckItemInBornItems(ItemData.ItemID) then if RecordInfo[ItemData.ItemID] then RecordInfo[ItemData.ItemID] = RecordInfo[ItemData.ItemID] + ItemData.Count else RecordInfo[ItemData.ItemID] = ItemData.Count end end end self.RoundAlivePlayerBackpackInfo[TempPawn.PlayerKey] = table.DeepCopy(RecordInfo) end end UGCLogSystem.LogTree("[UGCGameState_RecordPlayerBackpackInfo]", self.RoundAlivePlayerBackpackInfo) end function UGCGameState:CheckItemInBornItems(ItemID) for i, v in pairs(GlobalConfigs.GameSetting.BeBornItems) do if ItemID == v.ItemID then return true end end return false end function UGCGameState:EnableLoopAddPlayerRecordBackpack() if self.AddPlayerRecordBackpackHandle == nil and table.getCount(self.RoundAlivePlayerBackpackInfo) > 0 then self.AddPlayerRecordBackpackHandle = UGCEventSystem.SetTimerLoop(self, self.AddPlayerRecordBackpack, 0.5) end end function UGCGameState:AddPlayerRecordBackpack() UGCLogSystem.LogTree("[UGCGameState_AddPlayerRecordBackpack]", self.RoundAlivePlayerBackpackInfo) -- Data: {ItemID = Count} for PlayerKey, Data in pairs(self.RoundAlivePlayerBackpackInfo) do local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey) if PlayerPawn then for ItemID, Count in pairs(Data) do local ItemCount = UGCBackPackSystem.GetItemCount(PlayerPawn, ItemID) if ItemCount < Count then UGCBackPackSystem.AddItem(PlayerPawn, ItemID, 1) else self.RoundAlivePlayerBackpackInfo[PlayerKey][ItemID] = nil end end UGCLogSystem.LogTree("[UGCGameState_AddPlayerRecordBackpack] PlayerKey:".. tostring(PlayerKey), self.RoundAlivePlayerBackpackInfo[PlayerKey]) if table.getCount(self.RoundAlivePlayerBackpackInfo[PlayerKey]) <= 0 then self.RoundAlivePlayerBackpackInfo[PlayerKey] = nil end else if UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) == nil then self.RoundAlivePlayerBackpackInfo[PlayerKey] = nil end end end if table.getCount(self.RoundAlivePlayerBackpackInfo) <= 0 then UGCEventSystem.StopTimer(self.AddPlayerRecordBackpackHandle) self.AddPlayerRecordBackpackHandle = nil end end -------------------------------------------- Record player backpack info 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 -------------------------------------------- ---------------------------------------------------- KeyMapSetting ---------------------------------------------------- ---@param ButtonsRender {[Index] = {TargetWidgetName = string, Pos = FVector2D, Scale = float}} Index对应AllButtons的Index function UGCGameState:Server_SaveButtonSetting(PlayerKey, ButtonsRender) self:SaveButtonSettingArchiveData(PlayerKey, ButtonsRender) UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.ButtonSettingCallBack, ButtonsRender) end function UGCGameState:Server_GetButtonSetting(PlayerKey) local ButtonsRender = {} if self.PlayerArchiveInfos[PlayerKey] and self.PlayerArchiveInfos[PlayerKey].ButtonSetting then ButtonsRender = self.PlayerArchiveInfos[PlayerKey].ButtonSetting end UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.ButtonSettingCallBack, ButtonsRender) end -- 保存键位设置 function UGCGameState:SaveButtonSettingArchiveData(PlayerKey, ButtonsRender) if self.PlayerArchiveInfos[PlayerKey] == nil then self.PlayerArchiveInfos[PlayerKey] = {} end self.PlayerArchiveInfos[PlayerKey].ButtonSetting = ButtonsRender UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID, self.PlayerArchiveInfos[PlayerKey]) end -------------------------------------------------- KeyMapSetting End -------------------------------------------------- -------------------------------------------------- Spectate -------------------------------------------------- --function UGCGameState:PlayerSpectate(PlayerKey) -- -- if UGCGameSystem.IsServer() then -- local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) -- if UE.IsValid(PC) then -- if GlobalConfigs.SpectateAllPlayer then -- --观战所有玩家 -- local OBPlayerKeys = {} -- local PlayerControllerList = UGCGameSystem.GetAllPlayerController() -- for _, PlayerController in ipairs(PlayerControllerList) do -- if PlayerController and PlayerController ~= self and UE.IsValid(PlayerController.Pawn) and PlayerController.Pawn:IsAlive() then -- table.insert(OBPlayerKeys, PlayerController.PlayerKey) -- end -- end -- UGCGameSystem.EnterSpectating(PC) --进入观战 -- UGCGameSystem.ChangeAllowOBPlayerKeys(PC, OBPlayerKeys) --设置该玩家可以观战所有玩家。 -- -- UGCLogSystem.Log("[UGCPlayerController_SpectateOther] PlayerKey:%s", tostring(self.PlayerKey)) -- UGCLogSystem.LogTree("[UGCPlayerController_SpectateOther] OBPlayerKeys:", OBPlayerKeys) -- else -- -- 默认观看队友 -- UGCGameSystem.EnterSpectating(PC) --进入观战 -- end -- UGCSendRPCSystem.ActorRPCNotify(PlayerKey, self, "PlayerSpectate", PlayerKey) -- else -- UGCLogSystem.LogError("[UGCGameState_PlayerSpectate] PC is nil. PlayerKey:%s", tostring(PlayerKey)) -- end -- -- else -- local PC = UGCSystemLibrary.GetLocalPlayerController() -- PC.IsSpectateOther = true -- PC:CastUIMsg("UIMsg_HideQuitWatch", ""); -- UGCEventSystem.SetTimer(self, function() -- PC:CastUIMsg("UIMsg_HideQuitWatch", ""); -- end, 1.) -- end --end function UGCGameState:PlayerDelaySpectate(VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue, Assister) local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(VictimKey) if UE.IsValid(PC) then UGCGameSystem.MyObserversChangeTarget(PC) self.SpectateHandle[VictimKey] = UGCEventSystem.SetTimer(self, function() self.SpectateHandle[VictimKey] = nil PC = UGCGameSystem.GetPlayerControllerByPlayerKey(VictimKey) if UE.IsValid(PC) then PC:SpectateOther() else UGCLogSystem.LogError("[UGCGameState_PlayerDelaySpectate] PC is nil --- 2. VictimKey:%s", tostring(VictimKey)) end end , 2.) else UGCLogSystem.LogError("[UGCGameState_PlayerDelaySpectate] PC is nil. VictimKey:%s", tostring(VictimKey)) end end function UGCGameState:CleanSpectateHandle() for i, v in pairs(self.SpectateHandle) do UGCEventSystem.StopTimer(v) end self.SpectateHandle = {} end ------------------------------------------------ Spectate End ------------------------------------------------ function UGCGameState:SetEnablePlayerSkill(SkillType, IsEnable) self.EnablePlayerSkillList[SkillType] = IsEnable and 1 or 0 end function UGCGameState:GetEnablePlayerSkill(SkillType) return self.EnablePlayerSkillList[SkillType] > 0 end function UGCGameState:OnRep_EnablePlayerSkillList() UGCEventSystem.SendEvent(EventEnum.EnablePlayerSkillListUpdate) end function UGCGameState:GetGameTime() return self.GameTime end function UGCGameState:SetGameTime(NewTime) if UGCGameSystem.IsServer() then self.GameTime = NewTime else UGCLogSystem.LogError("[UGCGameState_SetGameTime] 客户端无法设置游戏时间") end end function UGCGameState:OnRep_PlayerGradientGrade() UGCEventSystem.SendEvent(EventEnum.PlayerGradientGradeChange) end function UGCGameState:ShowControlPanel() local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C") MainControlPanel:SetVisibility(ESlateVisibility.SelfHitTestInvisible) end ------------------------------------------------ GameState Abstract RPC ------------------------------------------------ function UGCGameState:UGCSendRPCSystemFunc(...) UGCSendRPCSystem.RPCFunc(...) end ---------------------------------------------- GameState Abstract RPC End ---------------------------------------------- function UGCGameState:GetAvailableServerRPCs() return "MulticastRPC_SpawnParticleAttachPlayer", "UGCSendRPCSystemFunc", "Server_ControllerInitFinish", "Server_SaveButtonSetting", "Server_GetButtonSetting" end return UGCGameState;