---@class UGCGameState_C:BP_UGCGameState_C --Edit Below-- ---@type UGCGameState_C UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom') UGCGameSystem.UGCRequire('Script.Global.Global') local UGCGameState = { WaitPlayerJoinTime = 0; GameStateType = CustomEnum.EGameState.Waiting; GameTime = 0; -- 游戏倒计时时间 RoundCount = 0; -- 当前回合数 PlayerPersonalInfos = {}; -- 玩家信息{PlayerKey = {UID, PlayerKey, TeamID, IsOffline, PlayerName, Gender, IconURL, AchievementScore, IsSelectTeam}, ...} PlayerScoreDatas = {}; -- 玩家得分信息{[PlayerKey] = {Kills = int32, Assists = int32, Score = int32}...} TeamScore = {}; -- 队伍得分{[TeamID] = Score} PlayerJoinNum = 0; -- 玩家加入的数量作为个人TeamID PlayerIsAlive = {}; -- 玩家是否存活 MapKey = -1; -- 选择出的地图的索引 SyncPlayModeUIInfo = {}; -- 同步游玩模式显示的UI -- 服务器时间同步 ClientGameTimeDifference = 0.; -- 客户端与服务器的游戏时间差时间差 GameTimeCalibrationCycle = 1; -- 校准客户端GameTime的周期 -- 武器配置选择 PlayerWeaponCombination = {}; -- 玩家可选的武器组合索引 PlayerSelectedWeaponIndex = {}; -- 玩家选择的武器配置索引 PlayerAutoSelectWeaponHandle = {}; -- 自动选择武器索引 -- 呼吸回血的玩家 RespiratoryRegurgitationPlayers = {}; -- 玩法工程参数 根据玩法的改变可替换删除 BreakThroughCount = 0; -- 突围的次数 Attackers = {}; -- 进攻方玩家 Defenders = {}; TeamBreakThroughTime = {}; -- 队伍突围成功的时间 bCanBreakThrough = true; -- 是否允许突围 }; function UGCGameState:GetReplicatedProperties() return "GameTime", "PlayerPersonalInfos", "WaitPlayerJoinTime", "GameStateType", "PlayerScoreDatas", "TeamScore", "PlayerIsAlive", "MapKey", "SyncPlayModeUIInfo", "PlayerWeaponCombination", "PlayerSelectedWeaponIndex", "BreakThroughCount", "Attackers", "Defenders", "TeamBreakThroughTime", "bCanBreakThrough", BuffManager.GetReplicatedProperties(), ArchiveDataConfig.GetAllReplicatedPropertiesName() end -------------------------------------------------------- OnRep -------------------------------------------------------- function UGCGameState:OnRep_PlayerScoreDatas() PlayerScoreSystem.SetPlayerScoreDatas(self.PlayerScoreDatas) UGCEventSystem.SendEvent(EventEnum.UpdatePlayerScoreData) end function UGCGameState:OnRep_PlayerPersonalInfos() UGCEventSystem.SendEvent(EventEnum.UpdatePlayerScoreData) end function UGCGameState:OnRep_GameStateType() if self:HasAuthority() then return end UGCEventSystem.SendEvent(EventEnum.GameStateChange, self.GameStateType) if self.GameStateType == CustomEnum.EGameState.Playing then if self.LoopCheckWallHandle == nil then self.LoopCheckWallHandle = UGCEventSystem.SetTimerLoop(self, function() local BlockWallPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/ParkourActor/BlockWall/BP_WaitingBlockWall.BP_WaitingBlockWall_C') local AllWaitingWalls = GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, UE.LoadClass(BlockWallPath), {}) for i, v in pairs(AllWaitingWalls) do -- 销毁初始阻挡墙 v:K2_DestroyActor() UGCLogSystem.Log("[UGCGameState_OnRep_GameStateType] i:%s", tostring(i)) end if table.getCount(AllWaitingWalls) <= 0 then UGCEventSystem.StopTimer(self.LoopCheckWallHandle) end UGCLogSystem.Log("[UGCGameState_OnRep_GameStateType] Check") end, 3) UGCLogSystem.Log("[UGCGameState_OnRep_GameStateType] Finish") end end end function UGCGameState:OnRep_PlayerIsAlive() UGCEventSystem.SendEvent(EventEnum.PlayerIsAliveIsChange) end function UGCGameState:OnRep_SyncPlayModeUIInfo() for _, UIType in pairs(WidgetConfig.SyncShowPlayModeWidget) do local Params = self.SyncPlayModeUIInfo[UIType] if Params == nil then WidgetManager:ClosePanel(UIType) end end for UIType, Params in pairs(self.SyncPlayModeUIInfo) do WidgetManager:ShowPanel(UIType, false, table.unpack(Params)) end end function UGCGameState:OnRep_PlayerWeaponCombination() UGCEventSystem.SendEvent(EventEnum.PlayerWeaponCombinationUpdate, self.PlayerWeaponCombination) end function UGCGameState:OnRep_PlayerSelectedWeaponIndex() UGCEventSystem.SendEvent(EventEnum.PlayerSelectedWeaponIndexUpdate, self.PlayerSelectedWeaponIndex) end function UGCGameState:OnRep_TeamScore() UGCEventSystem.SendEvent(EventEnum.UpdateTeamScore, self.TeamScore) end function UGCGameState:OnRep_MapKey() UGCEventSystem.SendEvent(EventEnum.UpdateMapKey, self.MapKey) self:LoadNowMiniMap() end function UGCGameState:OnRep_Attackers() UGCEventSystem.SendEvent(EventEnum.UpdateAttackers, self.Attackers) end function UGCGameState:OnRep_TeamBreakThroughTime() UGCEventSystem.SendEvent(EventEnum.UpdateTeamBreakThroughTime, self.TeamBreakThroughTime) end function UGCGameState:OnRep_bCanBreakThrough() UGCEventSystem.SendEvent(EventEnum.UpdateCanBreakThrough, self.bCanBreakThrough) end ------------------------------------------------------ OnRep End ------------------------------------------------------ function UGCGameState:ReceiveBeginPlay() UGCLogSystem.Log("[UGCGameState_ReceiveBeginPlay]") --屏蔽死亡盒子 self.IsShowDeadBox = false; -- 显示飘字 self.bIsShowHitValue = true; -- 注册存档API ArchiveDataConfig.Register(self) -- 注册BuffSystem BuffManager.InitRegister(self) -- 特效初始化 ParticleConfig.Init(self) -- 初始化全局逻辑 GlobalInit.Init() self:AddBind() -- 开启滑铲State部分 self.bIsOpenShovelingAbility = true -- 注册排行信息 PlayerScoreSystem.RegisterInfo(PlayerScoreSystem.Config.ScoreList) -- 初始化RPC系统 UGCSendRPCSystem.InitUGCSendRPCSystem(self, "UGCSendRPCSystemFunc") if UGCGameSystem.IsServer() then -- 绑定更新积分的函数 PlayerScoreSystem.BindChangeScoreDataCallBack(self.UpdateAllPlayerScoreDatas, self) else self:OnRep_SyncPlayModeUIInfo() end UGCLogSystem.Log("[UGCGameState_ReceiveBeginPlay] Finish") end --function UGCGameState:ReceiveTick(DeltaTime) --end function UGCGameState:ReceiveEndPlay() self:RemoveBind() end function UGCGameState:AddBind() UGCCommoditySystem.BuyUGCCommodityResultDelegate:Add(self.OnBuyUGCCommodityResult, self) if self:HasAuthority() then UGCEventSystem.AddListener(EventEnum.PlayerLogin, self.PlayerLogin, self) UGCEventSystem.AddListener(EventEnum.PlayerExit, self.PlayerExit, self) -- 时间同步校验 self.GameTimeCalibrationHandle = UGCEventSystem.SetTimerLoop(self, self.CalibrationServerGameTime, self.GameTimeCalibrationCycle) else end end function UGCGameState:RemoveBind() UGCCommoditySystem.BuyUGCCommodityResultDelegate:Remove(self.OnBuyUGCCommodityResult, self) if self:HasAuthority() then UGCEventSystem.RemoveListener(EventEnum.PlayerLogin, self.PlayerLogin, self) UGCEventSystem.RemoveListener(EventEnum.PlayerExit, self.PlayerExit, self) if self.GameTimeCalibrationHandle then UGCEventSystem.StopTimer(self.GameTimeCalibrationHandle) self.GameTimeCalibrationHandle = nil end else end end function UGCGameState:PlayerLogin(PlayerPawn, PlayerKey) UGCLogSystem.Log("[UGCGameState_PlayerLogin] PlayerKey:%s", tostring(PlayerKey)) -- 更新玩家队伍设置 self:UpdatePlayerTeam(PlayerKey) -- 获取玩家信息 self:GetUserInfo(PlayerKey) -- 注册玩家得分信息 PlayerScoreSystem.InitPlayerScoreData(PlayerKey) -- 增加玩家游玩次数 self:AddPlayerNumberOfPlays(PlayerKey) --UGCEventSystem.SetTimer(self, function() -- UGCLogSystem.Log("[UGCGameState_PlayerLogin] --PlayerKey:%s", tostring(PlayerKey)) -- self:AddPlayerNumberOfPlays(PlayerKey) end, 15) UGCLogSystem.Log("[UGCGameState_PlayerLogin] Finish") end function UGCGameState:PlayerExit(PlayerPawn, PlayerKey) if GlobalConfigs.GameSetting.EnablePlayerJoin then PlayerScoreSystem.RemovePlayerScoreInfo(PlayerKey) end end --- 根据游戏队伍模式更新玩家队伍 ---@param PlayerKey uint function UGCGameState:UpdatePlayerTeam(PlayerKey) if GlobalConfigs.GameModeSetting.TeamModeType == CustomEnum.ETeamMode.PersonalWarfare then local NewTeamID = self:GetNewTeamID() UGCTeamSystem.ChangePlayerTeamID(PlayerKey, NewTeamID) UGCLogSystem.Log("[UGCGameState_UpdatePlayerTeam] NewTeamID:%s", tostring(NewTeamID)) end end --- 玩家登录获取玩家数据 ---@param PlayerKey uint function UGCGameState:GetUserInfo(PlayerKey) if self.PlayerPersonalInfos[PlayerKey] then return self.PlayerPersonalInfos[PlayerKey] end local UserInfo = UGCPlayerStateSystem.GetPlayerAccountInfo(PlayerKey) if UserInfo then --- UID,PlayerName,TeamID,Gender,PlatformGender,PlayerLevel,SegmentLevel,IconURL local UserInfoCpy = UserInfo:Copy() UGCLogSystem.Log("[UGCGameState_GetUserInfo] PlayerName:%s", UserInfoCpy.PlayerName) local CustomUserInfo = { UID = UserInfoCpy.UID, PlayerKey = PlayerKey, TeamID = UserInfoCpy.TeamID, IsOffline = false, PlayerName = UserInfoCpy.PlayerName, Gender = UserInfoCpy.PlatformGender, IconURL = UserInfoCpy.IconURL, IsSelectTeam = false, } self.PlayerPersonalInfos[PlayerKey] = CustomUserInfo UGCLogSystem.LogTree("[UGCGameState_GetUserInfo] CustomUserInfo:", CustomUserInfo) return CustomUserInfo else UGCLogSystem.LogError("[UGCGameState_GetUserInfo] UserInfo Error PlayerKey:%s", tostring(PlayerKey)) end end -------------------------------------------------- ArchiveData -------------------------------------------------- function UGCGameState:GetArchiveDataByType(PlayerKey, ArchiveType) local UID = self:GetPlayerUIDByPlayerKey(PlayerKey) if UID then local ArchiveData = UGCPlayerStateSystem.GetPlayerArchiveData(UID) if ArchiveData then UGCLogSystem.Log("[UGCGameState_GetArchiveDataByType] Succeed") return ArchiveData[ArchiveType] end end return nil end function UGCGameState:SavePlayerArchiveData(PlayerKey, ArchiveType, Data) local UID = self:GetPlayerUIDByPlayerKey(PlayerKey) if UID then local ArchiveData = UGCPlayerStateSystem.GetPlayerArchiveData(UID) if ArchiveData == nil then ArchiveData = {} end ArchiveData[ArchiveType] = Data UGCPlayerStateSystem.SavePlayerArchiveData(UID, ArchiveData) return true end return false end ------------------------------------------------ ArchiveData End ------------------------------------------------ -- 存档 --------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------- NumberOfPlays ------------------------------------------------- --- 增加玩家游玩次数 function UGCGameState:AddPlayerNumberOfPlays(PlayerKey) local NumberOfPlays = self:GetArchiveDataByType(PlayerKey, ArchiveDataConfig.EArchiveType.NumberOfPlays) if NumberOfPlays then self:SavePlayerArchiveData(PlayerKey, ArchiveDataConfig.EArchiveType.NumberOfPlays, NumberOfPlays + 1) else self:SavePlayerArchiveData(PlayerKey, ArchiveDataConfig.EArchiveType.NumberOfPlays, 1) end end --- 获取玩家游玩次数 function UGCGameState:GetPlayerNumberOfPlays(PlayerKey) return ArchiveDataConfig.GetPlayerArchiveDataFromType(PlayerKey, ArchiveDataConfig.EArchiveType.NumberOfPlay) end ----------------------------------------------- NumberOfPlays End ----------------------------------------------- -- 存档 End ----------------------------------------------------------------------------------------------------------------------------------------------- -- ServerGameTime ----------------------------------------------------------------------------------------------------------------------------------------------- --- 校准服务器时间 function UGCGameState:CalibrationServerGameTime(ServerGameTime) if UGCGameSystem.IsServer() then UGCSendRPCSystem.ActorRPCNotify(nil, self, "CalibrationServerGameTime", self:GetServerGameTime()) else self.ClientGameTimeDifference = UGCSystemLibrary.GetGameTime() - ServerGameTime end end --- 获取校准后的服务器时间 function UGCGameState:GetServerGameTime() if UGCGameSystem.IsServer() then return UGCSystemLibrary.GetGameTime() else return UGCSystemLibrary.GetGameTime() - self.ClientGameTimeDifference end end -- ServerGameTime End ------------------------------------------------------------------------------------------------------------------------------------------- -- Score Data ---------------------------------------------------------------------------------------- --- 更新返回所有玩家得分 function UGCGameState:UpdateAllPlayerScoreDatas() self.PlayerScoreDatas = PlayerScoreSystem.GetPlayerScoreDatas() UGCLogSystem.LogTree("[UGCGameState_UpdateAllPlayerScoreDatas]", self.PlayerScoreDatas) end --- 获取队伍得分 function UGCGameState:GetTeamScore(TeamID) return (self.TeamScore[TeamID] and self.TeamScore[TeamID] or 0) end --- 获取最高的队伍得分 function UGCGameState:GetMaxTeamScore() local Res = 0 for i, v in pairs(self.TeamScore) do Res = math.max(Res, v) end return Res end --- 重置队伍得分 function UGCGameState:ResetTeamScore() self.TeamScore = {} end --- 增加队伍得分 function UGCGameState:AddTeamScore(TeamID, Score) self.TeamScore[TeamID] = self:GetTeamScore(TeamID) + Score UGCEventSystem.SendEvent(EventEnum.UpdateTeamScore) end -- Score Data 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:GameFinish() self:SetGameStateType(CustomEnum.EGameState.End) end --- 获取一个新的队伍ID 个人战使用 function UGCGameState:GetNewTeamID() -- body self.PlayerJoinNum = self.PlayerJoinNum + 1 return self.PlayerJoinNum 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:GetPlayerUIDByPlayerKey(PlayerKey) return self.PlayerPersonalInfos[PlayerKey].UID end ---------------------------------------------------------------- 获取玩家信息 End ---------------------------------------------------------------- function UGCGameState:GetGameTime() return self.GameTime end function UGCGameState:SetGameTime(NewTime) if UGCGameSystem.IsServer() then self.GameTime = NewTime else UGCLogSystem.LogError("[UGCGameState_SetGameTime] 客户端无法设置游戏时间") end end function UGCGameState:SetPlayerIsAlive(PlayerKey, Pawn) if Pawn then self.PlayerIsAlive[PlayerKey] = Pawn else self.PlayerIsAlive[PlayerKey] = nil end end function UGCGameState:GetPlayerIsAlive(PlayerKey) if self.PlayerIsAlive[PlayerKey] then return true end return false end function UGCGameState:GetAlivePawn(PlayerKey) return self.PlayerIsAlive[PlayerKey] end --------------------------------------------- SyncUIInfo --------------------------------------------- -- PlayMode ------------------------------------------------------------------------------------------- function UGCGameState:ShowSimplePlayModeUI(UIType, Params) if Params == nil then Params = {} end self.SyncPlayModeUIInfo = {} self.SyncPlayModeUIInfo[UIType] = Params end function UGCGameState:AddPlayModeUI(UIType, Params) if table.hasValue(WidgetConfig.SyncShowPlayModeWidget, UIType) then if Params == nil then Params = {} end self.SyncPlayModeUIInfo[UIType] = Params end end function UGCGameState:RemovePlayModeUI(UIType) self.SyncPlayModeUIInfo[UIType] = nil end -- PlayMode End --------------------------------------------------------------------------------------- --------------------------------------------- SyncUIInfo End --------------------------------------------- -- PlayerWeaponCombination --------------------------------------------------------------------------------------------------------------- function UGCGameState:SetPlayerWeaponCombination(PlayerKey, WeaponCombinationType) self.PlayerWeaponCombination[PlayerKey] = WeaponCombinationType self:ResetPlayerSelectWeaponIndex(PlayerKey) end function UGCGameState:GetPlayerWeaponCombination(PlayerKey) if self.PlayerWeaponCombination[PlayerKey] then return self.PlayerWeaponCombination[PlayerKey] else return 1 end end --- 重置玩家选择的武器配置索引 function UGCGameState:ResetPlayerSelectWeaponIndex(PlayerKey) self.PlayerSelectedWeaponIndex[PlayerKey] = 1 end --- 重置所有玩家的武器配置索引 function UGCGameState:ResetAllPlayerSelectWeaponIndex() self.PlayerSelectedWeaponIndex = {} end --- 设置玩家选择的武器配置索引 function UGCGameState:PlayerSelectWeaponIndex(PlayerKey, WeaponCombinationIndex) self.PlayerSelectedWeaponIndex[PlayerKey] = WeaponCombinationIndex -- self:CheckWeaponAndParts(PlayerKey) self:UpdatePlayerWeapon(PlayerKey) if self.PlayerAutoSelectWeaponHandle[PlayerKey] then UGCEventSystem.StopTimer(self.PlayerAutoSelectWeaponHandle[PlayerKey]) self.PlayerAutoSelectWeaponHandle[PlayerKey] = nil end end --- 校验玩家选择的武器配置索引 function UGCGameState:CheckPlayerSelectWeaponIndex(PlayerKey) local SelectedWeaponIndex = self:GetPlayerSelectedWeaponIndex(PlayerKey) if SelectedWeaponIndex then local WeaponCombination = WeaponSelectionCombinationConfig.WeaponCombinationList[self:GetPlayerWeaponCombination(PlayerKey)] if WeaponCombination then if WeaponCombination.Weapon[SelectedWeaponIndex] then return true end end end return false end --- 获取玩家选择的武器配置索引 function UGCGameState:GetPlayerSelectedWeaponIndex(PlayerKey) return self.PlayerSelectedWeaponIndex[PlayerKey] end --- 获取玩家选择的武器索引对应的武器及配件 function UGCGameState:GetPlayerSelectedWeaponAndParts(PlayerKey) local Res = {} if not self:CheckPlayerSelectWeaponIndex(PlayerKey) then self.PlayerSelectedWeaponIndex[PlayerKey] = 1 end local PlayerWeaponCombination = self:GetPlayerWeaponCombination(PlayerKey) local PlayerSelectedWeaponIndex = self:GetPlayerSelectedWeaponIndex(PlayerKey) local WeaponCombination = WeaponSelectionCombinationConfig.WeaponCombinationList[PlayerWeaponCombination] if WeaponCombination then local Weapons = WeaponCombination.Weapon[PlayerSelectedWeaponIndex] if Weapons then for i, WeaponID in pairs(Weapons) do Res[WeaponID] = 1 for _, PartID in pairs(WeaponTable.RecommendedWeaponParts[WeaponID]) do if Res[PartID] then Res[PartID] = 1 + Res[PartID] else Res[PartID] = 1 end end end end end return Res end --- 获取玩家选择的武器Item表 function UGCGameState:GetPlayerSelectedWeaponItemInfo(PlayerKey) local Res = {} if not self:CheckPlayerSelectWeaponIndex(PlayerKey) then self.PlayerSelectedWeaponIndex[PlayerKey] = 1 end local PlayerWeaponCombination = self:GetPlayerWeaponCombination(PlayerKey) local PlayerSelectedWeaponIndex = self:GetPlayerSelectedWeaponIndex(PlayerKey) local WeaponCombination = WeaponSelectionCombinationConfig.WeaponCombinationList[PlayerWeaponCombination] if WeaponCombination then local Weapons = WeaponCombination.Weapon[PlayerSelectedWeaponIndex] if Weapons then for i, WeaponID in pairs(Weapons) do local WeaponItemInfo = {} WeaponItemInfo.ItemID = WeaponID WeaponItemInfo.Count = 1 WeaponItemInfo.SubItemList = {} for PartIndex, PartID in pairs(WeaponTable.RecommendedWeaponParts[WeaponID]) do WeaponItemInfo.SubItemList[PartIndex] = {ItemID = PartID, Count = 1} end Res[#Res + 1] = WeaponItemInfo end end end return Res end --- 检测并给予玩家武器和配件 function UGCGameState:CheckWeaponAndParts(InPlayerKey) local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey) if TargetPawn == nil then return end local WeaponAndParts = self:GetPlayerSelectedWeaponAndParts(InPlayerKey) UGCLogSystem.LogTree("[UGCGameState_CheckWeaponAndParts]", WeaponAndParts) ---@return ItemDataList LuaTable @LuaTable, ItemData结构:ItemID,InstanceID,Count,Type,SubType,IsAvatar local AllItems = UGCBackPackSystem.GetAllItemData(TargetPawn) local BackPackWeaponAndParts = {} -- 验证玩家当前背包武器及配件是否需要销毁 for i, ItemInfo in pairs(AllItems) do local ItemID = ItemInfo.ItemID if (ItemID < 108000 and ItemID > 100000) or (ItemID >= 200000 and ItemID < 300000) then if BackPackWeaponAndParts[ItemInfo.ItemID] == nil then BackPackWeaponAndParts[ItemInfo.ItemID] = 1 else BackPackWeaponAndParts[ItemInfo.ItemID] = BackPackWeaponAndParts[ItemInfo.ItemID] + 1 end end end -- 验证玩家当前背包武器及配件是否需要销毁 for _, ItemInfo in pairs(AllItems) do local TypeID = UGCSystemLibrary.GetItemTypeID(ItemInfo.ItemID) if (ItemInfo.ItemID < 108000 and ItemInfo.ItemID > 100000) or (TypeID >= 200 and TypeID < 300) then local TargetItemCount = WeaponAndParts[ItemInfo.ItemID] if TargetItemCount == nil then TargetItemCount = 0 end if BackPackWeaponAndParts[ItemInfo.ItemID] > TargetItemCount then --- 销毁背包中的物品 --UGCBackPackSystem.DropItem(TargetPawn, ItemInfo.ItemID, ItemInfo.Count - TargetItemCount, true) for i = 1, BackPackWeaponAndParts[ItemInfo.ItemID] - TargetItemCount do UGCBackPackSystem.DropItem(TargetPawn, ItemInfo.ItemID, 1, true) end end end end local bGiveWeapon = false -- 添加武器及配件 for ItemID, TargetCount in pairs(WeaponAndParts) do local Count = UGCBackPackSystem.GetItemCount(TargetPawn, ItemID) UGCLogSystem.Log("[UGCGameState_CheckWeaponAndParts] ItemID:%s, Count:%s", tostring(ItemID), tostring(Count)) if TargetCount > Count then --UGCBackPackSystem.AddItem(TargetPawn, ItemID, TargetCount - Count) for i = 1, TargetCount - Count do UGCBackPackSystem.AddItem(TargetPawn, ItemID, 1) end local ItemTypeID = UGCSystemLibrary.GetItemTypeID(ItemID) if ItemTypeID > 100 and ItemTypeID < 200 then bGiveWeapon = true end end end -- 补满弹夹 if bGiveWeapon then UGCEventSystem.SetTimer(TargetPawn, function() for i, v in pairs(ShootWeaponEnums) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(TargetPawn, v) if UE.IsValid(Weapon) then UGCGunSystem.EnableClipInfiniteBullets(Weapon, true) local MaxBulletNumInOneClip = UGCGunSystem.GetMaxBulletNumInOneClip(Weapon) Weapon:SetCurrentBulletNumInClipOnServer(MaxBulletNumInOneClip, true) -- 玩家离开换弹状态 if UE.IsValid(TargetPawn) then UGCPawnSystem.LeavePawnState(TargetPawn, EPawnState.Roload) end end end end, 1. ) end end --- 更新玩家的武器装备 function UGCGameState:UpdatePlayerWeapon(InPlayerKey) local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey) if TargetPawn == nil then return end local AllItems = UGCBackPackSystem.GetAllItemData(TargetPawn) -- 清除玩家武器 for _, ItemInfo in pairs(AllItems) do local TypeID = UGCSystemLibrary.GetItemTypeID(ItemInfo.ItemID) if (ItemInfo.ItemID < 108000 and ItemInfo.ItemID > 100000) or (TypeID >= 200 and TypeID < 300) then UGCBackPackSystem.DropItem(TargetPawn, ItemInfo.ItemID, ItemInfo.Count, true) end end local WeaponItemInfo = self:GetPlayerSelectedWeaponItemInfo(InPlayerKey) UGCLogSystem.LogTree("[UGCGameState_UpdatePlayerWeapon] WeaponItemInfo:", WeaponItemInfo) self:PlayerAddItemInfo(InPlayerKey, WeaponItemInfo) end ---@param InItems {ItemID, Count, SubItemList:配件{{ItemID, Count}, ...}} function UGCGameState:PlayerAddItemInfo(InPlayerKey, InItems) local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey) local BackpackComponent = PC:GetBackpackComponent() for _, Item in pairs(InItems) do if ItemUtils.IsUGCItem(Item.ItemID) == true then local ItemDefineID = BackpackUtils.GenerateItemDefineIDByItemTableIDWithRandomInstanceID(Item.ItemID) local ItemInfo = CreateStruct("BattleItemPickupInfo") UGCLogSystem.Log("[UGCGameState_PlayerAddItemInfo] ItemID:%s, InstID:%s", tostring(Item.ItemID), tostring(ItemDefineID.InstanceID)) ItemInfo.Count = Item.Count ItemInfo.bAutoEquip = (2 == ItemDefineID.Type) or (8 == ItemDefineID.Type) BackpackComponent:RegisterItemGenerated(ItemDefineID.TypeSpecificID, ItemInfo.Count, ItemDefineID.InstanceID) BackpackComponent:PickupItem(ItemDefineID, ItemInfo, EBattleItemPickupReason.Initial) -- BackpackComponent:PickupInitialItem(ItemDefineID, ItemInfo, true) local BattleItemUseTarget = { TargetDefineID = ItemDefineID, -- TargetAssociationName = "", FilterTargetWhenPickup = true, } for _, SubItem in ipairs(Item.SubItemList or {}) do if ItemUtils.IsUGCItem(SubItem.ItemID) == true then local SubItemDefineID = BackpackUtils.GenerateItemDefineIDByItemTableIDWithRandomInstanceID(SubItem.ItemID) local EquipPickupInfo = CreateStruct("BattleItemPickupInfo") EquipPickupInfo.Count = SubItem.Count EquipPickupInfo.bAutoEquip = (2 == SubItemDefineID.Type) or (8 == SubItemDefineID.Type) EquipPickupInfo.AutoEquipTarget = BattleItemUseTarget UGCLogSystem.Log("[UGCGameState_UpdatePlayerWeapon], SubItem.ItemID="..SubItem.ItemID.." SubItem.Count="..SubItem.Count) BackpackComponent:PickupInitialItem(SubItemDefineID, EquipPickupInfo, true) end end end end local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey) if UE.IsValid(TargetPawn) then --补满子弹 TargetPawn:SetAllWeaponBulletNumToMaxOnServer(true, false) UGCEventSystem.SetTimer(TargetPawn, function() if UE.IsValid(TargetPawn) and TargetPawn:IsAlive() then for i, v in pairs(ShootWeaponEnums) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(TargetPawn, v) if UE.IsValid(Weapon) then UGCGunSystem.EnableClipInfiniteBullets(Weapon, true) local MaxBulletNumInOneClip = UGCGunSystem.GetMaxBulletNumInOneClip(Weapon) Weapon:SetCurrentBulletNumInClipOnServer(MaxBulletNumInOneClip, true) -- 玩家离开换弹状态 if UE.IsValid(TargetPawn) then UGCPawnSystem.LeavePawnState(TargetPawn, EPawnState.Roload) end end end end end, 1. ) end end --- 显示玩家选择武器UI,并延迟默认选择第一个 function UGCGameState:ShowPlayerSelectWeaponWidget(PlayerKey) UGCSendRPCSystem.ClientShowUI(PlayerKey, WidgetConfig.EUIType.WeaponSelect) if self.PlayerAutoSelectWeaponHandle[PlayerKey] then UGCEventSystem.StopTimer(self.PlayerAutoSelectWeaponHandle[PlayerKey]) end self.PlayerAutoSelectWeaponHandle[PlayerKey] = UGCEventSystem.SetTimer(self, function() self.PlayerAutoSelectWeaponHandle[PlayerKey] = nil self:PlayerSelectWeaponIndex(PlayerKey, 1) end, GlobalConfigs.GameSetting.WeaponSelectTime) end --- 获取当前默认配置项的其他配件(头甲等出生给予的配置) function UGCGameState:GetPlayerBeBornParts(InPlayerKey) local WeaponCombinationList = WeaponSelectionCombinationConfig.WeaponCombinationList[self:GetPlayerWeaponCombination(InPlayerKey)] if WeaponCombinationList then return WeaponCombinationList.OtherParts end return {} end -- PlayerWeaponCombination End ----------------------------------------------------------------------------------------------------------- -- 内购 ------------------------------------------------------------------------------------------------------------------------------------------------- --可以通过参数得知玩家物品的变化已经是否购买成功 function UGCGameState:OnBuyUGCCommodityResult(bSucceeded, PlayerKey, CommodityID, Count, UID, ProductID) local Result = string.format( "([UGCGameState_OnBuyUGCCommodityResult bSucceeded=%s PlayerKey=%s CommodityID=%s Count=%s)", tostring(bSucceeded), tostring(PlayerKey), tostring(CommodityID), tostring(Count), tostring(ProductID) ) ugcprint(Result) local cond = UGCGameSystem.IsServer() if cond then if bSucceeded then self:AddGoldBrick(PlayerKey, Count) UGCLogSystem.Log("[UGCGameState_OnBuyUGCCommodityResult] AddSucceed") end local CommodityList = UGCCommoditySystem.GetAllPlayerUGCCommodityList() local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) ugcprint(ToTreeString(CommodityList[PlayerController:GetInt64UID()])) else local CommodityList = UGCCommoditySystem.GetUGCCommodityList() ugcprint(ToTreeString(CommodityList)) end end -- 内购 End --------------------------------------------------------------------------------------------------------------------------------------------- -- Map --------------------------------------------------------------------------------------------------------------------------------------------- function UGCGameState:SetMapKey(InMapKey) self.MapKey = InMapKey end function UGCGameState:GetMapKey() return self.MapKey end function UGCGameState:LoadNowMiniMap() UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap]") if self:HasAuthority() or self.MapKey == nil then UGCLogSystem.LogError("[UGCGameState_LoadNowMiniMap] self.MapSelectionFinalResult is nil") return end if MapConfig.MapInfo[self.MapKey] == nil then UGCLogSystem.LogError("[UGCGameState_LoadNowMiniMap] MapInfo is nil. MapKey:%s", tostring(self.MapKey)) return end local MiniMapInfo = MapConfig.MapInfo[self.MapKey].MiniMapInfo UGCLogSystem.LogTree("[UGCGameState_LoadNowMiniMap]", MiniMapInfo) UGCWidgetManagerSystem.ChangeMap(MiniMapInfo.MapPath, MiniMapInfo.MapCentre, MiniMapInfo.MapSize, MiniMapInfo.MapScale) UGCLogSystem.Log("[UGCGameState_LoadNowMiniMap] Finish") end -- Map End ----------------------------------------------------------------------------------------------------------------------------------------- -- 呼吸恢复 ----------------------------------------------------------------------------------------------------------------------------------------- --- 设置可呼吸回血的玩家 function UGCGameState:SetRespiratoryRegurgitationPlayers(InPlayers) self.RespiratoryRegurgitationPlayers = InPlayers end --- 获取可呼吸回血的玩家 function UGCGameState:GetRespiratoryRegurgitationPlayers() return self.RespiratoryRegurgitationPlayers end -- 呼吸恢复 End ------------------------------------------------------------------------------------------------------------------------------------- -- Round ------------------- function UGCGameState:AddNewRound() self.RoundCount = self.RoundCount + 1 end function UGCGameState:IsFinishRound() return self.RoundCount >= GlobalConfigs.GameSetting.MaxRound end -- Round End --------------- -- GameLogic 玩法中的函数 随工程修改、删除 ------------------------------------------------------------------------------------------------------------- --- 重置玩家 function UGCGameState:ResetPlayer(InPlayerKey) local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey) if Pawn and Pawn:IsAlive() then UGCSystemLibrary.RespawnPlayer(InPlayerKey) end end -- GameLogic End --------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------ GameState Abstract RPC ------------------------------------------------ function UGCGameState:UGCSendRPCSystemFunc(...) UGCSendRPCSystem.RPCFunc(...) end ---------------------------------------------- GameState Abstract RPC End ---------------------------------------------- function UGCGameState:GetAvailableServerRPCs() return "UGCSendRPCSystemFunc" end return UGCGameState;