UGCProjects/SoloKing/Script/Blueprint/UGCPlayerPawn.lua
2025-02-04 17:59:01 +08:00

392 lines
14 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 UGCPlayerPawn_C:BP_UGCPlayerPawn_C
--Edit Below--
---@type UGCPlayerPawn_C
local UGCPlayerPawn = {};
function UGCPlayerPawn:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
self.bVaultIsOpen = DefaultSettings.OpenVault;
self.DamageNotifyDelegate:Add(self.PlayerInjury, self)
end
function UGCPlayerPawn:ReceiveEndPlay()
if GlobalTickTool then GlobalTickTool:RemoveTickByOwner(self) end
self.SuperClass.ReceiveEndPlay(self);
end
function UGCPlayerPawn:GetAvailableServerRPCs()
return "UpdateWeaponParts", "ReplacePartId"
end
function UGCPlayerPawn:ReceivePossessed(NewController)
self.SuperClass.ReceivePossessed(self, NewController);
UGCLogSystem.Log("[UGCPlayerPawn:ReceivePossessed] 是否可以滑铲:%s", tostring(GameState.EnableShovel));
UGCPawnSystem.DisabledPawnState(self, EPawnState.Shoveling, not GameState.EnableShovel);
table.func(MiniManager, "OnPlayerPossessed", self, NewController);
end
---@return bool 是否开启掉落盒子
function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater) return DefaultSettings.EnableDeadBox; end
----------------------------------------- 玩家伤害处理 -----------------------------------------
function UGCPlayerPawn:PreInstigatedDamage(DamageAmount, DamageEvent, DamageCauser, Victim)
UGCLogSystem.Log("[UGCPlayerPawn:PreInstigatedDamage] DamageAmount = %f", DamageAmount);
return DamageAmount;
end
---@param ShootWeapon ASTExtraShootWeapon
---@param Bullet ASTExtraShootWeaponBulletBase
function UGCPlayerPawn:UGC_WeaponShootBulletEvent(ShootWeapon, Bullet)
self.SuperClass.UGC_WeaponShootBulletEvent(self, ShootWeapon, Bullet);
end
--- 武器攻击到什么东西的时候
---@param ShootWeapon ASTExtraShootWeapon
---@param Bullet ASTExtraShootWeaponBulletBase
---@param HitInfo FHitResult
function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo)
--local HitActor = HitInfo.Actor:Get()
--if HitActor and UE.IsValid(HitActor) and UE.Is then
-- UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] 击中 %s", UE.GetName(HitActor));
--
--end
end
function UGCPlayerPawn:PlayerInjury(DamageInfo)
if IsServer then
local DamageData = self:GetDamageData(DamageInfo)
MiniManager:OnPlayerInjury(DamageData.VictimKey, DamageData.CauserKey, DamageData);
end
end
---@param DamageInfo FDamageInfoCollection
function UGCPlayerPawn:GetDamageData(DamageInfo)
local CauserController = DamageInfo.Instigator
local WeaponID = -1
local CauserKey = CauserController and CauserController.PlayerKey or -1
local VictimKey = self.PlayerKey
local CauserItemID = DamageInfo.CauserItemID
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:GetDamageData] DamageInfo ="), DamageInfo)
--- 近战投掷、投掷手雷
if CauserItemID then WeaponID = CauserItemID; end
UGCLogSystem.Log("[UGCPlayerPawn_GetDamageInfoCollectionInfo] WeaponID:%d", WeaponID)
--local Distance = 0.
--if CauserController and CauserController.Pawn then
-- Distance = VectorHelper.GetDistance(self:K2_GetActorLocation(), CauserController.Pawn:K2_GetActorLocation())
--end
local IsHeadShotDamage = (DamageInfo.Hit.BoneName == "head");
return {
VictimKey = VictimKey, -- 受伤者
CauserKey = CauserKey, -- 导致者
WeaponID = WeaponID, -- 武器ID
DamageType = DamageInfo.DamageType,
IsHeadShotDamage = IsHeadShotDamage, -- 暴击
--Distance = Distance, -- 距离,
Damage = DamageInfo.Damage,
};
end
-------------------------------- 玩家物品处理 --------------------------------
--- 添加物品,如果是要添加武器,可以在后面的选项进行配置,可添加选项为 是否需要添加对应的配件 武器无限子弹配置 EFillBulletType (bool&EFillBulletType | EFillBulletType)
---@param InItemId int32
---@param InItemCount int32
function UGCPlayerPawn:AddItem(InItemId, InItemCount, ...)
UGCLogSystem.Log("[UGCPlayerPawn:AddItem] InItemId = %d", InItemId);
ItemTool.AddItem(self, InItemId, InItemCount, ...);
UGCLogSystem.Log("[ItemTool.AddItem] 执行")
ItemTool.FillAllWeaponBullets(self);
UGCEventSystem.SetTimer(self, function()
UGCLogSystem.Log("[ItemTool.AddItem] 再次添加子弹")
ItemTool.FillAllWeaponBullets(self);
end, 1);
end
--- 添加初始物品
function UGCPlayerPawn:AddInitItems(Weapons)
if table.isEmpty(Weapons) then Weapons = DefaultSettings.PlayerInitEquipment end
if not table.isEmpty(Weapons) then
for i, v in pairs(Weapons) do
local ItemId = -1;
if type(v[1]) == 'string' then
local Item = EnglishNamedWeapon[v[1]]
if Item == nil then
ItemId = ItemNameTable[v[1]] == nil and ItemId or ItemNameTable[v[1]]
else
ItemId = Item.ItemId;
end
elseif type(v[1]) == 'number' then
ItemId = v[1];
end
local Params = {};
if #v > 1 then for c = 2, #v do Params[#Params + 1] = v[c]; end end
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:AddInitItems] First = %s, Params =", v[1]), Params)
if ItemId ~= -1 then self:AddItem(ItemId, table.unpackTable(Params)); end
end
end
end
---
---@param slot ESurviveWeaponPropSlot
---@overload fun(slot:ESurviveWeaponPropSlot) OnEquipWeapon
function UGCPlayerPawn:OnEquipWeapon(slot)
--UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] slot = %s, ESurviveWeaponPropSlot.SWPS_HandProp = %d", tostring(slot), ESurviveWeaponPropSlot.SWPS_HandProp);
--if slot == ESurviveWeaponPropSlot.SWPS_HandProp then
-- UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] 切换成拳头")
--end
UGCEventSystem.SendEvent(EventTypes.PlayerChangeWeapon, self, slot, UGCWeaponManagerSystem.GetWeaponBySlot(self, slot));
end
--- 当玩家获取武器之后执行
---@param Weapon ASTExtraShootWeapon
function UGCPlayerPawn:OnPostGetWeapon(Weapon)
table.func(MiniManager, "OnPlayerGetWeapon", self, Weapon)
--- 绑定 delegate
if ItemTool.IsShootWeapon(Weapon) then
--- 客户端
--Weapon.OnBulletNumChangeDelegate:Add(function()
-- UGCLogSystem.Log("[UGCPlayerPawn:OnPostGetWeapon] 子弹数量改变");
--end, self);
--
--Weapon.OnWeaponShootDelegate:Add(function()
-- UGCLogSystem.Log("[UGCPlayerPawn:OnPostGetWeapon] 武器开火")
--end, self);
Weapon.OnDSBulletNumChangeDelegate:Add(self.OnBulletNumChanged, self);
end
end
--- 玩家是否有近战武器
function UGCPlayerPawn:IsPawnHasMeleeWeapon(WeaponID, Count)
local HadCount = 0;
local AllDatas = UGCBackPackSystem.GetAllItemData(self);
for i, Info in pairs(AllDatas) do
if Info.ItemID == WeaponID then
HadCount = HadCount + Info.Count;
end
end
if Count == HadCount then return true; end
return false, Count;
end
--- 检查玩家是否在 Slot 上有武器
function UGCPlayerPawn:IsPawnHasShootWeapon(WeaponID, Slot)
if Slot then
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, Slot);
if Weapon and UE.IsValid(Weapon) then
if Weapon:GetWeaponItemID() == WeaponID then
return true;
end
end
else
for i, Enum in pairs(ShootWeaponEnums) do
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, Enum)
if Weapon and UE.IsValid(Weapon) then
if Weapon:GetWeaponItemID() == WeaponID then
return true;
end
end
end
end
return false;
end
UGCPlayerPawn.CheckSlotWeaponsTimer = nil;
function UGCPlayerPawn:CloseCheckSlotWeaponsTimer()
if self.CheckSlotWeaponsTimer then
UGCEventSystem.StopTimer(self.CheckSlotWeaponsTimer);
self.CheckSlotWeaponsTimer = nil;
end
end
---@type table<ESurviveWeaponPropSlot, int[]> 插槽武器
UGCPlayerPawn.SlotWeapons = {};
---@param Weapons table<ESurviveWeaponPropSlot, int[]> 插槽武器
function UGCPlayerPawn:UpdateSlotWeapons(Weapons)
self.SlotWeapons = TableHelper.DeepCopyTable(Weapons);
for i = 0, ESurviveWeaponPropSlot.SWPS_Max do
if self.SlotWeapons[i] then
self:CheckHasSlotWeapon(i, self.SlotWeapons[i]);
end
end
self:AddAllTelescopes();
self:CheckSlotWeapons();
end
function UGCPlayerPawn:AddAllTelescopes()
local AllDatas = UGCBackPackSystem.GetAllItemData(self)
local HadTeles = {};
for i, v in pairs(AllDatas) do
if GetItemIdType(v.ItemID) == 203 then
HadTeles[v.ItemID] = v.Count;
end
end
-- 直接给他所有的配件
for i, v in pairs(WeaponTypeParts[EWeaponPartType.Telescope]) do
if HadTeles[v] == nil then
ItemTool.AddItem(self, v, 1, false);
end
end
end
--- 通过插槽检查武器需要先配置好之后再启动该方法仅限两把武器如果只有一把武器SlotWeapons的第一个值必须为 SWPS_MainShootWeapon1
function UGCPlayerPawn:CheckSlotWeapons()
if table.isEmpty(self.SlotWeapons) then return self:CloseCheckSlotWeaponsTimer(); end
UGCLogSystem.Log("[UGCPlayerPawn:CheckSlotWeapons] 开始检测是否添加")
self.CheckSlotWeaponsTimer = UGCEventSystem.SetTimerLoop(self, function()
for i = 0, ESurviveWeaponPropSlot.SWPS_Max do
if self.SlotWeapons[i] then
self:CheckHasSlotWeapon(i, self.SlotWeapons[i]);
end
end
end, 1);
end
---@param Slot ESurviveWeaponPropSlot
---@param WeaponID int32
function UGCPlayerPawn:CheckHasSlotWeapon(Slot, WeaponID)
if Slot == nil then return ; end
if self.SlotWeapons[Slot] == nil then self.SlotWeapons[Slot] = WeaponID; end
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, Slot);
if Weapon == nil or not UE.IsValid(Weapon) then
ItemTool.AddWeaponItem(self, WeaponID, 1, true, EFillBulletType.ClipInfinite);
return ;
end
local SlotWeaponID = Weapon:GetWeaponItemID();
if SlotWeaponID == WeaponID then
self.SlotWeapons[Slot] = nil;
return ;
end
local DefineID = Weapon:GetItemDefineID();
ItemTool.RemoveWeapon(self, Weapon);
ItemTool.AddWeaponItem(self, WeaponID, 1, true, EFillBulletType.ClipInfinite);
end
UGCPlayerPawn.CurrBulletNum = -1;
function UGCPlayerPawn:OnBulletNumChanged(Weapon)
local BulletCount = Weapon.CurBulletNumInClip;
if self.CurrBulletNum == -1 then self.CurrBulletNum = BulletCount; end
if self.CurrBulletNum > BulletCount then
local ItemID = Weapon:GetWeaponItemID();
table.func(MiniManager, "OnBulletNumChange", self.PlayerKey, ItemID, self.CurrBulletNum, BulletCount);
end
self.CurrBulletNum = BulletCount;
end
--- 替换配件
---@param InPartId int32
---@param InType EWeaponPartType
function UGCPlayerPawn:ReplacePartId(InPartId, InType)
UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 替换 InPartId = %s", tostring(InPartId));
-- 移除当前
local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self);
if Weapon == nil or (not UE.IsValid(Weapon)) then
return UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 不存在武器 或 武器无效");
end
local ItemID = Weapon:GetWeaponItemID();
if table.isEmpty(WeaponSuits[ItemID]) then
return UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 武器不是 射击武器")
end
-- 找到类型
if InType == nil then InType = WeaponParts[InPartId].Type end
local SocketType = ItemTool.GetWeaponAttachmentSocketType(InType);
local DefineID = ItemTool.GetDefineIDBySocketType(Weapon, SocketType);
if DefineID then ItemTool.RemoveItemByDefineID(self, DefineID); end
if InPartId ~= 0 then
UGCGunSystem.CreateAndAddGunAttachment(Weapon, InPartId);
UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 添加配件: %d", InPartId);
-- 检查武器上是否有这个配件
local PartDefineID = ItemTool.GetDefineIDBySocketType(Weapon, SocketType);
if PartDefineID == nil or PartDefineID.TypeSpecificID ~= InPartId then
UGCGunSystem.CreateAndAddGunAttachment(Weapon, InPartId);
local ItemIds = ItemTool.GetWeaponParts(Weapon);
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:ReplacePartId] ItemIds ="), ItemIds);
end
end
if ArchiveTable[self.PlayerKey].Weapons == nil then ArchiveTable[self.PlayerKey].Weapons = {}; end
ArchiveTable[self.PlayerKey].Weapons[ItemID] = ItemTool.GetWeaponParts(Weapon);
end
--- 更新武器配件
function UGCPlayerPawn:UpdateWeaponParts(WeaponID, WeaponParts)
ArchiveTable[self.PlayerKey].Weapons[WeaponID] = WeaponParts;
local Weapons = {};
for i, Enum in pairs(AllWeaponEnums) do
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, Enum);
if Weapon and UE.IsValid(Weapon) then
if Weapon:GetWeaponItemID() == WeaponID then
table.insert(Weapons, Weapon);
end
end
end
--
for i, Weapon in pairs(Weapons) do
local HadSet = false;
if Weapon and UE.IsValid(Weapon) then
local CurrWeaponID = Weapon:GetWeaponItemID();
if CurrWeaponID == WeaponID then
-- 直接设置 Parts
ItemTool.SetWeaponParts(Weapon, WeaponParts);
HadSet = true;
end
end
if not HadSet then
UGCLogSystem.LogError("[UGCPlayerPawn:UpdateWeaponParts] 当前武器跟设置的武器不相同,检查一下, WeaponID : %d", WeaponID);
end
end
UnrealNetwork.CallUnrealRPC(self:GetPlayerControllerSafety(), self, "RecvParts", WeaponID, WeaponParts);
end
function UGCPlayerPawn:RecvParts(WeaponID, Parts)
if table.isEmpty(ArchiveTable[LocalPlayerKey]) then ArchiveTable[LocalPlayerKey] = {}; end
if table.isEmpty(ArchiveTable[LocalPlayerKey].Weapons) then ArchiveTable[LocalPlayerKey].Weapons = {}; end
ArchiveTable[LocalPlayerKey].Weapons[WeaponID] = Parts;
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:RecvParts] Parts ="), Parts)
UGCEventSystem.SendEvent(EventTypes.UpdateWeapons, WeaponID)
end
--- 发送 RPC 进行再次同步
function UGCPlayerPawn:UpdateEnterWeapons(Index, Weapons)
if table.isEmpty(ArchiveTable[self.PlayerKey]) then ArchiveTable[self.PlayerKey] = {}; end
if table.isEmpty(ArchiveTable[self.PlayerKey].EnterWeapons) then ArchiveTable[self.PlayerKey].EnterWeapons = {}; end
ArchiveTable[self.PlayerKey].EnterWeapons[Index] = Weapons;
UGCEventSystem.SendEvent(EventTypes.UpdateEnterWeapons);
end
--- 处理飘字 客户端触发
function UGCPlayerPawn:UGC_GetDamageNumberConfigIndex(Damage, IsHeadShot, InstigatorController, DamageCauser, DamageType)
if DefaultSettings.EnableDamageText then
if InstigatorController == LocalPlayerController then
return LocalPlayerController.EnableDamageText and 0 or -1;
end
end
return -1
end
-------------------------------- 测试 --------------------------------
function UGCPlayerPawn:AddOutline()
if IsClient then
if DefaultSettings.EnableOutline then
if self.PlayerKey ~= LocalPlayerKey then
UGCLogSystem.Log("[UGCPlayerPawn:AddOutline] 尝试添加")
STExtraBlueprintFunctionLibrary.EnablePlayerAvatarOutline(self, true);
--UGCGameSystem.GameState:RegisterPostProcessMgr(self);
end
end
end
end
return UGCPlayerPawn;