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

1464 lines
55 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, 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;