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

931 lines
34 KiB
Lua
Raw 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
--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, Score = float, TechnicalScore = float}...}
PlayerRankDatas = {}; -- 玩家排行信息{[TeamID] = {{PlayerKey = uint}, ... }
PlayerJoinNum = 0; -- 玩家加入的数量作为个人TeamID
PlayerSaveWeaponSelect = {}; -- 玩家存档中的武器选择 {[PlayerKey] = {WeaponID = int32, PropID = int32}}
PlayerArchiveInfos = {}; -- 玩家存档{[PlayerKey] = ArchiveData}
ControllerInitializationEndedPlayer = {}; -- 控制器初始化完成的玩家{PlayerKey}
PlayerIsFirstTimePlayingCache = {}; -- 客户端需执行首次登录函数的玩家{PlayerKey}
PlayerWeaponGradient = {}; -- 玩家的武器梯度 {PlayerKey = {WeaponID = uint, ..}}
PlayerGradientGrade = {}; -- 玩家的武器梯度等级 {PlayerKey = Grade}
PlayerDefaultMeleeWeapon = {}; -- 玩家选择的默认近战武器{PlayerKey = WeaponID}
MapSelectionResult = nil; -- 地图选择结果
MapSelectionFinalResult = nil; -- 地图选择最终结果(包括随机之后的结果)
PlayerSelectMapList = {}; -- 玩家选择的地图{PlayerKey = Enum.SelectMap}
SelectMapInfo = {}; -- 选择地图的数量{Enum.SelectMap = uint}
TeamScore = {}; -- 队伍得分信息 { TeamID = Score, ... }
PlayerIsAlive = {}; -- 玩家是否存活
---test
DoOnceAddJoinPlayer = false;
};
function UGCGameState:GetReplicatedProperties()
return
"GameTime",
"PlayerPersonalInfos",
"WaitPlayerJoinTime",
"GameStateType",
"PlayerSaveWeaponSelect",
"PlayerScoreDatas",
"PlayerWeaponGradient",
"PlayerGradientGrade",
"PlayerDefaultMeleeWeapon",
"DoOnceAddJoinPlayer",
"PlayerRankDatas",
"TeamScore",
"MapSelectionResult",
"SelectMapInfo",
"MapSelectionFinalResult",
"PlayerIsAlive"
end
function UGCGameState:ReceiveBeginPlay()
--屏蔽死亡盒子
self.IsShowDeadBox = false;
self:AddBind()
GlobalInit.Init()
-- 开启滑铲State部分
self.bIsOpenShovelingAbility = true
UGCSendRPCSystem.InitUGCSendRPCSystem(self, "UGCSendRPCSystemFunc")
if UGCGameSystem.IsServer() then
else
UGCLogSystem.Log("[UGCGameState_ReceiveBeginPlay]")
UGCLogSystem.SetEnableLog(false)
end
end
function UGCGameState:ReceiveTick(DeltaTime)
--UGCLogSystem.Log("[UGCGameState_ReceiveTick] ModeID:%s", tostring(UGCMultiMode.GetModeID()))
end
function UGCGameState:ReceiveEndPlay()
self:RemoveBind()
end
function UGCGameState:AddBind()
if self:HasAuthority() then
UGCEventSystem.AddListener(EventEnum.PlayerLogin, self.PlayerLogin, self)
UGCEventSystem.AddListener(EventEnum.PlayerExit, self.PlayerExit, self)
self.ClearPickUpHandle = UGCEventSystem.SetTimerLoop(self, self.ClearPickUpItem, 1)
else
end
end
function UGCGameState:RemoveBind()
if self:HasAuthority() then
UGCEventSystem.RemoveListener(EventEnum.PlayerLogin, self.PlayerLogin, self)
UGCEventSystem.RemoveListener(EventEnum.PlayerExit, self.PlayerExit, self)
if self.ClearPickUpHandle then
UGCEventSystem.StopTimer(self.ClearPickUpHandle)
self.ClearPickUpHandle = nil
end
else
end
end
function UGCGameState:ClearPickUpItem()
UGCSystemLibrary.ClearPickUpActor({108001, 108002, 108003, 108004})
end
function UGCGameState:PlayerLogin(PlayerPawn, PlayerKey)
self:UpdatePlayerTeam(PlayerKey)
self:GetUserInfo(PlayerKey)
self:UpdatePlayerJoin()
self:UpdateAllPlayerScoreDatas()
self:GetPlayerArchiveInfos(PlayerKey)
self:CheckFirstTimePlaying(PlayerKey)
self:InitPlayerGradient(PlayerKey)
self:UpdatePlayerRankDatas(PlayerKey, self:GetPlayerTeamIDByPlayerKey(PlayerKey))
end
function UGCGameState:PlayerExit(PlayerPawn, PlayerKey)
self:UpdatePlayerJoin()
self:UpdateAllPlayerScoreDatas()
if GlobalConfigs.GameSetting.EnablePlayerJoin then
self:InspectPlayerRankDatas()
end
end
--- 根据游戏队伍模式更新玩家队伍
---@param PlayerKey uint
function UGCGameState:UpdatePlayerTeam(PlayerKey)
if GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.PersonalWarfare then
local NewTeamID = self:GetNewTeamID()
UGCTeamSystem.ChangePlayerTeamID(PlayerKey, NewTeamID)
UGCLogSystem.Log("[UGCGameState_UpdatePlayerTeam] NewTeamID:%s", tostring(NewTeamID))
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 aScore > bScore
-- end)
-- end
--end
--- 对玩家在队伍中进行排序
function UGCGameState:SortPlayerRankDatas()
if #self.PlayerRankDatas < 1 then return end
for i, v in pairs(self.PlayerRankDatas) do
for Index = #v, 1, -1 do
if self.PlayerScoreDatas[v[Index]] == nil then
self.PlayerRankDatas[i][Index] = nil
end
end
end
local LocalGetScore = function(PlayerKey)
if self.PlayerScoreDatas[PlayerKey] == nil or self.PlayerScoreDatas[PlayerKey].Score == nil then
return 0
else
return self.PlayerScoreDatas[PlayerKey].Score
end
end
local LocalGetTechnicalScore = function(PlayerKey)
if self.PlayerScoreDatas[PlayerKey] == nil or self.PlayerScoreDatas[PlayerKey].TechnicalScore == nil then
return 0
else
return self.PlayerScoreDatas[PlayerKey].TechnicalScore
end
end
for i, v in pairs(self.PlayerRankDatas) do
table.sort(self.PlayerRankDatas[i], function(a, b)
local aScore = LocalGetScore(a) + LocalGetTechnicalScore(a) * GlobalConfigs.GameSetting.TechnicalScoreProportion
local bScore = LocalGetScore(b) + LocalGetTechnicalScore(b) * GlobalConfigs.GameSetting.TechnicalScoreProportion
return aScore > bScore
end)
end
end
--- 更新玩家排序信息
function UGCGameState:UpdatePlayerRankDatas(PlayerKey, TeamID)
if self.PlayerRankDatas[TeamID] == nil then
self.PlayerRankDatas[TeamID] = {}
end
if not table.hasValue(self.PlayerRankDatas[TeamID], PlayerKey) then
self.PlayerRankDatas[TeamID][#self.PlayerRankDatas[TeamID] + 1] = PlayerKey
end
if GlobalConfigs.GameSetting.EnablePlayerJoin then
self:InspectPlayerRankDatas()
end
--self:SortPlayerRankDatas()
end
--- 检验RankDatas
function UGCGameState:InspectPlayerRankDatas()
for TempTeamID, PlayerKeys in pairs(self.PlayerRankDatas) do
for i = #PlayerKeys, 1, -1 do
if UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKeys[i]) == nil then
self.PlayerRankDatas[TempTeamID][i] = nil
end
end
--for i, TempPlayerKey in pairs(PlayerKeys) do
-- if UGCGameSystem.GetPlayerControllerByPlayerKey(TempPlayerKey) == nil then
-- self.PlayerRankDatas[TempTeamID][TempPlayerKey] = nil
-- end
--end
end
end
function UGCGameState:GetPlayerRankByPlayerKey(PlayerKey)
local TeamID = self:GetPlayerTeamIDByPlayerKey(PlayerKey)
if self.PlayerRankDatas[TeamID] == nil then return 0 end
return table.FindKey(self.PlayerRankDatas[TeamID], PlayerKey)
end
function UGCGameState:OnRep_PlayerRankDatas()
UGCEventSystem.SendEvent(EventEnum.UpdatePlayerRank)
end
function UGCGameState:GetPlayerRank()
return self.PlayerRankDatas
end
--- 获取存档
function UGCGameState:GetPlayerArchiveInfos(PlayerKey)
self.PlayerArchiveInfos[PlayerKey] = UGCPlayerStateSystem.GetPlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID)
if self.PlayerArchiveInfos[PlayerKey] then
self.PlayerSaveWeaponSelect[PlayerKey] = self.PlayerArchiveInfos[PlayerKey].PlayerSaveWeaponSelect
end
end
--- 获取存档信息
---@param PlayerKey
function UGCGameState:GetPlayerArchiveInfosFromArchiveType(PlayerKey, ArchiveType)
if self.PlayerArchiveInfos[PlayerKey] == nil then
if self.PlayerPersonalInfos[PlayerKey] then
self.PlayerArchiveInfos[PlayerKey] = UGCPlayerStateSystem.GetPlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID)
else
UGCLogSystem.LogError("[UGCGameState_GetPlayerArchiveInfosFromArchiveType] PlayerPersonalInfos[%s] is nil", tostring(PlayerKey))
end
end
if ArchiveType == nil then
return self.PlayerArchiveInfos[PlayerKey]
elseif type(ArchiveType) == "table" then
local Res = nil
for i, v in pairs(ArchiveType) do
if Res == nil then
Res = self.PlayerArchiveInfos[PlayerKey][v]
else
Res = Res[v]
end
if Res == nil then
return nil
end
end
return Res
else
return self.PlayerArchiveInfos[PlayerKey][ArchiveType]
end
end
--- 保存武器选择存档
function UGCGameState:SavePlayerWeaponSelectArchiveData(PlayerKey)
if self.PlayerArchiveInfos[PlayerKey] == nil then
self.PlayerArchiveInfos[PlayerKey] = {}
end
self.PlayerArchiveInfos[PlayerKey].PlayerSaveWeaponSelect = self.PlayerSaveWeaponSelect[PlayerKey]
UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID, self.PlayerArchiveInfos[PlayerKey])
end
function UGCGameState:OnRep_PlayerSaveWeaponSelect()
UGCEventSystem.SendEvent(EventEnum.PlayerSaveWeaponChange)
end
--- 判断玩家是否为第一次进入游戏
function UGCGameState:CheckFirstTimePlaying(PlayerKey)
if self.PlayerArchiveInfos[PlayerKey] == nil then
self.PlayerArchiveInfos[PlayerKey] = {}
end
if self.PlayerArchiveInfos[PlayerKey].PlayedTimes == nil then
self.PlayerArchiveInfos[PlayerKey].PlayedTimes = 1
self:PlayerIsFirstTimePlaying(PlayerKey)
else
self.PlayerArchiveInfos[PlayerKey].PlayedTimes = 1 + self.PlayerArchiveInfos[PlayerKey].PlayedTimes
end
UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerPersonalInfos[PlayerKey].UID, self.PlayerArchiveInfos[PlayerKey])
end
function UGCGameState:PlayerIsFirstTimePlaying(PlayerKey)
UGCEventSystem.SendEvent(EventEnum.PlayerFirstTimePlaying, PlayerKey)
if table.hasValue(self.ControllerInitializationEndedPlayer, PlayerKey) then
local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey)
if UE.IsValid(TargetController) then
UnrealNetwork.CallUnrealRPC(TargetController, TargetController, "Client_PlayerIsFirstTimePlaying")
else
UGCLogSystem.LogError("[UGCGameState_PlayerIsFirstTimePlaying] TargetController is nil")
end
else
self.PlayerIsFirstTimePlayingCache[#self.PlayerIsFirstTimePlayingCache + 1] = PlayerKey
end
UGCLogSystem.Log("[UGCGameState_PlayerIsFirstTimePlaying]")
end
-- 玩家已选择队伍
function UGCGameState:PlayerHasSelectedTeam(PlayerKey)
if self.PlayerPersonalInfos[PlayerKey] == nil or self.PlayerPersonalInfos[PlayerKey].IsSelectTeam == false then
return false
end
return true
end
---@param PlayerKey int32
---@param AddScore float
---@return Succeed bool
function UGCGameState:AddScore(PlayerKey, AddScore)
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
if UE.IsValid(TargetPlayerState) then
TargetPlayerState:SetScore(TargetPlayerState:GetScore() + AddScore)
self.PlayerScoreDatas[PlayerKey].Score = TargetPlayerState:GetScore()
--DOREPONCE(self, "PlayerScoreDatas")
self:SortPlayerRankDatas()
self:AddTeamScore(self:GetPlayerTeamIDByPlayerKey(PlayerKey), AddScore)
return true
end
return false
end
function UGCGameState:GetPlayerScore(PlayerKey)
if self.PlayerScoreDatas[PlayerKey].Score then
return self.PlayerScoreDatas[PlayerKey].Score
else
return 0
end
end
function UGCGameState:GetTeamScore(TeamID)
if UGCGameSystem.GameState:GetSpecialModeType() == MapConfig.ESpecialModeType.ArmsRace then
local PlayerKey = self.PlayerRankDatas[TeamID][1]
if PlayerKey then
return self:GetPlayerScore(PlayerKey)
else
return 0
end
end
return (self.TeamScore[TeamID] and self.TeamScore[TeamID] or 0)
end
function UGCGameState:ResetTeamScore()
self.TeamScore = {}
end
function UGCGameState:AddTeamScore(TeamID, Score)
self.TeamScore[TeamID] = self:GetTeamScore(TeamID) + Score
end
---@param PlayerKey int32
---@param AddTechnicalScore float
---@return Succeed bool
function UGCGameState:AddTechnicalScore(PlayerKey, AddTechnicalScore)
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
if UE.IsValid(TargetPlayerState) then
TargetPlayerState:SetTechnicalScore(TargetPlayerState:GetTechnicalScore() + AddTechnicalScore)
self.PlayerScoreDatas[PlayerKey].TechnicalScore = TargetPlayerState:GetTechnicalScore()
self:SortPlayerRankDatas()
return true
end
return false
end
-- 更新返回所有玩家得分
function UGCGameState:UpdateAllPlayerScoreDatas()
local AllPlayerState = UGCGameSystem.GetAllPlayerState(false)
local ResScoreDatas = {}
if AllPlayerState then
for _, PlayerState in pairs(AllPlayerState) do
if UE.IsValid(PlayerState) and self.PlayerPersonalInfos[PlayerState.PlayerKey] and self.PlayerPersonalInfos[PlayerState.PlayerKey].IsOffline == false then
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:Server_ControllerInitFinish(PlayerKey)
self.ControllerInitializationEndedPlayer[#self.ControllerInitializationEndedPlayer + 1] = PlayerKey
UGCLogSystem.Log("[UGCGameState_Server_ControllerInitFinish]")
-- 首次登录
if table.hasValue(self.PlayerIsFirstTimePlayingCache, PlayerKey) then
-- self.PlayerIsFirstTimePlayingCache[PlayerKey] = nil
table.removeValue(self.PlayerIsFirstTimePlayingCache, PlayerKey, true)
local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey)
if UE.IsValid(TargetController) then
UnrealNetwork.CallUnrealRPC(TargetController, TargetController, "Client_PlayerIsFirstTimePlaying")
else
UGCLogSystem.LogError("[UGCGameState_Server_ControllerInitFinish] TargetController is nil")
end
end
end
------------------------------------------------ GameState WeaponGradient ------------------------------------------------
--- 初始化玩家武器梯度
function UGCGameState:InitPlayerGradient(PlayerKey)
self.PlayerWeaponGradient[PlayerKey] = WeaponGradientManager.GetPlayerGradient(PlayerKey)
UGCLogSystem.LogTree("[UGCGameState_InitPlayerGradient] " .. PlayerKey .. " PlayerWeaponGradient:", self.PlayerWeaponGradient[PlayerKey] )
DOREPONCE(self, "PlayerWeaponGradient")
self:SetPlayerWeaponGrade(PlayerKey, 1, false)
end
function UGCGameState:OnRep_PlayerWeaponGradient()
UGCEventSystem.SendEvent(EventEnum.PlayerGradientGradeChange)
end
function UGCGameState:GetPlayerWeaponGradientByPlayerKey(PlayerKey)
return self.PlayerWeaponGradient[PlayerKey]
end
--- 获取玩家梯度等级
function UGCGameState:GetPlayerWeaponGrade(PlayerKey)
return (self.PlayerGradientGrade[PlayerKey] and self.PlayerGradientGrade[PlayerKey] or 1)
end
--- 设置玩家梯度等级
---@param PlayerKey uint
---@param NewGrade uint 新的玩家等级
---@param bUpdateWeapon bool 是否刷新玩家武器
function UGCGameState:SetPlayerWeaponGrade(PlayerKey, NewGrade, bUpdateWeapon)
self.PlayerGradientGrade[PlayerKey] = NewGrade
DOREPONCE(self, "PlayerGradientGrade")
if bUpdateWeapon then
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
local DefaultWeaponID = self:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey)
WeaponGradientManager.UpdatePlayerGradientWeaponMatching(PlayerKey, NewGrade, DefaultWeaponID)
if self.PlayerWeaponGradient[PlayerKey][NewGrade] < 0 then
if UGCBackPackSystem.GetItemCount(PlayerPawn, DefaultWeaponID) <= 0 then
UGCBackPackSystem.AddItem(PlayerPawn, DefaultWeaponID, 1)
end
UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MeleeWeapon, false)
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.AddTip, TipConfig.TipType.UseMeleeToKill)
else
UGCEventSystem.SetTimer(UGCGameSystem.GameState,
function()
PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
if UE.IsValid(PlayerPawn) then
if UGCWeaponManagerSystem.GetWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MainShootWeapon1) then
UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MainShootWeapon1, false)
else
UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MainShootWeapon2, false)
UGCLogSystem.LogError("[UGCGameState_SetPlayerWeaponGrade] 插槽位错误")
end
end
end,
0.5
)
end
end
end
--- 根据玩家等级刷新玩家武器
function UGCGameState:RefreshPlayerWeapons(PlayerKey)
local Grade = self:GetPlayerWeaponGrade(PlayerKey)
WeaponGradientManager.UpdatePlayerGradientWeaponMatching(PlayerKey, Grade, self:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey))
UGCLogSystem.LogTree("[UGCGameState_RefreshPlayerWeapons]", self.PlayerWeaponGradient)
if self.PlayerWeaponGradient[PlayerKey][Grade] < 0 then
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
UGCWeaponManagerSystem.SwitchWeaponBySlot(PlayerPawn, ESurviveWeaponPropSlot.SWPS_MeleeWeapon, true)
end
end
function UGCGameState:GetPlayerNextWeaponID(PlayerKey)
if self.PlayerWeaponGradient[PlayerKey] then
return self.PlayerWeaponGradient[PlayerKey][self:GetPlayerWeaponGrade(PlayerKey) + 1]
end
return nil
end
--- 重置所有玩家的玩家等级,用于游戏开始阶段
function UGCGameState:ResetAllPlayerGrade()
for PlayerKey, v in pairs(self.PlayerPersonalInfos) do
self:SetPlayerWeaponGrade(PlayerKey, 1, true)
end
end
--- 玩家增加等级
function UGCGameState:PlayerAddWeaponGrade(PlayerKey, AddGrade)
local WeaponGradient = WeaponGradientManager.GetPlayerGradient(PlayerKey)
local PlayerLastGrade = self:GetPlayerWeaponGrade(PlayerKey)
if PlayerLastGrade == #WeaponGradient then
self.PlayerWeaponGradient[PlayerKey] = WeaponGradientManager.UpdatePlayerNextGradient(PlayerKey)
DOREPONCE(self, "PlayerWeaponGradient")
self:SetPlayerWeaponGrade(PlayerKey, 1, true)
self:AddScore(PlayerKey, GlobalConfigs.GameSetting.FullGradientAddScore)
UGCLogSystem.LogTree("[UGCGameState_PlayerAddWeaponGrade] " .. PlayerKey .. " PlayerWeaponGradient:", self.PlayerWeaponGradient[PlayerKey])
UGCSendRPCSystem.RPCEvent(nil, EventEnum.AddTip, TipConfig.TipType.PlayerCompleteGradient, PlayerKey)
else
self:SetPlayerWeaponGrade(PlayerKey, math.clamp(AddGrade + PlayerLastGrade, 1, #WeaponGradient), true)
end
end
--- 获取玩家选择的默认近战武器
function UGCGameState:GetPlayerDefaultMeleeWeaponByPlayerKey(PlayerKey)
return self.PlayerDefaultMeleeWeapon[PlayerKey] and self.PlayerDefaultMeleeWeapon[PlayerKey] or GlobalConfigs.GameSetting.DefaultMeleeWeapon
end
function UGCGameState:OnRep_PlayerGradientGrade()
UGCEventSystem.SendEvent(EventEnum.PlayerGradientGradeChange)
end
---------------------------------------------- GameState WeaponGradient End ----------------------------------------------
--------------------------------------------- SelectMap ---------------------------------------------
function UGCGameState:SetMapSelectionResult(NewMapType)
self.MapSelectionResult = NewMapType
if self.MapSelectionResult == MapConfig.MapType.Random then
self.MapSelectionFinalResult = table.Rand(self:GetEnableMapExcludeRandom())
else
self.MapSelectionFinalResult = self.MapSelectionResult
end
DOREPONCE(self, "MapSelectionFinalResult")
DOREPONCE(self, "MapSelectionResult")
end
--- 获取当前地图玩法类型
function UGCGameState:GetSpecialModeType()
if self.MapSelectionFinalResult then
return MapConfig.MapInfo[self.MapSelectionFinalResult].SpecialModeType
end
end
--- 获取当前已选择好的地图Type
---@return MapSelectionResult MapConfig.MapType 若未选择则返回nil
function UGCGameState:GetMapSelectionResult(bMustObtain)
if bMustObtain and self.MapSelectionResult == nil then
local MapTypes = self:GetMaxSameVotesMap()
self:SetMapSelectionResult(table.Rand(MapTypes))
end
return self.MapSelectionResult
end
function UGCGameState:GetPlayerSelectMapList()
return self.PlayerSelectMapList
end
function UGCGameState:GetMaxSameVotesMap()
local MaxType = self:GetMaxAndSecondMapType()
local Res = {}
for i, v in pairs(self.SelectMapInfo) do
if v == self.SelectMapInfo[MaxType] and MapConfig.MapEnable[i] then
Res[#Res + 1] = i
end
end
return Res
end
function UGCGameState:GetEnableMapExcludeRandom()
local Res = {}
for i, v in pairs(MapConfig.MapEnable) do
if v and (i ~= MapConfig.MapType.Random) then
Res[#Res + 1] = i
end
end
return Res
end
function UGCGameState:GetMapSelectionFinalResult()
return self.MapSelectionFinalResult
end
---@param MapType MapConfig.MapType
function UGCGameState:PlayerSelectMap(PlayerKey, MapType)
UGCLogSystem.Log("[UGCGameState_PlayerSelectMap] Begin")
if self.PlayerSelectMapList[PlayerKey] == nil and table.hasValue(MapConfig.MapType, MapType) then
self.PlayerSelectMapList[PlayerKey] = MapType
if #self.SelectMapInfo == 0 then
self:InitSelectMapInfo()
end
self.SelectMapInfo[MapType] = self.SelectMapInfo[MapType] + 1
DOREPONCE(self, "SelectMapInfo")
local MaxSelectMap, SecondSelectMap = self:GetMaxAndSecondMapType()
local SelectMapNum = self:GetSelectMapNum()
local MaxSelectMapNum = self.SelectMapInfo[MaxSelectMap]
local SecondSelectMapNum = (SecondSelectMap and self.SelectMapInfo[SecondSelectMap] or 0)
if (MaxSelectMapNum - SecondSelectMapNum) > (GlobalConfigs.GameModeSetting.MaxPlayerNum - SelectMapNum)
or (SelectMapNum == GlobalConfigs.GameModeSetting.MaxPlayerNum)
then
-- self:SetMapSelectionResult(MaxSelectMap)
local MapTypes = self:GetMaxSameVotesMap()
self:SetMapSelectionResult(table.Rand(MapTypes))
end
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, true, MapType)
UGCLogSystem.Log("[UGCGameState_PlayerSelectMap] Finish")
UGCLogSystem.LogTree("[UGCGameState_PlayerSelectMap] ", self.SelectMapInfo)
else
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, false, MapType)
end
end
function UGCGameState:PlayerOverlapSelectMap(PlayerKey, MapType)
UGCLogSystem.Log("[UGCGameState_PlayerOverlapSelectMap] Begin")
if self.PlayerSelectMapList[PlayerKey] ~= MapType and table.hasValue(MapConfig.MapType, MapType) then
self.PlayerSelectMapList[PlayerKey] = MapType
self:UpdateSelectMapInfo()
DOREPONCE(self, "SelectMapInfo")
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, true, MapType)
UGCLogSystem.Log("[UGCGameState_PlayerOverlapSelectMap] Finish")
UGCLogSystem.LogTree("[UGCGameState_PlayerOverlapSelectMapp] ", self.SelectMapInfo)
else
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectMapCallBack, false, MapType)
end
end
function UGCGameState:InitSelectMapInfo()
if #self.SelectMapInfo == 0 then
self:ResetSelectMapInfo()
end
end
function UGCGameState:ResetSelectMapInfo()
for i, v in pairs(MapConfig.MapType) do
self.SelectMapInfo[v] = 0
end
end
function UGCGameState:UpdateSelectMapInfo()
self:ResetSelectMapInfo()
for PlayerKey, MapType in pairs(self.PlayerSelectMapList) do
self.SelectMapInfo[MapType] = self.SelectMapInfo[MapType] + 1
end
end
function UGCGameState:GetSelectMapNumFromMapType(SelectMapType)
return (self.SelectMapInfo[SelectMapType] and self.SelectMapInfo[SelectMapType] or 0)
end
function UGCGameState:GetSelectMapNum()
local Sum = 0
for i, v in pairs(self.SelectMapInfo) do
Sum = Sum + v
end
return Sum
end
function UGCGameState:GetMaxAndSecondMapType()
local AllSelectType = {}
if #self.SelectMapInfo == 0 then
self:InitSelectMapInfo()
end
for i, v in pairs(self.SelectMapInfo) do
AllSelectType[#AllSelectType + 1] = {MapType = i, Num = v}
end
table.sort(AllSelectType, function(a, b) return a.Num > b.Num end)
UGCLogSystem.LogTree("[UGCGameState_GetMaxAndSecondMapType] AllSelectType", AllSelectType)
return AllSelectType[1].MapType, AllSelectType[2].MapType
end
function UGCGameState:OnRep_MapSelectionFinalResult()
self:LoadNowMiniMap()
local SceneItemGuide = WidgetManager:GetPanel(WidgetConfig.EUIType.SceneItemGuide)
if SceneItemGuide and self.MapSelectionFinalResult then
SceneItemGuide:UpdateMechanismDesc(self.MapSelectionFinalResult)
WidgetManager:ShowPanel(WidgetConfig.EUIType.SceneItemGuide, false)
end
UGCEventSystem.SendEvent(EventEnum.UpdateMapSelectionFinalResult, self.MapSelectionFinalResult)
end
function UGCGameState:LoadNowMiniMap()
UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap]")
if self:HasAuthority() or self.MapSelectionFinalResult == nil then
UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap] self.MapSelectionFinalResult is nil")
return
end
local MiniMapInfo = MapConfig.MapInfo[self.MapSelectionFinalResult].MiniMapInfo
UGCLogSystem.LogTree("[UGCGameState_LoadNowMiniMap]", MiniMapInfo)
UGCWidgetManagerSystem.ChangeMap(MiniMapInfo.MapPath, MiniMapInfo.MapCentre, MiniMapInfo.MapSize, MiniMapInfo.MapScale)
UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap] Finish")
end
function UGCGameState:PlayerSelectDefaultWeapon(PlayerKey, WeaponID)
if table.hasValue(WeaponGradientTable.DefaultWeapon, WeaponID) then
self.PlayerDefaultMeleeWeapon[PlayerKey] = WeaponID
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectDefaultWeaponCallBack, true, WeaponID)
else
UGCLogSystem.LogError("[UGCGameState_PlayerSelectDefaultWeapon] PlayerKey:%s, 默认武器表内没有武器:%s", tostring(PlayerKey), tostring(WeaponID))
UGCSendRPCSystem.RPCEvent(PlayerKey, EventEnum.SelectDefaultWeaponCallBack, false, WeaponID)
end
end
------------------------------------------- SelectMap End -------------------------------------------
function UGCGameState:GetGameTime()
return self.GameTime
end
function UGCGameState:SetGameTime(NewTime)
if UGCGameSystem.IsServer() then
self.GameTime = NewTime
else
UGCLogSystem.LogError("[UGCGameState_SetGameTime] 客户端无法设置游戏时间")
end
end
function UGCGameState:SetPlayerIsAlive(PlayerKey, Pawn)
if Pawn then
self.PlayerIsAlive[PlayerKey] = Pawn
else
self.PlayerIsAlive[PlayerKey] = nil
end
end
function UGCGameState:OnRep_PlayerIsAlive()
UGCEventSystem.SendEvent(EventEnum.PlayerIsAliveIsChange)
end
function UGCGameState:GetPlayerIsAlive(PlayerKey)
if self.PlayerIsAlive[PlayerKey] then
return true
end
return false
end
function UGCGameState:GetAlivePawn(PlayerKey)
return self.PlayerIsAlive[PlayerKey]
end
------------------------------------------------ GameState Abstract RPC ------------------------------------------------
function UGCGameState:UGCSendRPCSystemFunc(...)
UGCSendRPCSystem.RPCFunc(...)
end
---------------------------------------------- GameState Abstract RPC End ----------------------------------------------
function UGCGameState:GetAvailableServerRPCs()
return
"MulticastRPC_SpawnParticleAttachPlayer",
"UGCSendRPCSystemFunc",
"Server_ControllerInitFinish",
"Server_SaveButtonSetting",
"Server_GetButtonSetting"
end
return UGCGameState;