1036 lines
35 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
---@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
--- UIDPlayerNameTeamIDGenderPlatformGenderPlayerLevelSegmentLevelIconURL
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;