444 lines
16 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
---@class UGCPlayerPawn_C:BP_UGCPlayerPawn_C
--Edit Below--
---@type UGCPlayerPawn_C
local UGCPlayerPawn = {};
UGCPlayerPawn.Strong = 1.;
UGCPlayerPawn.Defence = 1.;
UGCPlayerPawn.PoisonDefence = 1.;
--- 启用毒圈
UGCPlayerPawn.DashDuration = -1
UGCPlayerPawn.CachedSTCharacterMovementGravityScale = 1.5
--- 毒圈伤害
UGCPlayerPawn.PoisonDamage = 0;
function UGCPlayerPawn:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
self:AddEvent()
-- 开启攀爬
self.bVaultIsOpen = true;
-- 开启滑铲
self.IsOpenShovelAbility = true;
if self:HasAuthority() then
-- 装备一下
local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey);
if UE.IsValid(PC) then end
-- 检查是否存在 Soldier Type
local SoldierType = UGCGameSystem.GameState.PlayerSoldierType[self.PlayerKey];
if SoldierType ~= nil then
self:OnSetSoldierType(SoldierType); -- 改变对应数据即可
end
self:EnablePickUp(false);
else
UGCEventSystem.AddListener(EventTypes.SkillBenefit, self.OnSkillBenefit, self)
end
---- 缓存一下
self:Client_OnShootEmitter(nil);
self.DamageNotifyDelegate:Add(self.OnDamageNotify_Test, self)
-- 获取 Init
UGCEventSystem.SetTimer(self, function()
self:InitPawn()
end, 1.3)
end
--function UGCPlayerPawn:ReceivePossessed(NewController)
-- NewController:SetCanMove(false);
--end
function UGCPlayerPawn:AddEvent()
if self:HasAuthority() then
self.DeadNotifyDelegate:Add(self.PlayerDead, self)
self.DamageNotifyDelegate:Add(self.PlayerInjury, self)
else
end
end
function UGCPlayerPawn:RemoveEvent()
if self:HasAuthority() then
self.DeadNotifyDelegate:Remove(self.PlayerDead, self)
self.DamageNotifyDelegate:Remove(self.PlayerInjury, self)
else
end
end
function UGCPlayerPawn:InitPawn()
-- 执行初始化
if IsClient then
local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C");
MainControlPanel:SetVisibility(ESlateVisibility.SelfHitTestInvisible);
end
end
function UGCPlayerPawn:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
--self:TickDash(DeltaTime)
end
function UGCPlayerPawn:ReceiveEndPlay()
self:RemoveEvent()
self.SuperClass.ReceiveEndPlay(self);
end
--- 设置兵种特征(在玩家进入的时候)
---@param InType int32 兵种类型
function UGCPlayerPawn:OnSetSoldierType(InType)
local Feature = SoldierConfig.Features[InType]
if table.isEmpty(Feature) then
return ;
end
for i, v in pairs(Feature) do
if i == SoldierConfig.ESpecialType.Health then
UGCPawnAttrSystem.SetHealthMax(self, UGCPawnAttrSystem.GetHealthMax(self) * v)
UGCPawnAttrSystem.SetHealth(self, UGCPawnAttrSystem.GetHealthMax(self));
elseif i == SoldierConfig.ESpecialType.Speed then
UGCPawnAttrSystem.SetSpeedScale(self, UGCPawnAttrSystem.GetSpeedScale(self) * v)
elseif i == SoldierConfig.ESpecialType.Damage then
-- 设置对应数据即可
self:SetParam('Strong', self.Strong * v);
elseif i == SoldierConfig.ESpecialType.Poison then
self.Defence = self.Defence * v; -- 永久改变
elseif i == SoldierConfig.ESpecialType.Jump then
UGCPawnAttrSystem.SetJumpZVelocity(self, UGCPawnAttrSystem.GetJumpZVelocity(self) * v);
end
end
end
function UGCPlayerPawn:GetReplicatedProperties()
return { "PoisonDamage", "Lazy" }
end
function UGCPlayerPawn:GetAvailableServerRPCs()
return "ReplacePartId"
end
---100000 - 199999 武器
---200000 - 299999 配件
---300000 - 399999 子弹
---400000 - 499999 衣服
---500000 - 599999 背包 / 护甲 / 头盔等
---600000 - 699999 补给品、投掷物等
---700000 - 799999 降落伞
---800000 - 899999 头盔、护甲皮肤
--- 清楚所有武器配件
function UGCPlayerPawn:ClearAllWeaponsAndProp()
local AllItem = UGCBackPackSystem.GetAllItemData(self)
if AllItem then
for Index, Item in pairs(AllItem) do
if (Item.ItemID > 100000 and Item.ItemID < 400000) -- 武器、配件、子弹等
or (Item.ItemID >= 8300000) -- 自定义的东西
or (Item.ItemID > 500000 and Item.ItemID < 700000) -- 补给品
then
UGCBackPackSystem.DropItem(self, Item.ItemID, Item.Count, true)
end
end
end
end
--- 添加物品
---@param InItemId int32
---@param InCount int32
function UGCPlayerPawn:AddItem(InItemId, InCount)
return UGCBackPackSystem.AddItem(self, InItemId, InCount);
end
function UGCPlayerPawn:PostAddItems() end
function UGCPlayerPawn:OnSkillBenefit(InUseKey, InBenefitPlayers, InBuffType)
-- 分别执行不同的特效
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:OnSkillBenefit] 操作的玩家:%d, InBenefitPlayers =", InUseKey), InBenefitPlayers)
end
UGCPlayerPawn.PlayerUseBuffs = {};
function UGCPlayerPawn:OnPlayerUseBuff(InPlayerKey, InBuffType, InBuffInfo, InServerTime)
-- 全局提示
local Params = { InPlayerKey = InPlayerKey, InBuffType = InBuffType, InBuffInfo = InBuffInfo, InServerTime = InServerTime };
UGCLogSystem.LogTree('[UGCPlayerPawn:OnPlayerUseBuff] Params = ', Params);
UGCLogSystem.Log("[UGCPlayerPawn:OnPlayerUseBuff] self = %s", tostring(self))
local TeamId = UGCGameSystem.GameState:GetPlayerTeamId(InPlayerKey);
if TeamId == DefaultSettings.LocalTeamId then
local Name = UGCGameSystem.GameState:GetPlayerNameByPlayerKey(InPlayerKey);
UGCLogSystem.Log("[UGCPlayerPawn:OnPlayerUseBuff] Name = %s", Name)
if self.PlayerUseBuffs[InServerTime] == nil then
self.PlayerUseBuffs[InServerTime] = InPlayerKey;
UGCWidgetManagerSystem.ShowTipsUI(string.format('%s 启动了技能:%s', Name, BuffConfig.BuffInfo[InBuffType].Desc));
end
end
end
UGCPlayerPawn.CachedGravity = 1;
UGCPlayerPawn.ImpulseLength = 9;
UGCPlayerPawn.ImpulseMoveTime = 0.1;
UGCPlayerPawn.StartLoc = nil;
UGCPlayerPawn.LimitDis = 50.;
--- 给定一个方向
function UGCPlayerPawn:AddImpulse(InImpulse)
UGCLogSystem.Log("[UGCPlayerPawn:AddImpulse] Impulse = %s", VectorHelper.ToString(InImpulse));
-- 缓存重力
self.StartLoc = self:K2_GetActorLocation();
self.CharacterMovement.Velocity = VectorHelper.MulNumber(InImpulse, VectorHelper.Length(self.CharacterMovement.Velocity));
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(InImpulse, self.ImpulseLength * 40), true);
if IsServer then
UnrealNetwork.CallUnrealRPC(UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey), self, "AddImpulse", InImpulse);
UGCEventSystem.SetTimer(self, function()
self:StopImpulse();
end, self.ImpulseMoveTime);
end
GlobalTickTool:AddTick(self, function(o, dt, ServerTime)
o.CharacterMovement:AddImpulse(VectorHelper.MulNumber(InImpulse, self.ImpulseLength * dt), true);
if o.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Falling then
o.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling);
end
self.CharacterMovement.Velocity = VectorHelper.MulNumber(InImpulse, math.clamp(VectorHelper.Length(self.CharacterMovement.Velocity), 0, 300));
-- 计算距离,超过
local Dis = VectorHelper.GetDistance(self:K2_GetActorLocation(), self.StartLoc);
if Dis > self.LimitDis then
self:StopImpulse();
GlobalTickTool:RemoveTick(self);
end
end, nil, self.ImpulseMoveTime);
end
function UGCPlayerPawn:StopImpulse()
if IsServer then
UnrealNetwork.CallUnrealRPC(UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey), self, "StopImpulse");
end
end
--------------------------------- Damage ---------------------------------
---@public
---@param InParamName string
---@param InVal float
function UGCPlayerPawn:SetParam(InParamName, InVal)
if self[InParamName] ~= nil then self[InParamName] = InVal; end
UGCLogSystem.Log("[UGCPlayerPawn:SetParam] Pawn: %s %s To %s", UE.GetName(self), InParamName, tostring(InVal));
end
---@public
---@param InParamName string
---@return float
function UGCPlayerPawn:GetParam(InParamName)
return self[InParamName];
end
--- 接收到伤害之后执行
--- S & C
---@field BPReceiveDamage fun(Damage:float,DamageType:UDamageType,InstigatedBy:AController,DamageCauser:AActor)
function UGCPlayerPawn:BPReceiveDamage(Damage, DamageType, InstigatedBy, DamageCauser)
UGCLogSystem.Log("[UGCPlayerPawn:BPReceiveDamage] Damage = %s", tostring(Damage));
-- 此时已经是玩家受到伤害了,用当前玩家的血量进行判断
end
UGCPlayerPawn.InPoisonDamage = false;
function UGCPlayerPawn:HandlePoisonDamage(InDamage, InCurrHealth, InMaxHealth)
-- 显示毒圈标识
self.InPoisonDamage = true;
self.PoisonDamage = InDamage;
UGCEventSystem.SendEvent(EventTypes.PlayerPoisonDamage, self.PlayerKey, InDamage);
end
-- 死亡之后不掉落死亡盒子
function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater)
return true;
end
function UGCPlayerPawn:GetKillAssists()
return self.KillAssists;
end
--- 玩家获取武器
---@param Weapon ASTExtraShootWeapon
function UGCPlayerPawn:OnPostGetWeapon(Weapon)
if UGCGameSystem.IsServer() then
local ItemId = Weapon:GetWeaponItemID();
if ItemId == 107001 then
-- 产生一个放射性伤害
Weapon:SetReloadTime(0.3);
end
-- 检测当前是否是志愿兵
local SoldierType = UGCGameSystem.GameState:GetSoldierTypeByPlayerKey(self.PlayerKey)
if SoldierType == SoldierConfig.ESoldierType.Volunteer then
UGCGunSystem.EnableClipInfiniteBullets(Weapon, true);
end
end
end
--- 玩家装备武器
---@param slot ESurviveWeaponPropSlot
function UGCPlayerPawn:OnEquipWeapon(slot)
-- 玩家装备武器
if slot == ESurviveWeaponPropSlot.SWPS_HandProp then return ; end
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, slot);
if Weapon ~= nil and UE.IsValid(Weapon) then
UGCEventSystem.SendEvent(EventTypes.PlayerChangeWeapon, self, slot, Weapon);
end
end
--- 替换配件
---@param InPartId int32
---@param InType EWeaponPartType
function UGCPlayerPawn:ReplacePartId(InPartId, InType)
UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 替换 InPartId = %d", InPartId);
-- 移除当前
local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self);
if Weapon == nil then return ; end
if not ItemTool.IsShootWeapon(Weapon) then return ; end
local DefineID = ItemTool.GetDefineIDBySocketType(Weapon, ItemTool.GetWeaponAttachmentSocketType(InType));
if DefineID then
UGCBackPackSystem.DropItemByInstanceID(self, DefineID.InstanceID, 1, true);
end
if InPartId ~= 0 then ItemTool.AddItem(self, InPartId, 1) end
local PS = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey);
table.func(PS, "UpdateWeaponAttachment", self, Weapon);
end
--- 武器攻击到什么东西的时候
---@param ShootWeapon ASTExtraShootWeapon
---@param Bullet ASTExtraShootWeaponBulletBase
---@param HitInfo FHitResult
function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo)
if UGCGameSystem.IsServer() then
local ItemId = ShootWeapon:GetWeaponItemID();
local Loc = VectorHelper.Add(HitInfo.Location, { X = 0, Y = 0, Z = 30 });
if ItemId == 107001 then
local DamageChannel = ECollisionChannel.ECC_Visibility;
UGCGameSystem.ApplyRadialDamage(
60,
10,
Loc,
10,
200,
4,
EDamageType.RadialDamage,
{},
ShootWeapon,
UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey),
DamageChannel,
ItemId
);
UnrealNetwork.CallUnrealRPC_Multicast(self, "Client_OnShootEmitter", Loc);
end
end
end
function UGCPlayerPawn:Client_OnShootEmitter(Location)
local Path = '/Game/Arts_Effect/ParticleSystems/Share/P_AH6_baozha_01.P_AH6_baozha_01';
UE.AsyncLoadObject_Cached(Path, function(TargetObject)
if Location == nil then return ; end
GameplayStatics.SpawnEmitterAtLocation(self, TargetObject, Location, VectorHelper.RotZero(), VectorHelper.ScaleOne(), true);
end)
end
-------------------------------------------------- Delegate --------------------------------------------------
---@param DamageInfo FDamageInfoCollection
---@return uint, uint, int, EDamageType, bool, float, float VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue
function UGCPlayerPawn:GetDamageInfoCollectionInfo(DamageInfo)
local CauserController = DamageInfo.Instigator
local WeaponID = -1
local CauserKey = CauserController and CauserController.PlayerKey or -1
local VictimKey = self.PlayerKey
local CauserItemID = DamageInfo.CauserItemID
--- 近战投掷、投掷手雷
if CauserItemID then
WeaponID = CauserItemID
end
UGCLogSystem.Log("[UGCPlayerPawn_GetDamageInfoCollectionInfo] WeaponID: %d", WeaponID)
local Distance = 0.
if CauserController and CauserController:GetPlayerCharacterSafety() then
Distance = VectorHelper.GetDistance(self:K2_GetActorLocation(), CauserController:GetPlayerCharacterSafety():K2_GetActorLocation())
end
local IsHeadShotDamage = (DamageInfo.Hit.BoneName == "head")
return VictimKey, CauserKey, WeaponID, DamageInfo.DamageType, IsHeadShotDamage, Distance, DamageInfo.Damage
end
---@param DamageInfo FDamageInfoCollection
function UGCPlayerPawn:PlayerDead(DamageInfo)
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
UGCSendRPCSystem.RPCEvent(nil, EventTypes.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
UGCEventSystem.SendEvent(EventTypes.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
end
---@param DamageInfo FDamageInfoCollection
---@param ReturnValue float
function UGCPlayerPawn:PlayerInjury(DamageInfo)
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
UGCSendRPCSystem.RPCEvent(CauserKey, EventTypes.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
end
------------------------------------------------ Delegate End ------------------------------------------------
function UGCPlayerPawn:PlayerDashSkill(Duration, DashForce)
--local ForwardV = self:GetActorForwardVector()
--self.DashDuration = 0.5
--self.LaunchCharacterForce = VectorHelper.MulNumber(ForwardV, 10000)
self:DashTo(self:GetActorForwardVector(), Duration, DashForce)
UGCSendRPCSystem.ActorRPCNotify(nil, self, "DashTo", VectorHelper.ToLuaTable(self:GetActorForwardVector()), Duration, DashForce)
UGCLogSystem.Log("[UGCPlayerPawn_PlayerSprintSkill] Finish")
end
--- 关闭重力影响
---@param On bool
function UGCPlayerPawn:TurnOffGravityScale(On)
if On then
self.STCharacterMovement.GravityScale = 0;
else
self.STCharacterMovement.GravityScale = self.CachedSTCharacterMovementGravityScale;
end
end
function UGCPlayerPawn:EnableDashTo(On)
self:TurnOffGravityScale(On);
end
function UGCPlayerPawn:TickDash(DeltaTime)
-- 冲刺时间
if self.DashDuration > 0 then
self.DashDuration = self.DashDuration - DeltaTime;
if self.DashDuration <= 0 then
self.LaunchDir = nil;
self:EnableDashTo(false);
end
if self.LaunchDir then
local TargetLocation = VectorHelper.Add(self:K2_GetActorLocation(), VectorHelper.MulNumber(self.LaunchDir, self.LaunchCharacterForce * DeltaTime))
local bMoveSucceed, HitRes = self:K2_SetActorLocation(TargetLocation, true)
-- 平移过程要检测下落
if self.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Falling then
--UGCLog.Log("[MoveMode] %s -> %s", tostring(self.CharacterMovement.MovementMode), tostring(EMovementMode.MOVE_Falling));
self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling);
end
end
end
end
function UGCPlayerPawn:DashTo(Dir, Duration, DashForce)
self.LaunchCharacterForce = DashForce;
self.DashDuration = Duration;
self:EnableDashTo(true);
self.LaunchDir = Dir;
end
---@param DamageInfo FDamageInfoCollection
function UGCPlayerPawn:OnDamageNotify_Test(DamageInfo)
UGCLogSystem.Log("[UGCPlayerPawn:OnDamageNotify_Test] Damage = %s", tostring(DamageInfo.Damage));
end
----------------------------------- 装备 -----------------------------------
return UGCPlayerPawn;