1036 lines
35 KiB
Lua
1036 lines
35 KiB
Lua
---@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;
|