2025-01-04 23:00:19 +08:00

1036 lines
35 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---@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;