861 lines
31 KiB
Lua
861 lines
31 KiB
Lua
---@class UGCPlayerPawn_C:BP_UGCPlayerPawn_C
|
||
---@field ShapeMesh UStaticMeshComponent
|
||
---@field ShapeTransformCollision UCapsuleComponent
|
||
---@field ShapeTransformation UShapeTransformationComponent
|
||
---@field SpringArm USpringArmComponent
|
||
---@field BigCamera UCameraComponent
|
||
--Edit Below--
|
||
---@type UGCPlayerPawn_C
|
||
local UGCPlayerPawn = {};
|
||
|
||
---@type int32
|
||
UGCPlayerPawn.CameraAddLength = 20;
|
||
---@type UCameraComponent
|
||
UGCPlayerPawn.CurrentCamera = nil;
|
||
---@type USpringArmComponent
|
||
UGCPlayerPawn.CurrentSpringArm = nil;
|
||
--- 是否受到过伤害
|
||
UGCPlayerPawn.bHadTokenDamage = false;
|
||
|
||
---@type table<EPawnBenefitType, float> 这个是暂存用的
|
||
UGCPlayerPawn.BenefitTable = {};
|
||
|
||
UGCPlayerPawn.BaseJumpZVelocity = 443.0;
|
||
|
||
function UGCPlayerPawn:ReceiveBeginPlay()
|
||
self.SuperClass.ReceiveBeginPlay(self);
|
||
|
||
self.bVaultIsOpen = DefaultSettings.OpenVault;
|
||
self.IsOpenShovelAbility = DefaultSettings.OpenShovel;
|
||
|
||
-- 因为无敌时间是 2 s,因此设置为 1.3 s
|
||
UGCEventSystem.SetTimer(self, function() self:InitPawn(); end, 1);
|
||
UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self)
|
||
|
||
---@type PlayerKDAItem1
|
||
local Kda = UGCGameSystem.GameState:GetPlayerKDA(self.PlayerKey)
|
||
if Kda == nil or Kda.Dead == 0 then
|
||
self:FirstBeginPlay();
|
||
else
|
||
self:RespawnBeginPlay(Kda.Dead);
|
||
end
|
||
|
||
self.EquipWeaponComplete:Add(self.OnPlayerEquipWeapon, self)
|
||
self.UnequipWeaponComplete:Add(self.OnPlayerUnequipWeapon, self)
|
||
|
||
if IsClient then
|
||
self.ScopeInComplete:Add(self.OnOpenScope, self)
|
||
self.OnScopeOutDelegate:Add(self.OnOutScope, self)
|
||
end
|
||
|
||
self.BaseGravity = self.STCharacterMovement.GravityScale;
|
||
self.CachedGravity = self.STCharacterMovement.GravityScale;
|
||
self.BaseJumpZVelocity = UGCPawnAttrSystem.GetJumpZVelocity(self);
|
||
|
||
--if self:GetPickupManagerComponent() then
|
||
-- UGCLogSystem.Log("[UGCPlayerPawn:ReceiveBeginPlay] 添加上去")
|
||
-- self:GetPickupManagerComponent().OnPickUpTarger:Add(self.OnPickUpItem, self);
|
||
--end
|
||
|
||
self.OnPlayerPickUp:Add(self.AfterPlayerPickUp, self)
|
||
local BackComp = UGCBackPackSystem.GetBackpackComponent(self)
|
||
if BackComp then
|
||
BackComp.ItemUpdatedDelegate:Add(self.OnItemUpdate, self)
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:ReceiveTick(DeltaTime)
|
||
self.SuperClass.ReceiveTick(self, DeltaTime);
|
||
self:DamageTick(DeltaTime);
|
||
if DefaultSettings.EnableTest then
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:ReceiveEndPlay()
|
||
self.SuperClass.ReceiveEndPlay(self);
|
||
if IsClient then
|
||
self.ScopeInComplete:Remove(self.OnOpenScope, self)
|
||
self.OnScopeOutDelegate:Remove(self.OnOutScope, self)
|
||
end
|
||
|
||
self.EquipWeaponComplete:Remove(self.OnPlayerEquipWeapon, self)
|
||
self.UnequipWeaponComplete:Remove(self.OnPlayerUnequipWeapon, self)
|
||
--if UGCEventSystem then
|
||
-- UGCEventSystem.RemoveListener(EventTypes.ClientAlready, self.OnClientAlready, self)
|
||
--end
|
||
if GlobalTickTool then GlobalTickTool:RemoveAll(self) end
|
||
|
||
if self.PickupManagerComponentRef then
|
||
self.PickupManagerComponentRef.OnPickUpTarger:Remove(self.OnPickUpItem, self);
|
||
end
|
||
self.OnPlayerPickUp:Remove(self.AfterPlayerPickUp, self)
|
||
end
|
||
|
||
function UGCPlayerPawn:GetReplicatedProperties()
|
||
return "CachedBodySize"
|
||
, "CachedGravity"
|
||
end
|
||
|
||
function UGCPlayerPawn:GetAvailableServerRPCs()
|
||
return "RespawnBeginPlay"
|
||
, "OnPickUpItem"
|
||
, "AfterPlayerPickUp"
|
||
, "ReplacePartId"
|
||
end
|
||
|
||
function UGCPlayerPawn:ReceivePossessed(NewController)
|
||
self.SuperClass.ReceivePossessed(self, NewController);
|
||
|
||
if UGCGameSystem.GameState and UGCGameSystem.GameState.MiniGameManager then
|
||
table.func(UGCGameSystem.GameState.MiniGameManager, "OnPlayerPossessed", self, NewController);
|
||
end
|
||
end
|
||
|
||
--- 第一次进入游戏执行函数
|
||
function UGCPlayerPawn:FirstBeginPlay() end
|
||
|
||
---@param InDeadTimes int32
|
||
function UGCPlayerPawn:RespawnBeginPlay(InDeadTimes)
|
||
-- 应用一下
|
||
if IsServer then
|
||
--self:UseBenefit(true);
|
||
else
|
||
UnrealNetwork.CallUnrealRPC(LocalPlayerController, self, "RespawnBeginPlay", InDeadTimes);
|
||
end
|
||
end
|
||
|
||
UGCPlayerPawn.BaseTargetOffset = {X=0,Y=0,Z=178.000000};
|
||
UGCPlayerPawn.BaseTargetArmLength = 220;
|
||
|
||
function UGCPlayerPawn:InitPawn()
|
||
if UGCGameSystem.GameState and GameState.MiniGameManager then
|
||
table.func(GameState.MiniGameManager, "OnPawnInit", self);
|
||
end
|
||
if IsServer then
|
||
self:EnablePickUp(DefaultSettings.EnableAutoPickUp);
|
||
self:UseBenefit(true);
|
||
---@type PlayerKDAItem1
|
||
self:InitBenefit();
|
||
local KDA = GameState:GetPlayerKDA(self.PlayerKey)
|
||
if (KDA.Dead) <= DefaultSettings.GiveWeaponTimes then self:AddInitItems(); end
|
||
self:TestPawn();
|
||
else
|
||
self:SetCurrentCamera(self.Camera, self.CustomSpringArm);
|
||
end
|
||
|
||
-- 获取玩家属性变化
|
||
local BodySize = UGCGameSystem.GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.BodySize);
|
||
if BodySize ~= nil then
|
||
if IsServer then
|
||
self.CachedBodySize = BodySize;
|
||
self:ChangeBody(BodySize);
|
||
else
|
||
self:ClientChangeBody(BodySize);
|
||
end
|
||
else
|
||
if IsServer then self.CachedBodySize = 1; end
|
||
end
|
||
end
|
||
|
||
---@return bool 是否开启掉落盒子
|
||
function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater) return DefaultSettings.EnableDeadBox; end
|
||
|
||
function UGCPlayerPawn:OnClientAlready()
|
||
--if self:GetPickupManagerComponent() then
|
||
-- -- 这个在手机上添加不上去
|
||
-- UGCLogSystem.Log("[UGCPlayerPawn:OnClientAlready] 添加上去")
|
||
-- self:GetPickupManagerComponent().OnPickUpTarger:Add(self.OnPickUpItem, self);
|
||
--end
|
||
end
|
||
|
||
----------------------------------------- Camera -----------------------------------------
|
||
---获取当前正在使用的 Camera
|
||
---@return UCameraComponent
|
||
function UGCPlayerPawn:GetCamera() return self.CurrentCamera; end
|
||
|
||
---@return USpringArmComponent
|
||
function UGCPlayerPawn:GetCurrentSpringArm()
|
||
if self.CurrentSpringArm == nil then return self.CustomSpringArm; end
|
||
return self.CurrentSpringArm;
|
||
end
|
||
|
||
---@param InCamera UCameraComponent
|
||
---@param InArm USpringArmComponent
|
||
function UGCPlayerPawn:SetCurrentCamera(InCamera, InArm)
|
||
self.CurrentCamera = InCamera;
|
||
self.CurrentSpringArm = InArm;
|
||
end
|
||
|
||
function UGCPlayerPawn:OnOpenScope()
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnOpenScope] 开镜!")
|
||
end
|
||
|
||
function UGCPlayerPawn:OnOutScope(bIsBegin)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnOutScope] 关镜 bIsBegin = %s", tostring(bIsBegin))
|
||
end
|
||
|
||
----------------------------------------- 玩家伤害处理 -----------------------------------------
|
||
|
||
function UGCPlayerPawn:GetDamageParam()
|
||
return GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.Damage);
|
||
end
|
||
|
||
function UGCPlayerPawn:PreInstigatedDamage(DamageAmount, DamageEvent, DamageCauser, Victim)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:PreInstigatedDamage] DamageAmount = %f", DamageAmount);
|
||
return DamageAmount;
|
||
end
|
||
|
||
--- 玩家受到伤害修改事件
|
||
---@field UGC_TakeDamageOverrideEvent fun(Damage:float,DamageType:EDamageType,EventInstigator:AController,DamageCauser:AActor,Hit:FHitResult):float
|
||
---@param Damage float
|
||
---@param DamageType EDamageType
|
||
---@param EventInstigator UGCPlayerController_C
|
||
---@param DamageCauser AActor
|
||
---@param Hit FHitResult
|
||
function UGCPlayerPawn:UGC_TakeDamageOverrideEvent(Damage, DamageType, EventInstigator, DamageCauser, Hit)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] DamageType = %s", tostring(DamageType));
|
||
if DefaultSettings.CloseDropDamage then
|
||
if DamageType == EDamageType.FallingDamage then return 0; end
|
||
end
|
||
if EventInstigator ~= nil then
|
||
local KillPlayerKey = EventInstigator.PlayerKey;
|
||
local Killer = UGCGameSystem.GetPlayerPawnByPlayerKey(KillPlayerKey);
|
||
--- 如果开启友伤
|
||
if not DefaultSettings.TeamDamage then
|
||
local TeamId = UGCPlayerStateSystem.GetTeamID(KillPlayerKey);
|
||
local SelfTeamId = UGCPlayerStateSystem.GetTeamID(self.PlayerKey)
|
||
if TeamId == SelfTeamId then Damage = 0; end
|
||
end
|
||
|
||
--- 自己造成的伤害
|
||
self.PlayerState.DamagedPlayerList[KillPlayerKey] = UE.GetCurrentTime() + DefaultSettings.AssistContinueTime;
|
||
|
||
-- 伤害处理
|
||
Damage = self:UseOneBenefit(DefaultSettings.EPawnBenefitType.Damage, true) * Damage;
|
||
--local Shield = self:UseOneBenefit(DefaultSettings.EPawnBenefitType.Shield, true);
|
||
--UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Shield = %f", Shield);
|
||
--Damage = DefaultSettings.ShieldFunc(Damage, Shield);
|
||
|
||
local KillerCurrSlot = UGCWeaponManagerSystem.GetCurrentWeaponSlot(Killer)
|
||
if ESurviveWeaponPropSlot.SWPS_HandProp == KillerCurrSlot then
|
||
UGCLogSystem.UGCLog("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] 使用拳头攻击");
|
||
else
|
||
---@type ASTExtraWeapon
|
||
local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(Killer);
|
||
if Weapon then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Weapon = %s", UE.GetName(Weapon));
|
||
end
|
||
end
|
||
else
|
||
--- 查看是否是毒圈上海
|
||
if DamageType == EDamageType.PoisonDamage then
|
||
Damage = self:ApplyPoisonDamage(Damage)
|
||
Damage = Damage == nil and 0 or Damage;
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Damage = %s", tostring(Damage));
|
||
end
|
||
end
|
||
if Damage > 0 then
|
||
UGCEventSystem.SendEvent(EventTypes.PlayerInjury, self.PlayerKey, UE.IsValid(EventInstigator) and EventInstigator.PlayerKey or nil, Damage)
|
||
end
|
||
--UnrealNetwork.CallUnrealRPC(self.Controller, self, "ClientReceiveDamage", Damage, DamageType, EventInstigator, DamageCauser);
|
||
--- 判断是不是平底锅的伤害,输出一下
|
||
return Damage;
|
||
end
|
||
|
||
---@param Damage float
|
||
---@param DamageType EDamageType
|
||
---@param Causer AActor
|
||
function UGCPlayerPawn:ClientReceiveDamage(Damage, DamageType, EventInstigator, Causer)
|
||
end
|
||
|
||
--- 应用毒圈伤害
|
||
function UGCPlayerPawn:ApplyPoisonDamage(InDamage)
|
||
-- 检查体型是否已经很大
|
||
return InDamage;
|
||
end
|
||
|
||
--- 服务器/客户端收到伤害数据
|
||
---@param Damage float
|
||
---@param DamageType UDamageType
|
||
---@param InstigatedBy UGCPlayerController_C
|
||
---@param DamageCauser AActor
|
||
function UGCPlayerPawn:BPReceiveDamage(Damage, DamageType, InstigatedBy, DamageCauser)
|
||
if GameState.MiniGameManager then
|
||
table.func(GameState.MiniGameManager, "BPReceiveDamage", self, Damage, DamageType, EventInstigator, Causer);
|
||
end
|
||
if Damage > 0 then
|
||
UGCEventSystem.SendEvent(EventTypes.PlayerInjury, self.PlayerKey, UE.IsValid(EventInstigator) and EventInstigator.PlayerKey or nil, Damage)
|
||
end
|
||
if Damage > 0 then self.bHadTokenDamage = true; end
|
||
if DamageType == EDamageType.PoisonDamage then
|
||
UGCEventSystem.SendEvent(EventTypes.PlayerPoisonDamage, self.PlayerKey, Damage);
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:DamageTick(InTime)
|
||
if IsServer then
|
||
local Time = UE.GetCurrentTime()
|
||
for i, v in pairs(self.PlayerState.DamagedPlayerList) do
|
||
if v >= Time then self.PlayerState.DamagedPlayerList[i] = nil end
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 当击杀其他玩家的时候
|
||
---@param InVictimPlayerKey PlayerKey
|
||
function UGCPlayerPawn:OnKillOther(InVictimPlayerKey)
|
||
-- 让玩家体型增大
|
||
if self:IsAlive() then
|
||
--self:AddBuff("ApplyKillChange", nil, 1, nil, nil);
|
||
local Attr = GameState:GetPlayerAttribute(self.PlayerKey);
|
||
self:UseBenefit(true);
|
||
UGCPawnAttrSystem.SetHealth(self, UGCPawnAttrSystem.GetHealth(self) + 20);
|
||
else
|
||
end
|
||
end
|
||
|
||
---@return bool 是否受到过伤害
|
||
function UGCPlayerPawn:HadTokenDamage() return self.bHadTokenDamage; end
|
||
|
||
--- 武器攻击到什么东西的时候
|
||
---@param ShootWeapon ASTExtraShootWeapon
|
||
---@param Bullet ASTExtraShootWeaponBulletBase
|
||
---@param HitInfo FHitResult
|
||
function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo)
|
||
--local HitActor = HitInfo.Actor:Get()
|
||
local HitLoc = VectorHelper.ToString(HitInfo.Location)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] HitLoc = %s", HitLoc);
|
||
if IsServer then
|
||
local ItemId = ShootWeapon:GetWeaponItemID();
|
||
if ItemId == 107001 then
|
||
local DamageChannel = ECollisionChannel.ECC_Visibility;
|
||
local bTakeDamage = UGCGameSystem.ApplyRadialDamage(75, 10, HitInfo.Location, 10, 200, 4,
|
||
EDamageType.RadialDamage, {}, ShootWeapon,
|
||
UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey),
|
||
DamageChannel, 107001
|
||
);
|
||
if bTakeDamage then
|
||
-- 造成了伤害
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] 造成了伤害")
|
||
else
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] 没有造成伤害")
|
||
end
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "Client_OnShootEmitter", VectorHelper.ToLuaTable(HitInfo.Location));
|
||
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)
|
||
GameplayStatics.SpawnEmitterAtLocation(self, TargetObject, Location, VectorHelper.RotZero(), VectorHelper.ScaleOne(), false);
|
||
end)
|
||
end
|
||
|
||
----------------------------------------- Benefit -----------------------------------------
|
||
|
||
function UGCPlayerPawn:InitBenefit()
|
||
if DefaultSettings.UseDurableBenefit then
|
||
self.BenefitTable = TableHelper.DeepCopyTable(self.PlayerState.BenefitTable)
|
||
self:CheckBenefits();
|
||
end
|
||
if table.isEmpty(self.BenefitTable) then
|
||
for i, v in pairs(DefaultSettings.EPawnBenefitType) do self:ResetBenefitType(v); end
|
||
end
|
||
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:InitBenefit] self.BenefitTable ="), self.BenefitTable)
|
||
DOREPONCE(self, "BenefitTable")
|
||
end
|
||
|
||
function UGCPlayerPawn:CheckBenefits()
|
||
if self.BenefitTable == nil then self.BenefitTable = {}; end
|
||
for i = 1, table.getCount(DefaultSettings.EPawnBenefitType) do
|
||
if self.BenefitTable[i] == nil then self:ResetBenefitType(i); end
|
||
end
|
||
end
|
||
|
||
--- 重置玩家属性特征
|
||
function UGCPlayerPawn:ResetBenefitType(v)
|
||
self.BenefitTable[v] = 0;
|
||
end
|
||
|
||
---@param InType EPawnBenefitType
|
||
---@param InVal float
|
||
function UGCPlayerPawn:AddBenefit(InType, InVal)
|
||
InVal = self:GetBenefit(InType) + InVal
|
||
self:SetBenefit(InType, InVal < 0 and 0 or InVal);
|
||
end
|
||
|
||
---@param InVal float
|
||
function UGCPlayerPawn:SetMaxHealth(InVal)
|
||
--UGCLogSystem.Log("[UGCPlayerPawn:SetMaxHealth] 执行 InVal = %f", InVal)
|
||
local CurrMax = UGCPawnAttrSystem.GetHealthMax(self);
|
||
local NextMax = InVal * 100;
|
||
if CurrMax == NextMax then return; end
|
||
local Health = UGCPawnAttrSystem.GetHealth(self)
|
||
local NextHealth = NextMax / CurrMax * Health;
|
||
UGCPawnAttrSystem.SetHealthMax(self, NextMax);
|
||
UGCPawnAttrSystem.SetHealth(self, NextHealth);
|
||
end
|
||
|
||
---@param InVal float
|
||
function UGCPlayerPawn:AddHealthMax(InVal)
|
||
self:SetMaxHealth(UGCPawnAttrSystem.GetHealthMax(self) + InVal);
|
||
end
|
||
|
||
---@param InVal float 增长的百分比
|
||
---@param InLimit float 限制的百分比
|
||
function UGCPlayerPawn:AddLimitHealth(InVal, InLimit)
|
||
local HealthMax = UGCPawnAttrSystem.GetHealthMax(self);
|
||
local Health = UGCPawnAttrSystem.GetHealth(self);
|
||
local Rate = Health / HealthMax;
|
||
local UseSuccess = false;
|
||
if Rate < InLimit then
|
||
UGCPawnAttrSystem.SetHealth(self, math.min(InLimit * HealthMax))
|
||
UseSuccess = true;
|
||
end
|
||
return UseSuccess;
|
||
end
|
||
|
||
--- 应用 Benefit
|
||
---@param InType EPawnBenefitType
|
||
---@param InVal float
|
||
function UGCPlayerPawn:SetBenefit(InType, InVal)
|
||
if InVal == nil or InVal == 0 then return; end
|
||
self.BenefitTable[InType] = InVal == nil and 0 or InVal;
|
||
self:UseBenefit(true);
|
||
DOREPONCE(self, "BenefitTable");
|
||
end
|
||
|
||
---@param InType EPawnBenefitType
|
||
function UGCPlayerPawn:GetBenefit(InType)
|
||
return self.BenefitTable[InType] == nil and 0 or self.BenefitTable[InType];
|
||
end
|
||
|
||
function UGCPlayerPawn:GetTotalBenefit(InType)
|
||
return self:GetBenefit(InType) + GameState:GetPlayerAttribute(self.PlayerKey, InType);
|
||
end
|
||
|
||
---@param IsAddAttr bool 是否也加上 GameState 中的 PlayerAttribute
|
||
---@param InTable table<EPawnBenefitType, float>
|
||
function UGCPlayerPawn:UseBenefit(IsAddAttr, InTable)
|
||
if InTable == nil then
|
||
if table.isEmpty(self.BenefitTable) then self:InitBenefit(); end
|
||
InTable = self.BenefitTable;
|
||
end
|
||
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:UseBenefit] InTable ="), InTable)
|
||
for InType, InVal in pairs(InTable) do self:UseOneBenefit(InType, IsAddAttr); end
|
||
end
|
||
|
||
---@param InType EPawnBenefitType
|
||
---@param IsAddAttr bool
|
||
---@return float 具体改变的值
|
||
function UGCPlayerPawn:UseOneBenefit(InType, IsAddAttr)
|
||
if table.isEmpty(self.BenefitTable) then self:InitBenefit(); end
|
||
local InVal = self.BenefitTable[InType]
|
||
local c = GameState:GetPlayerAttribute(self.PlayerKey, InType);
|
||
if IsAddAttr then InVal = InVal + c end
|
||
if InType == DefaultSettings.EPawnBenefitType.Damage or InType == DefaultSettings.EPawnBenefitType.Shield then
|
||
elseif InType == DefaultSettings.EPawnBenefitType.Speed then
|
||
if InVal > DefaultSettings.MaxBodySize then
|
||
UGCPawnAttrSystem.SetSpeedScale(self, DefaultSettings.MaxBodySize);
|
||
elseif InVal < 1 then
|
||
UGCPawnAttrSystem.SetSpeedScale(self, 1);
|
||
else
|
||
UGCPawnAttrSystem.SetSpeedScale(self, InVal);
|
||
end
|
||
elseif InType == DefaultSettings.EPawnBenefitType.Jump then
|
||
local AddVal = 0;
|
||
if InVal > 1 then AddVal = (InVal - 1) * 178.0; end
|
||
UGCPawnAttrSystem.SetJumpZVelocity(self, 443.0 + AddVal);
|
||
self.CachedGravity = InVal;
|
||
self.STCharacterMovement.GravityScale = self.CachedGravity;
|
||
elseif InType == DefaultSettings.EPawnBenefitType.MaxHealth then
|
||
self:SetMaxHealth(InVal);
|
||
elseif InType == DefaultSettings.EPawnBenefitType.BodySize then
|
||
self:ChangeBody(InVal);
|
||
end
|
||
return InVal;
|
||
end
|
||
|
||
function UGCPlayerPawn:OnRep_BenefitTable()
|
||
if table.isEmpty(self.BenefitTable) then return end
|
||
UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:OnRep_BenefitTable] self.BenefitTable ="), self.BenefitTable)
|
||
UGCEventSystem.SendEvent(EventTypes.PlayerBenefitChange, self.PlayerKey, self.BenefitTable);
|
||
end
|
||
|
||
function UGCPlayerPawn:OnRep_CachedGravity()
|
||
if self.CachedGravity ~= 0 then return; end
|
||
self.STCharacterMovement.GravityScale = self.CachedGravity;
|
||
end
|
||
|
||
---@type bool 是否是满血
|
||
function UGCPlayerPawn:IsFullHealth()
|
||
return UGCPawnAttrSystem.GetHealth(self) == UGCPawnAttrSystem.GetHealthMax(self)
|
||
end
|
||
|
||
UGCPlayerPawn.CachedBodySize = 1;
|
||
|
||
--- 改变体型,会有问题
|
||
function UGCPlayerPawn:ChangeBody(InVal)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ChangeBody] InVal = %s", tostring(InVal))
|
||
if IsServer then
|
||
if InVal > 2.5 then InVal = DefaultSettings.MaxBodySize end
|
||
if self:GetActorScale3D().X == InVal then return; end
|
||
self.CachedBodySize = InVal;
|
||
self:SetActorScale3D(VectorHelper.MakeVector1(self.CachedBodySize));
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:OnRep_CachedBodySize()
|
||
if UGCLogSystem then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnRep_CachedBodySize] CachedBodySize = %s, self.PlayerKey = %d", tostring(self.CachedBodySize), self.PlayerKey);
|
||
end
|
||
if self.CachedBodySize ~= nil then
|
||
self:ClientChangeBody(self.CachedBodySize);
|
||
else
|
||
local BodySize = UGCGameSystem.GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.BodySize);
|
||
if BodySize then
|
||
self.CachedBodySize = BodySize;
|
||
self:ClientChangeBody(BodySize);
|
||
else
|
||
if UGCLogSystem then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnRep_CachedBodySize] BodySize = nil");
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:ClientChangeBody(InVal)
|
||
if UGCLogSystem then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] InVal = %f", InVal)
|
||
end
|
||
if InVal > 2.5 then InVal = DefaultSettings.MaxBodySize end
|
||
self:SetActorScale3D({ X = InVal, Y = InVal, Z = InVal, });
|
||
--UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] self.BaseTargetOffset = %s", tostring(self.BaseTargetOffset))
|
||
self:GetCurrentSpringArm().TargetOffset = { X = self.BaseTargetOffset.X * InVal, Y = self.BaseTargetOffset.Y * InVal, Z = self.BaseTargetOffset.Z * InVal};
|
||
self:GetCurrentSpringArm().TargetArmLength = self.BaseTargetArmLength * InVal;
|
||
|
||
--
|
||
local OldSize = self:GetActorScale3D().X;
|
||
if OldSize < InVal and OldSize > 1 then
|
||
--UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] ")
|
||
if OldSize > 2 then
|
||
UGCWidgetManagerSystem.ShowTipsUI(string.format('%s体型增至%0.1f!', GameState.PlayerDatas.AccountInfo[self.PlayerKey].PlayerName, InVal));
|
||
if LocalPlayerKey == self.PlayerKey then
|
||
-- 说明是自己
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] 开始变形");
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 添加能量
|
||
function UGCPlayerPawn:AddEnergy(InVal) self:SetEnergy(self:GetEnergyCurrent() + InVal); end
|
||
--- 设置能量
|
||
function UGCPlayerPawn:SetEnergy(InVal) self:SetCharacterEnergy(InVal); end
|
||
--- 清空能量
|
||
function UGCPlayerPawn:ClearEnergy() self:SetCharacterEnergy(0.); 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, ...);
|
||
end
|
||
|
||
--- 清空所有物品
|
||
function UGCPlayerPawn:ClearItems()
|
||
ItemTool.ClearAllWeaponsAndProp(self, true, true, true, true, true);
|
||
end
|
||
|
||
function UGCPlayerPawn:Test_RemoveAttachment()
|
||
ItemTool.ClearCurrentWeapon(self, true);
|
||
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
|
||
|
||
---@return EFillBulletType
|
||
function UGCPlayerPawn:GetInfiniteType()
|
||
local Type = self.PlayerState:GetInfiniteType();
|
||
UGCLogSystem.Log("[UGCPlayerPawn:GetInfiniteType] Type = %s", tostring(Type))
|
||
return Type
|
||
end
|
||
|
||
---@param InType EFillBulletType
|
||
function UGCPlayerPawn:SetInfiniteType(InType)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:SetInfiniteType] 执行 InType = %s", tostring(InType))
|
||
self.PlayerState:SetInfiniteType(InType);
|
||
end
|
||
|
||
--- 换弹
|
||
function UGCPlayerPawn:WeaponReload()
|
||
ItemTool.Reload(self, false)
|
||
end
|
||
|
||
function UGCPlayerPawn:SetPlayerPickUpEnable(IsEnable)
|
||
DefaultSettings.EnableAutoPickUp = IsEnable;
|
||
self:EnablePickUp(IsEnable);
|
||
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
|
||
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, slot);
|
||
UGCEventSystem.SendEvent(EventTypes.PlayerChangeWeapon, self, slot, Weapon);
|
||
end
|
||
|
||
function UGCPlayerPawn:OnWeaponEquipAttachment(AttachmentID)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnWeaponEquipAttachment] Attachment ID = %d", AttachmentID);
|
||
end
|
||
|
||
--- 当玩家拾取之后调用,这个是无论是怎么添加都会走,但是客户端只会走添加的
|
||
function UGCPlayerPawn:UGC_PlayerPickUpEvent()
|
||
UGCLogSystem.Log("[UGCPlayerPawn:UGC_PlayerPickUpEvent] 执行")
|
||
|
||
local Comp = UGCBackPackSystem.GetBackpackComponent(self)
|
||
|
||
for i, v in pairs(ShootWeaponEnums) do
|
||
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, v);
|
||
if Weapon then
|
||
--local ItemId = Weapon:GetWeaponItemID()
|
||
-- 查看之前是否有过
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:OnPostEquipOrUnEquipWeapon(Weapon, bEquip)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnPostEquipOrUnEquipWeapon] 执行")
|
||
if bEquip then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnPostEquipOrUnEquipWeapon] 玩家装备上 %s", UE.GetName(Weapon));
|
||
end
|
||
end
|
||
|
||
--- 玩家
|
||
---@overload fun() OnUnEquipWeapon
|
||
function UGCPlayerPawn:OnUnEquipWeapon()
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnUnEquipWeapon] 玩家收起武器");
|
||
--GameState:ClearWrappers();
|
||
local Weapon = UGCWeaponManagerSystem.GetLastUsedWeapon(self)
|
||
if Weapon then
|
||
|
||
end
|
||
end
|
||
|
||
--- 当玩家获取武器之后执行
|
||
---@param Weapon ASTExtraWeapon
|
||
function UGCPlayerPawn:OnPostGetWeapon(Weapon)
|
||
if UGCGameSystem.GameState then
|
||
table.func(UGCGameSystem.GameState.MiniGameManager, "OnPlayerGetWeapon", self, Weapon)
|
||
end
|
||
end
|
||
|
||
---@param InHitActor AActor
|
||
---@param ImpactPosDistanceToWeapon float
|
||
---@param Player APawn
|
||
function UGCPlayerPawn:OnBulletHitSomething(InHitActor, ImpactPosDistanceToWeapon, Player)
|
||
if InHitActor then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnBulletHitSomething] 执行:击中了 %s", UE.GetName(InHitActor));
|
||
else
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnBulletHitSomething] 执行:击中了空的");
|
||
end
|
||
end
|
||
|
||
---@param DamageDetail FShootWeaponDamageEvent
|
||
---@param HitData FBulletHitInfoUploadData
|
||
---@param LocalHitData FLocalShootHitData
|
||
function UGCPlayerPawn:OnWeaponShootHitSomething(DamageDetail, HitData, LocalHitData)
|
||
-- 执行
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnWeaponShootHitSomething] 击中了 %s", VectorHelper.ToString(HitData.VictimLocation))
|
||
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
|
||
end
|
||
|
||
----------------------------------------- 玩家拾取 -----------------------------------------
|
||
|
||
---@type BP_CustomItemBase_C
|
||
UGCPlayerPawn.InPickSceneObj_Weapon = nil;
|
||
UGCPlayerPawn.IsPickUping = false;
|
||
|
||
--- 这个的作用是通过绑定 PickUpTarger 用的
|
||
function UGCPlayerPawn:SetInPickUp(InPick, InSceneObj)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:SetInPickUp] InPick = %s", tostring(InPick))
|
||
self.InPickSceneObj_Weapon = InPick and InSceneObj or nil;
|
||
self.IsPickUping = InPick;
|
||
end
|
||
|
||
--- 开始拾取的回调
|
||
---@param Target APickUpWrapperActor
|
||
function UGCPlayerPawn:OnPickUpItem(Target)
|
||
if IsServer then
|
||
---@type BP_WeaponItem_C
|
||
local Owner = Target:GetOwner()
|
||
if Owner ~= nil then
|
||
self:SetInPickUp(true, Owner);
|
||
if Target ~= nil then
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnPickUpItem] Owner = %s, Wrapper Id = %d", UE.GetName(Owner), Target.DefineID.TypeSpecificID);
|
||
end
|
||
Owner:OnAutoItemUsed(self, Target == nil and nil or Target.DefineID.TypeSpecificID);
|
||
end
|
||
else
|
||
UGCLogSystem.Log("[UGCPlayerPawn:OnPickUpItem] Target = %s", UE.GetName(Target));
|
||
-- 发送到服务器
|
||
UnrealNetwork.CallUnrealRPC(self:GetPlayerControllerSafety(), self, "OnPickUpItem", Target);
|
||
end
|
||
end
|
||
|
||
-- 这是拾取物品之后调用的了,因此需要清空地面
|
||
function UGCPlayerPawn:AfterPlayerPickUp(SelfRef)
|
||
UGCLogSystem.Log("[UGCPlayerPawn:AfterPlayerPickUp] 拾取之后执行")
|
||
if IsServer then
|
||
else
|
||
UnrealNetwork.CallUnrealRPC(self:GetPlayerControllerSafety(), self, "AfterPlayerPickUp");
|
||
end
|
||
end
|
||
|
||
-------------------------------- 玩家技能 --------------------------------
|
||
|
||
--- 添加 Buff
|
||
---@param InIndex EBuffType
|
||
---@param InPlayerKey PlayerKey
|
||
function UGCPlayerPawn:ApplyBuff(InIndex, InPlayerKey)
|
||
if IsServer then
|
||
if type(InIndex) == 'string' then
|
||
self:AddBuff(InIndex, nil, 1, nil, nil);
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ApplyBuff] 执行 InIndex = %s", InIndex)
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "ApplyBuff", BuffTable.EBuffType[InIndex], self.PlayerKey);
|
||
elseif type(InIndex) == 'number' then
|
||
self:ApplyBuff(BuffTable.GetBuffName(InIndex));
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ApplyBuff] 执行 InIndex = %d", InIndex)
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "ApplyBuff", InIndex, self.PlayerKey);
|
||
end
|
||
else
|
||
if UGCPlayerStateSystem.GetTeamID(InPlayerKey) == LocalTeamId then
|
||
local Name = UE.GetAccountInfo(InPlayerKey).PlayerName;
|
||
local BuffName = BuffTable.GetBuffName(InIndex);
|
||
UITool.ShowTips("%s 获取了 Buff: %s", Name, BuffName);
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 受到炸弹伤害,击退玩家
|
||
function UGCPlayerPawn:BombSkill() end
|
||
function UGCPlayerPawn:EnableInvincible(Enable) self:SetInvincible(Enable) end
|
||
function UGCPlayerPawn:GetEnableInvincible() return self.bInvincible; end
|
||
function UGCPlayerPawn:AddDamageScale(InVal)
|
||
self.DamageScaleValue = self.DamageScaleValue + InVal;
|
||
end
|
||
|
||
--- 玩家眩晕
|
||
---@param IsOpen bool 是否开启
|
||
function UGCPlayerPawn:Stun(IsOpen)
|
||
self:UseSkill(SkillTable.ESkillType.Stun)
|
||
end
|
||
|
||
function UGCPlayerPawn:UseSkill(InSkillId)
|
||
local SkillMgr = self:GetSkillManagerComponent()
|
||
SkillMgr:TriggerEvent(SkillTable.SkillInfo[InSkillId].SkillId, UTSkillEventType.SET_KEY_DOWN)
|
||
end
|
||
|
||
function UGCPlayerPawn:StopSkill(InSkillId)
|
||
--local SkillMgr = self:GetSkillManagerComponent()
|
||
--SkillMgr.StopSkillAll()
|
||
end
|
||
|
||
--- 玩家被击退
|
||
function UGCPlayerPawn:Repulse(InNum)
|
||
--- LaunchVelocity:FVector,bXYOverride:bool,bZOverride:bool
|
||
local Vec = VectorHelper.MulNumber(self:GetActorForwardVector(), InNum)
|
||
--VectorHelper.Add(Vec, VectorHelper.MakeVector(0, 0, 200));
|
||
self.CharacterMovement.MovementMode = EMovementMode.MOVE_Falling;
|
||
self.CharacterMovement.Velocity = VectorHelper.MakeVector(self.CharacterMovement.Velocity.X, self.CharacterMovement.Velocity.Y, 2000);
|
||
self:Jump();
|
||
self:LaunchCharacter(Vec, true, true);
|
||
end
|
||
|
||
---
|
||
function UGCPlayerPawn:PlayerLaunch()
|
||
local SkillMgr = self:GetSkillManagerComponent()
|
||
SkillMgr:TriggerEvent(121, UTSkillEventType.SET_KEY_DOWN)
|
||
end
|
||
|
||
function UGCPlayerPawn:SetState(InState)
|
||
--self:UGC_LeavePawnStateEvent()
|
||
UGCPawnSystem.EnterPawnState(self, EPawnState.Stun);
|
||
end
|
||
|
||
function UGCPlayerPawn:TransShape(InKey)
|
||
if InKey == nil then
|
||
self.ShapeTransformation:TransformBackToHuman();
|
||
else
|
||
UGCLogSystem.Log("[UGCPlayerPawn:TransShape] InKey = %s", tostring(InKey))
|
||
self.ShapeTransformation:TransformToRandomShape();
|
||
end
|
||
end
|
||
|
||
-------------------------------- 测试 --------------------------------
|
||
|
||
function UGCPlayerPawn:TestPawn()
|
||
self:TransShape();
|
||
end
|
||
|
||
function UGCPlayerPawn:ClearAllAttachments()
|
||
UGCLogSystem.Log("[UGCPlayerPawn:ClearAllAttachments] 执行")
|
||
local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self)
|
||
if Weapon then
|
||
local PartList = Weapon:GetAvailableWeaponAttachmentSocketTypeList();
|
||
local Parts = UE.ToTable(PartList);
|
||
table.printTable(Parts);
|
||
end
|
||
end
|
||
|
||
function UGCPlayerPawn:Test_AddRangeParts()
|
||
ItemTool.AddRangeItems(self, 204001, 204100);
|
||
|
||
-- 获取当前武器
|
||
local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self);
|
||
local DefineID = ItemTool.GetDefineIDBySocketType(Weapon, ItemTool.GetWeaponAttachmentSocketType(EWeaponPartType.Magazine));
|
||
UGCLogSystem.Log("[UGCPlayerPawn:Test_AddRangeParts] DefineID = %d", DefineID.TypeSpecificID);
|
||
end
|
||
|
||
return UGCPlayerPawn; |