UGCProjects/ProjectTemp_T/Script/Blueprint/UGCPlayerController.lua
2025-01-04 23:00:19 +08:00

556 lines
17 KiB
Lua

---@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<ESoldierType, SoldierBase> 保存的兵种类型
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<int32, int32>
function UGCPlayerController:Server_SelectWeapons(InList)
self.SelectWeapons = InList;
end
UGCPlayerController.EquipWeaponTimer = nil;
--- 选择武器
---@param InList table<int32, int32>
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<int32, bool>
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;