392 lines
14 KiB
Lua
392 lines
14 KiB
Lua
---@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)
|
||
|
||
--- 仅客户端
|
||
--self.OnCharacterShootDelegate:Add(function(Pawn, Weapon)
|
||
-- UGCLogSystem.Log("[UGCPlayerPawn:ReceiveBeginPlay] %s 开始射击", UE.GetName(Weapon));
|
||
--end, self);
|
||
|
||
--self.OnCharacterStartFireDelegate:Add(function(Pawn, Weapon)
|
||
-- UGCLogSystem.Log("[UGCPlayerPawn:ReceiveBeginPlay] Weapon = %s 开火", UE.GetName(Weapon))
|
||
--end, self)
|
||
end
|
||
|
||
--function UGCPlayerPawn:ReceiveTick(DeltaTime)
|
||
-- self.SuperClass.ReceiveTick(self, DeltaTime);
|
||
--end
|
||
|
||
function UGCPlayerPawn:ReceiveEndPlay()
|
||
if GlobalTickTool then GlobalTickTool:RemoveTickByOwner(self) end
|
||
self.SuperClass.ReceiveEndPlay(self);
|
||
end
|
||
|
||
--function UGCPlayerPawn:GetReplicatedProperties()
|
||
-- return;
|
||
--end
|
||
|
||
function UGCPlayerPawn:GetAvailableServerRPCs()
|
||
return "UpdateWeaponParts"
|
||
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:CheckSlotWeapons();
|
||
|
||
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, "RecvWeaponParts", WeaponID, WeaponParts);
|
||
end
|
||
|
||
function UGCPlayerPawn:RecvWeaponParts(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:RecvWeaponParts] 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; |