490 lines
19 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 = {
-- Attr -------------------------
-- 伤害缩放
Attr_DamageScale = 1;
-- 防御缩放
Attr_DefenseScale = 1;
-- 闪避概率
Attr_Dodge = 0;
--
-- Attr End ---------------------
};
-- Replicated -------------------------------------------------------------------------------------------------------
function UGCPlayerPawn:GetReplicatedProperties()
return
end
-- Replicated End ---------------------------------------------------------------------------------------------------
-- Attr -------------------------------------------------------------------------------------------------------------
function UGCPlayerPawn:SetDamageScale(InDamageScale)
self.Attr_DamageScale = InDamageScale
end
function UGCPlayerPawn:GetDamageScale()
return self.Attr_DamageScale
end
function UGCPlayerPawn:SetDefenseScale(InDefenseScale)
-- 防御值不能小于0
if InDefenseScale <= 0 then return false end
self.Attr_DefenseScale = InDefenseScale
return true
end
function UGCPlayerPawn:GetDefenseScale()
return self.Attr_DefenseScale
end
function UGCPlayerPawn:SetDodge(InDodge)
self.Attr_Dodge = InDodge
return true
end
function UGCPlayerPawn:GetDodge()
return self.Attr_DefenseScale
end
-- Attr End ---------------------------------------------------------------------------------------------------------
-- 关闭盒子掉落
--function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater)
-- return true
--end
function UGCPlayerPawn:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
--- 设置翻墙功能
self.bVaultIsOpen = true
--- 设置滑铲功能
self.IsOpenShovelAbility = false
UGCEventSystem.SendEvent(EventEnum.PlayerBeginPlay, self)
if self:HasAuthority() then
self:AddEvent()
if UE.IsValid(self:GetController()) then
self:ReceivePossessed(self:GetController())
UGCLogSystem.Log("[UGCPlayerPawn_ReceiveBeginPlay] Controller Is Valid")
end
else
end
end
--- 客户端必定执行的BeginPlay
function UGCPlayerPawn:ClientMustBeExeBeginPlay()
if self.DoOnceMustBeExeBeginPlay then return end
self.DoOnceMustBeExeBeginPlay = true
self.ClientUpdatedPlayerKey = false
end
function UGCPlayerPawn:ReceivePossessed(NewController)
self.SuperClass.ReceivePossessed(self, NewController);
UGCLogSystem.Log("[UGCPlayerPawn_ReceivePossessed] PlayerKey:%s", tostring(NewController.PlayerKey))
UGCEventSystem.SendEvent(EventEnum.PlayerPossessed, NewController.PlayerKey)
UGCGameSystem.GameState:SetPlayerIsAlive(NewController.PlayerKey, self)
if UGCSystemLibrary.GetIsPreparationState() then
UGCSystemLibrary.SetPlayerPawnMovable(self, false)
end
---- 设置上条命保存的Buff
--self.OwnedIncrease = NewController:GetOwnedIncrease()
--for IncreaseType, Level in pairs(self.OwnedIncrease) do
-- BuffSystemAPI.PlayerAddBuff(self, GodOfWarConfig.BuffList[IncreaseType][Level])
--end
---- 初始化上条命的进度
--self:AddToGodSchedule(NewController:GetToGodSchedule())
---- 初始化上条命可选择的增益
--self:SetNowCanSelectIncrease(NewController:GetNowCanSelectIncrease())
---- 初始化上条命可选择的增益数
--self:SetCanObtainIncreaseCount(NewController:GetCanObtainIncreaseCount())
--
---- 增加一个增益
--self:AddCanObtainIncreaseCount()
end
function UGCPlayerPawn:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
if not UGCGameSystem.IsServer() then
self:ClientMustBeExeBeginPlay()
self:UpdatePlayerKey()
--local HeadPos = self.Mesh:GetSocketLocation("head")
--UGCLogSystem.Log("[UGCPlayerPawn_ReceiveTick]HeadPos:%s, ActorPos:%s", VectorHelper.ToString(HeadPos), VectorHelper.ToString(self:K2_GetActorLocation()))
end
end
function UGCPlayerPawn:ReceiveEndPlay()
self:RemoveEvent()
self.SuperClass.ReceiveEndPlay(self);
end
function UGCPlayerPawn:AddEvent()
if self:HasAuthority() then
-- 这个回调无法拿到倒地死亡的玩家
-- self.DeadNotifyDelegate:Add(self.PlayerDead, self)
self.DamageNotifyDelegate:Add(self.PlayerInjury, self)
self.OnDeath:Add(self.OnDeathCallBack, self)
else
end
end
function UGCPlayerPawn:RemoveEvent()
if self:HasAuthority() then
-- self.DeadNotifyDelegate:Remove(self.PlayerDead, self)
self.DamageNotifyDelegate:Remove(self.PlayerInjury, self)
self.OnDeath:Remove(self.OnDeathCallBack, self)
if self.CheckBornItemsHandle then
UGCEventSystem.StopTimer(self.CheckBornItemsHandle)
self.CheckBornItemsHandle = nil
end
if self.CheckWeaponAndPartsHandle then
UGCEventSystem.StopTimer(self.CheckWeaponAndPartsHandle)
self.CheckWeaponAndPartsHandle = nil
end
else
end
end
function UGCPlayerPawn:CheckWeaponAndParts()
UGCGameSystem.GameState:CheckWeaponAndParts(self.PlayerKey)
end
function UGCPlayerPawn:CheckBornItems()
UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] PlayerKey:%s", tostring(self.PlayerKey))
UGCLogSystem.LogTree("[UGCPlayerPawn_CheckBornItems]", self.DefaultBackPack)
for i = #self.DefaultBackPack, 1, -1 do
local ItemID = self.DefaultBackPack[i].ItemID
local Count = self.DefaultBackPack[i].Count
local InstCount = UGCBackPackSystem.GetItemCount(self, ItemID)
if InstCount >= Count then
UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] i:%s", tostring(i))
table.remove(self.DefaultBackPack, i)
UGCLogSystem.LogTree("[UGCPlayerPawn_CheckBornItems]", self.DefaultBackPack)
else
UGCBackPackSystem.AddItem(self, ItemID, Count - InstCount)
end
end
if #self.DefaultBackPack == 0 then
UGCEventSystem.StopTimer(self.CheckBornItemsHandle)
self.CheckBornItemsHandle = nil
UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] Succeed PlayerKey:%s", tostring(self.PlayerKey));
end
end
-------------------------------------------------- Delegate --------------------------------------------------
---@param DamageInfo FDamageInfoCollection
---@return VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue uint, uint, int, EDamageType, bool, float, float
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.Pawn then
Distance = VectorHelper.GetDistance(self:K2_GetActorLocation(), CauserController.Pawn: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)
UGCLogSystem.LogTree("[UGCPlayerPawn_PlayerDead] DamageInfo:", UE.ToTable(DamageInfo))
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
--UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
--UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
UGCGameSystem.GameState:SetPlayerIsAlive(VictimKey, nil)
end
---@param DamageInfo FDamageInfoCollection
---@param ReturnValue float
function UGCPlayerPawn:PlayerInjury(DamageInfo)
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
UGCEventSystem.SendEvent(EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
UGCSendRPCSystem.RPCEvent(CauserKey, EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
end
function UGCPlayerPawn:OnDeathCallBack(DeadCharacter,Killer,DamageCauser,KillingHitInfo,KillingHitImpulseDir,KillingHitDamageTypeID,DamageTypeClass,IsHeadShotDamage)
local CauserKey = Killer and Killer.PlayerKey
local WeaponID = -1
local DamageType = EDamageType.UGCCustomDamageType + 1
UGCLogSystem.Log("[UGCPlayerPawn_TestOnDeath] PlayerKey:%s, CauserKey:%s", tostring(self.PlayerKey), tostring(CauserKey))
UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0)
UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0)
UGCGameSystem.GameState:SetPlayerIsAlive(self.PlayerKey, nil)
end
------------------------------------------------ Delegate End ------------------------------------------------
------------------------------------------------ ModifyDamage ------------------------------------------------
---@field UGC_TakeDamageOverrideEvent:fun(Damage:float,DamageType:EDamageType,EventInstigator:AController,DamageCauser:AActor,Hit:FHitResult):float
function UGCPlayerPawn:UGC_TakeDamageOverrideEvent(Damage, DamageType, EventInstigator, DamageCauser, Hit)
-- 判断游戏状态伤害
if GlobalConfigs.GameSetting.JustPlayingEnableDamage and UGCGameSystem.GameState:GetGameStateType() ~= CustomEnum.EGameState.Playing then
return 0
end
-- 判断准备阶段伤害开启
if not GlobalConfigs.GameSetting.ReadyStateEnableDamage and UGCGameSystem.GameState:IsReadyState() then
return 0
end
-- 拷贝临时伤害值
local DamageAmount = Damage
-- 输出修改前的伤害数值
UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] InDamageAmount:%s, DamageType:%s", tostring(DamageAmount), tostring(DamageType))
-- 玩家参数信息对伤害数值的修改
DamageAmount = self:ModifyDamageByPlayerParameters(DamageAmount, EventInstigator)
-- 伤害类型对伤害数值的修改
DamageAmount = self:ModifyDamageByDamageType(DamageAmount, DamageType)
-- 绑定的委托的伤害修改
DamageAmount = self:ModifyDamageByAttachDamageFunc(DamageAmount, DamageType, EventInstigator, DamageCauser, Hit)
UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] ModifyDamageAmount:%s", tostring(DamageAmount))
return DamageAmount
end
--- 玩家信息对伤害数值的修改
function UGCPlayerPawn:ModifyDamageByPlayerParameters(DamageAmount, CauserPC)
if UE.IsValid(CauserPC) then
local CauserPlayerKey = CauserPC.PlayerKey
if CauserPlayerKey then
-- 获取敌方队伍ID
local CauserTeamID = UGCPlayerStateSystem.GetTeamID(CauserPlayerKey)
-- 获取己方队伍ID
local SelfTeamID = UGCPlayerStateSystem.GetTeamID(self.PlayerKey)
-- 获取施加者的玩家Pawn
local CauserPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(CauserPlayerKey)
if CauserPlayerKey == self.PlayerKey and GlobalConfigs.GameSetting.bEnableSelfHarm then
--- 对自己的伤害
DamageAmount = GlobalConfigs.GameSetting.SelfHarmInjuryRatio * DamageAmount
else
--- 他人对自己的伤害
-- 判断友伤
if CauserTeamID == SelfTeamID then
-- 友伤数值修改
DamageAmount = GlobalConfigs.GameSetting.FriendlyInjuryRatio * DamageAmount
end
end
-- 获取攻击者伤害缩放
local DamageScale = CauserPawn and CauserPawn:GetDamageScale() or 1
-- 施加者攻击力对伤害的修改
DamageAmount = DamageAmount / self:GetDefenseScale() * DamageScale
end
-- 防御力对伤害的修改
DamageAmount = DamageAmount / self:GetDefenseScale()
end
return DamageAmount
end
--- 伤害类型对伤害数值的修改
function UGCPlayerPawn:ModifyDamageByDamageType(DamageAmount, DamageType)
-- 掉落伤害
if DamageType == EDamageType.FallingDamage then
DamageAmount = GlobalConfigs.GameSetting.bEnableDropDamage and DamageAmount or 0.
end
-- 设置近战伤害缩放
if DamageType == EDamageType.MeleeDamage then
DamageAmount = DamageAmount * GlobalConfigs.GameSetting.MeleeDamageScale
end
-- 判断忽略的伤害
if table.hasValue(GlobalConfigs.GameSetting.IgnoreDamageType, DamageType) then
DamageAmount = 0.
end
return DamageAmount
end
-- 伤害修改列表
UGCPlayerPawn.DamageModifyFunctions = {}
--- 绑定是伤害修改函数对伤害的修改
function UGCPlayerPawn:ModifyDamageByAttachDamageFunc(DamageAmount, DamageType, EventInstigator, DamageCauser, Hit)
for i, v in pairs(self.DamageModifyFunctions) do
if v.Obj then
DamageAmount = v.Func(v.Obj, self, DamageAmount, DamageType, EventInstigator, DamageCauser, Hit)
else
DamageAmount = v.Func(self, DamageAmount, DamageType, EventInstigator, DamageCauser, Hit)
end
UGCLogSystem.Log("[UGCPlayerPawn_ModifyDamageByAttachDamageFunc] ChangeDamage:%s", tostring(DamageAmount))
end
return DamageAmount
end
--- 添加伤害修改函数
---@param ModifyFunc function 修改伤害的静态函数 fun(Pawn, Damage, DamageType, EventInstigator, DamageCauser, Hit):float
---@param Layer 修改的层级 层级越高越往后对伤害进行修改
function UGCPlayerPawn:AddDamageModifyFunc(ModifyFunc, Obj, Layer)
-- 设置层级默认值
if Layer == nil then Layer = 1 end
-- 插入修改函数
local IsInsert = false
for i, v in pairs(self.DamageModifyFunctions) do
if v.Layer > Layer then
table.insert(self.DamageModifyFunctions, i, {Func = ModifyFunc, Obj = Obj, Layer = Layer})
IsInsert = true
break
end
end
if not IsInsert then
table.insert(self.DamageModifyFunctions, #self.DamageModifyFunctions + 1, {Func = ModifyFunc, Obj = Obj, Layer = Layer})
end
UGCLogSystem.LogTree("[UGCPlayerPawn_AddDamageModifyFunc]", self.DamageModifyFunctions)
end
--- 移除伤害修改函数
function UGCPlayerPawn:RemoveDamageModifyFunc(ModifyFunc, Obj)
for i, v in pairs(self.DamageModifyFunctions) do
if v.Func == ModifyFunc and v.Obj == Obj then
table.remove(self.DamageModifyFunctions, i)
UGCLogSystem.LogTree("[UGCPlayerPawn_RemoveDamageModifyFunc]", self.DamageModifyFunctions)
break
end
end
end
---------------------------------------------- ModifyDamage End ----------------------------------------------
-- UGC Event -------------------------------------------------------------------------------------------------------
-- 这些事件都是官方的回调或者可重写的事件
---@field UGC_PlayerDeadEvent:fun(Killer:AController,DamageType:EDamageType)
---@field UGC_PlayerPickUpEvent:fun()
---@field UGC_LeavePawnStateEvent:fun(PawnState:EPawnState)
---@field UGC_EnterPawnStateEvent:fun(PawnState:EPawnState)
---@field UGC_CloseScopeEvent:fun()
---@field UGC_OpenScopeEvent:fun()
---@field UGC_ReloadEndEvent:fun()
---@field UGC_ReloadStartEvent:fun()
---@field UGC_WeaponSwitchEvent:fun()
---@field UGC_WeaponStopFireEvent:fun()
---@field UGC_WeaponStartFireEvent:fun(isAuto:ESTEWeaponShootType)
---@field UGC_EquipWeaponEvent:fun(Slot:ESurviveWeaponPropSlot)
---@field UGC_ChangeCurrentUsingWeaponEvent:fun(UsingWeaponSlot:ESurviveWeaponPropSlot,LastSlot:ESurviveWeaponPropSlot)
--- 子弹命中
---@field UGC_WeaponBulletHitEvent:fun(ShootWeapon:ASTExtraShootWeapon,Bullet:ASTExtraShootWeaponBulletBase,HitInfo:FHitResult)
function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo)
UGCEventSystem.SendEvent(EventEnum.BulletHitCallBack, self, ShootWeapon, Bullet, HitInfo)
end
---@field UGC_WeaponShootBulletEvent:fun(ShootWeapon:ASTExtraShootWeapon,Bullet:ASTExtraShootWeaponBulletBase)
-- UGC Event End -----------------------------------------------------------------------------------------------------
--- 处理飘字
function UGCPlayerPawn:UGC_GetDamageNumberConfigIndex(Damage, IsHeadShot, InstigatorController, DamageCauser, DamageType)
UGCLogSystem.Log("[UGCPlayerPawn_UGC_GetDamageNumberConfigIndex]")
if GlobalConfigs.GameSetting.ShowDamageNumber and InstigatorController == UGCSystemLibrary.GetLocalPlayerController() then
return 0
else
return -1
end
end
--- 播放粒子
function UGCPlayerPawn:PlayParticle(InParticleType)
ParticleConfig.AddParticleAttachPlayer(self, InParticleType)
end
-----------------------------------------------------------------------------------------------------------------------
--- 客户端玩家Key更新
function UGCPlayerPawn:UpdatePlayerKey()
if self.ClientUpdatedPlayerKey == false then
if self.PlayerKey and self.PlayerKey > 0 then
self.ClientUpdatedPlayerKey = true
self:Stroke()
end
end
end
--- Client
--- 描边
function UGCPlayerPawn:Stroke()
if GlobalConfigs.GameSetting.EnableStroke then
UGCLogSystem.Log("[UGCPlayerPawn_Stroke]PlayerKey:%s", tostring(self.PlayerKey))
UGCEventSystem.SetTimer(self, function()
if UGCGameSystem.GameState:GetPlayerTeamIDByPlayerKey(self.PlayerKey) ~= UGCGameSystem.GameState:GetPlayerTeamIDByPlayerKey(UGCSystemLibrary.GetLocalPlayerKey()) then
if GlobalConfigs.IsHaiDao then
self.Mesh:SetDrawIdeaOutline(true)
for EAvatarSlotTypeNum = 0, EAvatarSlotType.EAvatarSlotType_Max -1 do
UGCLogSystem.Log("[UGCPlayerPawn_Stroke]" .. EAvatarSlotTypeNum)
local MeshComponent = self.CharacterAvatarComp_BP:GetMeshCompBySlot(EAvatarSlotTypeNum)
if MeshComponent ~= nil then
UGCLogSystem.Log("[UGCPlayerPawn_Stroke] Succeed" .. EAvatarSlotTypeNum)
MeshComponent:SetDrawIdeaOutline(true)
end
end
else
-- UGCGameSystem.GameState:RegisterPostProcessMgr(self)
STExtraBlueprintFunctionLibrary.EnablePlayerAvatarOutline(self, true)
UGCLogSystem.Log("[UGCPlayerPawn_Stroke] EnablePlayerAvatarOutline")
end
end
end, 2)
end
end
--function UGCPlayerPawn:GetAvailableServerRPCs()
-- return
--end
return UGCPlayerPawn;