1464 lines
55 KiB
Lua
Raw Normal View History

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