---@class UGCPlayerController_C:BP_UGCPlayerController_C --Edit Below-- ---@type UGCPlayerController_C local UGCPlayerController = {}; UGCPlayerController.HadSelectTeam = true; UGCPlayerController.FillBulletType = 0; --- 是否启用毒圈 UGCPlayerController.EnablePoison = true; UGCPlayerController.SelectWeapons = {}; ---@type table 保存的兵种类型 UGCPlayerController.Soldiers = {} UGCPlayerController.InSpectate = false; UGCPlayerController.EnableBombExplosion = false; function UGCPlayerController:ReceiveBeginPlay() self.SuperClass.ReceiveBeginPlay(self); GlobalInit.InitGlobalVar(); if self:HasAuthority() then else WidgetManager = WidgetManager and WidgetManager or require("Script.Global.WidgetManager.WidgetManager") WidgetManager:Init(self); LocalPlayerController = self; if LocalPlayerKey == nil then LocalPlayerKey = self.PlayerKey; end if DefaultSettings.LocalTeamId == nil then DefaultSettings.LocalTeamId = UGCPlayerStateSystem.GetTeamID(self.PlayerKey); end UGCEventSystem.SetTimer(self, function() self:CloseOBUI(); end, 5); WidgetConfig.CloseAutoJoinPanel(); UGCEventSystem.SetTimer(self, function() WidgetConfig.CloseAutoJoinPanel(); end, 18); end end function UGCPlayerController:CloseOBUI() -- 关闭观战界面 WidgetManager.HideReturnToLobbyButton(); self:CastUIMsg("UIMsg_HideQuitWatch", ""); self.ClearSpectateButtonTimer = UGCEventSystem.SetTimerLoop(self, function() WidgetManager.HideReturnToLobbyButton(); end, 0.5) UGCEventSystem.SetTimer(self, function() if self.ClearSpectateButtonTimer then UGCEventSystem.StopTimer(self.ClearSpectateButtonTimer) self.ClearSpectateButtonTimer = nil; end end, 1.5) end --[[ function UGCPlayerController:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); end --]] --[[ function UGCPlayerController:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); end --]] --[[ function UGCPlayerController:GetReplicatedProperties() return end --]] --function UGCPlayerController:GetAvailableServerRPCs() -- return -- --"Server_SelectWeapons", -- "ExitSpectate" --end -- 重置玩家 function UGCPlayerController:ResetPlayer() self.PlayerState:ResetPlayer(); end ---@param InSoldier ESoldierType ---@return SoldierBase function UGCPlayerController:GetSoldierBase(InSoldier) return self.Soldiers[InSoldier]; end --- S & C ---@param InSoldierType ESoldierType ---@return SoldierBase function UGCPlayerController:AddSoldierBase(InSoldierType) -- 再次检测 if self.Soldiers[InSoldierType] ~= nil then return self.Soldiers[InSoldierType]; end -- 找到名称 --UGCLogSystem.Log("[UGCPlayerController:AddSoldierBase] %s 当前选择了 %s 类型的兵种", tostring(self.PlayerKey), SoldierConfig.GetSoldierName(InSoldierType)) local ModuleName = string.format('Script.Blueprint.Soldiers.Soldier_%s', SoldierConfig.GetSoldierName(InSoldierType)); local Soldier = require(ModuleName); local SoldierBase = setmetatable({}, {__index = Soldier, __metatable = Soldier}); -- 初始化 if SoldierBase ~= nil then SoldierBase.SoldierType = InSoldierType; self.Soldiers[InSoldierType] = SoldierBase; UGCEventSystem.SetTimer(self, function() -- 此时玩家还未生成,需要等玩家生成之后再执行初始化 self.Soldiers[InSoldierType]:Init(self.PlayerKey, InSoldierType); end, 2); else UGCLogSystem.Log("[UGCPlayerController:AddSoldierBase] 无法创建兵种类型是 %s 的兵种", tostring(InSoldierType)); end return SoldierBase; end function UGCPlayerController:CheckSoldierTypeAndWeapons() if UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey] == nil then self:RandSelectSoldierType() end -- 输出一下 local Type = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey]; UGCLogSystem.Log("[UGCPlayerController:CheckSoldierTypeAndWeapons] Type = %s", tostring(Type)); if table.isEmpty(self.SelectWeapons) then self:RandWeapons(); end end --- 随机选择兵种类型 function UGCPlayerController:RandSelectSoldierType() UGCLogSystem.Log("[UGCPlayerController:RandSelectSoldierType] 执行") local Soldier = math.random(table.getCount(SoldierConfig.ESoldierType)) UGCLogSystem.Log("[UGCPlayerController:RandSelectSoldierType] Soldier = %s", tostring(Soldier)) UGCGameSystem.GameState:Server_SelectSoldier(self.PlayerKey, Soldier); end -- 重新装备 function UGCPlayerController:EquipSelf() if UGCGameSystem.IsServer() then self:CheckSoldierTypeAndWeapons(); self:EquipWeapon(self.SelectWeapons); UnrealNetwork.CallUnrealRPC(self, self, "EquipSelf"); else -- 获取玩家有几个槽 UGCEventSystem.SetTimer(self, function() local Type = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey] local WeaponCount = SoldierConfig.WeaponCount[Type]; for i, v in pairs(SoldierConfig.WeaponLimits[Type]) do if v == EWeaponTypeNew.EWeaponTypeNew_Melee then WeaponCount = WeaponCount - 1 end end ---@type MainControlPanelTochButton_C local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C"); local ShootingUIPanel = MainControlPanel.ShootingUIPanel; if WeaponCount == 0 then ShootingUIPanel.MultiLayer_LeftWeaponSlot:SetVisibility(ESlateVisibility.Collapsed); ShootingUIPanel.MultiLayer_RightWeaponSlot:SetVisibility(ESlateVisibility.Collapsed); elseif WeaponCount == 1 then ShootingUIPanel.MultiLayer_RightWeaponSlot:SetVisibility(ESlateVisibility.Collapsed); end end, 1); end end --- 武器随机 function UGCPlayerController:RandWeapons() local Type = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey] if Type == nil then return; end local WeaponCount = SoldierConfig.WeaponCount[Type]; if WeaponCount == 1 then local WeaponLimit = SoldierConfig.WeaponLimits[Type] UGCLogSystem.LogTree(string.format("[UGCPlayerController:RandWeapons] WeaponLimit ="), WeaponLimit) local List = {}; for Index, NewType in pairs(WeaponLimit) do local Weapons = GetWeaponListByTypeNew(NewType) for c, WeaponId in pairs(Weapons) do List[#List + 1] = WeaponId; end end self.SelectWeapons[#self.SelectWeapons + 1] = List[math.random(#List)]; elseif WeaponCount == 2 then local Config = SoldierConfig.WeaponSet[Type] self.SelectWeapons = Config[math.random(1, table.getCount(Config))]; end UGCLogSystem.LogTree("[UGCPlayerController:RandWeapons] self.SelectWeapons = ", self.SelectWeapons); end ---@param InList table function UGCPlayerController:Server_SelectWeapons(InList) self.SelectWeapons = InList; end UGCPlayerController.EquipWeaponTimer = nil; --- 选择武器 ---@param InList table function UGCPlayerController:EquipWeapon(InList) if table.isEmpty(InList) then return; end local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey); if Pawn == nil or not UE.IsValid(Pawn) or not Pawn:IsAlive() then return; end UGCLogSystem.LogTree(string.format("[UGCPlayerController:EquipWeapon] InList ="), InList) self:EquipDefence(Pawn); self:EquipBombs(Pawn); self:EquipMedications(Pawn); self:AddWeaponItem(Pawn, InList); UGCSendRPCSystem.ActorRPCNotify(self.PlayerKey, self, "PostAddItems") self:PostAddItems(); -- 执行添加物品后操作 UGCLogSystem.Log("[UGCPlayerController:EquipWeapon] 执行玩家添加后操作") Pawn:PostAddItems(); end ---@type table UGCPlayerController.AddWeaponList = {}; function UGCPlayerController:AddOneWeaponItem(Pawn, WeaponId) local Times = 10; local bSuccess = false; repeat bSuccess = Pawn:AddItem(WeaponId, 1); Times = Times - 1 until bSuccess and Times > 0; local AllParts = WeaponSuits[WeaponId]; if not table.isEmpty(AllParts) then local PartListBests = AllParts[EWeaponPartType.Best]; if not table.isEmpty(PartListBests) then local PartList = PartListBests[1]; if not table.isEmpty(PartList) then for PartIndex, PartId in pairs(PartList) do Pawn:AddItem(PartId, 1); end end end end local Bullet = WeaponAmmunitionItem[WeaponId]; if Bullet ~= nil then -- 先给子弹 if self.FillBulletType ~= EFillBulletType.ClipInfinite or self.FillBulletType ~= EFillBulletType.Infinite then Pawn:AddItem(Bullet, AmmoTable[Bullet].Count); end end self:ReloadWeaponById(Pawn, WeaponId); end function UGCPlayerController:AddWeaponItem(Pawn, InList) for index, WeaponId in pairs(InList) do self:AddOneWeaponItem(Pawn, WeaponId); end end function UGCPlayerController:ReloadWeaponById(Pawn, WeaponId) for i, v in pairs(ShootWeaponEnums) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, v) if UE.IsValid(Weapon) then local Id = Weapon:GetWeaponID() UGCLogSystem.Log("[UGCPlayerController:ReloadWeaponById] Id = %d", Id); if WeaponId == nil then self:SetWeaponInfinite(Weapon); else if WeaponId == Id then self:SetWeaponInfinite(Weapon); end end end end end function UGCPlayerController:SetWeaponInfinite(Weapon) if not UE.IsValid(Weapon) then return end if self.FillBulletType == EFillBulletType.Infinite then UGCGunSystem.EnableInfiniteBullets(Weapon, true); elseif self.FillBulletType == EFillBulletType.ClipInfinite then UGCGunSystem.EnableClipInfiniteBullets(Weapon, true); end end --- 第一次验证 function UGCPlayerController:CheckHaveWeapon(InWeaponId) local SlotTable = EWeaponNewTypeSlot[WeaponTable[InWeaponId].TypeNew] local WeaponCount = SoldierConfig.WeaponCount[self:GetSoldierType()]; local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey); if WeaponCount == 1 then local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, SlotTable[1]); if Weapon then return true; end return false; elseif WeaponCount == 2 then -- 分别检测两个是否是这个 local Found = false; for i, v in pairs(SlotTable) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, v); if Weapon then if Weapon:GetWeaponItemID() == InWeaponId then Found = true; break; end end end return Found; end end function UGCPlayerController:FillClipBullet() UGCEventSystem.SetTimer(self, function() local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey); for i, TheEnum in pairs(ShootWeaponEnums) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, TheEnum); local Count = UGCGunSystem.GetMaxBulletNumInOneClip(Weapon); UGCLogSystem.Log("[UGCPlayerController:FillClipBullet] Count = %s", tostring(Count)); end end, 5); end --- 添加物品之后 function UGCPlayerController:PostAddItems() if self:HasAuthority() then self:FillClipBullet(); else end end --- 自己死亡 ---@param KillerPlayerKey PlayerKey function UGCPlayerController:OnSelfDead(KillerPlayerKey) if self:HasAuthority() then self:SpectateOther(); -- 发送 RPC UGCSendRPCSystem.ActorRPCNotify(self.PlayerKey, self, "OnSelfDead", KillerPlayerKey); else -- 关闭技能按钮 WidgetManager:GetPanel(WidgetConfig.EUIType.Main):SetShowButton(false, "WB_UseBuffs"); end end --- 当击杀其他人 ---@param InDeadPlayerKey PlayerKey function UGCPlayerController:OnKillPlayer(InDeadPlayerKey) if self:HasAuthority() then UGCSendRPCSystem.ActorRPCNotify(self.PlayerKey, self, "OnKillPlayer", InDeadPlayerKey); else end end function UGCPlayerController:OnPlayerAssist(InDeadPlayerKey, InKillerPlayerKey) end ---装备炸弹 function UGCPlayerController:EquipBombs(Pawn) local Config = SoldierConfig.Bombs[self:GetSoldierType()]; if table.isEmpty(Config) then return; end for i, v in pairs(Config) do Pawn:AddItem(i, v); end end --- 装备药物 function UGCPlayerController:EquipMedications(Pawn) local Config = SoldierConfig.Medications[self:GetSoldierType()]; if table.isEmpty(Config) then return; end for i, v in pairs(Config) do Pawn:AddItem(i, v); end end --- 装备护甲相关的 function UGCPlayerController:EquipDefence(Pawn) local Type = self:GetSoldierType(); local Armor = SoldierConfig.DefenceItems[Type]; if Armor == nil then return; end if Pawn then Pawn:AddItem(Armor.Armor, 1); Pawn:AddItem(Armor.Helmet, 1); Pawn:AddItem(Armor.Bag, 1); else UGCLogSystem.Log("[UGCPlayerController:EquipDefence] 无法获取玩家 Pawn") end end --- S & C ---@return ESoldierType function UGCPlayerController:GetSoldierType() local Type = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey]; if Type ~= nil then return Type; end UGCGameSystem.GameState:CheckHasSoldier(); return UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey]; end --- 第二次验证 --- UGCPlayerController.HaveWeapons = false; UGCPlayerController.CheckHasWeaponTimer = nil; UGCPlayerController.CheckHasWeaponConstTime = 0.5; function UGCPlayerController:OnEnterRoundSettle() if self.CheckHasWeaponTimer ~= nil then UGCEventSystem.StopTimer(self.CheckHasWeaponTimer); self.CheckHasWeaponTimer = nil; end end function UGCPlayerController:CheckHasWeapon() self.CheckHasWeaponTimer = UGCEventSystem.SetTimerLoop(self, function() self:CheckHasWeapon_Internal(); end, self.CheckHasWeaponConstTime); end function UGCPlayerController:CheckHasWeapon_Internal() UGCLogSystem.LogTree(string.format("[UGCPlayerController:CheckHasWeapon_Internal] Begin self.SelectWeapons ="), self.SelectWeapons) if table.isEmpty(self.SelectWeapons) then self:RandWeapons(); -- 添加上去 self:EquipSelf(); else local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) local ArmorItem = UGCBackPackSystem.GetArmorInBackpack(Pawn); local HelmatItem = UGCBackPackSystem.GetHelmatInBackpack(Pawn); if ArmorItem.Count == 0 or HelmatItem.Count == 0 then self:EquipSelf(); else if self.CheckHasWeaponTimer ~= nil then UGCEventSystem.StopTimer(self.CheckHasWeaponTimer); self.CheckHasWeaponTimer = nil; end end end UGCLogSystem.LogTree(string.format("[UGCPlayerController:CheckHasWeapon_Internal] End self.SelectWeapons ="), self.SelectWeapons) end --- 通过 ItemId 进行验证 function UGCPlayerController:CheckHaveItemId(InItemId, InCount) local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey); if Pawn == nil or UE.IsValid(Pawn) then UGCLogSystem.Log("[UGCPlayerController:CheckHaveItemId] 玩家不存在!!!") return; end local AllDatas = UGCBackPackSystem.GetAllItemData(Pawn); for i, v in pairs(AllDatas) do if v.ItemID == InItemId then if v.Count == InCount then return true, 0; end return true, InCount - v.Count; end end return false, 0; end --- 观战 function UGCPlayerController:SpectateOther() local OBKeys = {}; local LocalTeamId = UGCPlayerStateSystem.GetTeamID(self.PlayerKey); local PlayerLists = UGCGameSystem.GameState.PlayerTeams[LocalTeamId] for i, PlayerKey in pairs(PlayerLists) do if PlayerKey ~= self.PlayerKey then OBKeys[#OBKeys + 1] = PlayerKey; end end if table.getCount(OBKeys) == 0 then UnrealNetwork.CallUnrealRPC(self, self, "Client_CanSpectateOthers", 0); return; end UGCGameSystem.MyObserversChangeTarget(self); UGCGameSystem.EnterSpectating(self); UGCGameSystem.ChangeAllowOBPlayerKeys(self, OBKeys); self.InSpectate = true; UnrealNetwork.CallUnrealRPC(self, self, "Client_CanSpectateOthers", 1); end function UGCPlayerController:ExitSpectate() UGCGameSystem.LeaveSpectating(self); end UGCPlayerController.ClearSpectateButtonTimer = nil; ---@param InVal int32 控制的值 function UGCPlayerController:Client_CanSpectateOthers(InVal) if InVal == 0 then -- 说明当前无法查看其他人,也就不进入观战 elseif InVal == 1 then -- 说明当前可以观战,进入观战 self:CloseOBUI(); elseif InVal == 2 then WidgetManager:ClosePanel(WidgetConfig.EUIType.Spectation); end end -- 清空玩家身上所有的东西 function UGCPlayerController:ClearAllWeaponsAndProp() local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey); if UE.IsValid(Pawn) and Pawn:IsAlive() then Pawn:ClearAllWeaponsAndProp(); end end function UGCPlayerController:SetEnableInfiniteBulletsType(IsEnable, Type) UGCLogSystem.Log("[UGCPlayerController:SetEnableInfiniteBulletsType] 设置 %s 开启无限子弹,类型是:%s", tostring(IsEnable), tostring(Type)); if not IsEnable then self.FillBulletType = EFillBulletType.None; else self.FillBulletType = Type; end end ---@param InType ESoldierType function UGCPlayerController:Server_PlayerUseBuff(InType) -- 执行自己身上的 Buff local SoldierBase = self.Soldiers[InType] if SoldierBase == nil then return end SoldierBase:TriggerSkill(); -- 同步回去 end -- 准备正式开始游戏 function UGCPlayerController:OnStartRound(IsReset) if self:HasAuthority() then -- 通知自己身上的所有 SoliderBase 都准备好 for i, v in pairs(self.Soldiers) do v:RestSoldier(); end UnrealNetwork.CallUnrealRPC(self, self, "OnStartRound"); else WidgetManager:GetPanel(WidgetConfig.EUIType.Main):EnableButton("WB_UseBuffs") if self:HasSkills() then WidgetManager:GetPanel(WidgetConfig.EUIType.Main):SetShowButton(true, "WB_UseBuffs") else WidgetManager:GetPanel(WidgetConfig.EUIType.Main):SetShowButton(false, "WB_UseBuffs") end if not IsReset then UGCEventSystem.SendEvent(EventTypes.ResetRound) end end end function UGCPlayerController:HasSkills() local Type = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey]; return SoldierConfig.Skills[Type].SkillType == SoldierConfig.ESkillType.Active; end --- 正式开始游戏 function UGCPlayerController:OnFormalStart() --self:SetCanMove(true); self:EquipSelf(); end function UGCPlayerController:SetCanMove(IsCan) --self:SetCinematicMode(not IsCan, false, false, true, false); end return UGCPlayerController;