444 lines
16 KiB
Lua
444 lines
16 KiB
Lua
---@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;
|