UGCProjects/ProjectTemp_T/Script/Blueprint/BUFF/BuffAction/BuffAction_RespiratoryRegurgitation.lua
2025-01-04 23:00:19 +08:00

114 lines
5.4 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local BuffAction_RespiratoryRegurgitation = {
-- 以下参数信息可以通过manager的 GetBuffDefaultParam(BuffPath, ParamName)来获取 --
-- 默认颜色信息,非必要参数
BuffColor = {R = 0.97, G = 0.88, B = 0.1, A = 1.};
BuffIconPath = "默认Icon路径非必要参数";
BuffParticlePath = "默认粒子路径,非必要参数";
BuffDesc = "呼吸回复";
--------------------------------------------------------------------------------
bInitBuff = false;
LastDetectionTime = 0.;
--- Tick 回复频率
DetectionFrequency = 5.;
--- {PlayerKey = uint, BuffTag = string, LastHitTime: float, HitDelayExecution = float, RecoveryPerSecond = float}, ...
PlayerParams = {};
--- PlayerKey = Time:float
PlayerLastHitTime = {}
}
--- 必须包含ApplyBuff函数
---@param BuffTag Any Buff的标签
---@param ValidPawn UGCPlayerPawn*
---@param Args ... Any
---@return ApplySucceed:bool
function BuffAction_RespiratoryRegurgitation:ApplyBuff(BuffTag, ValidPawn, InHitDelayExecution, InRecoveryPerSecond)
-- Tick逻辑
if not self.bInitBuff then
self.LastDetectionTime = KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
self.bInitBuff = true
end
-- Apply逻辑
if InHitDelayExecution < 0 then
return false
end
ValidPawn.OnPostTakeDamage:Add(self.TargetPlayerTakeDamage, self)
table.insert(self.PlayerParams, {PlayerKey = ValidPawn.PlayerKey, BuffTag = BuffTag, HitDelayExecution = InHitDelayExecution, RecoveryPerSecond = InRecoveryPerSecond})
return true
end
--- 可以包含RemoveBuff若包含该函数则玩家应用该Buff时会保存Buff信息缓存作为移除或者获取玩家当前Buff的备份信息
---@param BuffTag Any Buff的标签
---@param ValidPawn UGCPlayerPawn_C
---@param Args ... Any Args顺序必须与ApplyBuff顺序一致
function BuffAction_RespiratoryRegurgitation:RemoveBuff(BuffTag, ValidPawn, InHitDelayExecution, InRecoveryPerSecond)
-- Remove逻辑
ValidPawn.OnPostTakeDamage:Remove(self.TargetPlayerTakeDamage, self)
log_tree("[BuffAction_RespiratoryRegurgitation:RemoveBuff]", self.PlayerParams)
for i = #self.PlayerParams, 1, -1 do
if self.PlayerParams[i].PlayerKey == ValidPawn.PlayerKey and self.PlayerParams[i].BuffTag == BuffTag then
table.remove(self.PlayerParams, i)
-- self.PlayerParams[i] = nil
end
end
log_tree("[BuffAction_RespiratoryRegurgitation:RemoveBuff] RemoveFinish", self.PlayerParams)
end
--- Tick函数 服务器客户端均会调用
function BuffAction_RespiratoryRegurgitation:Tick(DeltaTime)
if self.bInitBuff then
local NowTime = KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
local DetectionTime = self.LastDetectionTime + (1. / self.DetectionFrequency)
--UGCLogSystem.Log("[BuffAction_RespiratoryRegurgitation:Tick] DeltaTime:%f, NowTime:%f, DetectionTime:%f", DeltaTime, NowTime, DetectionTime)
if DetectionTime < NowTime then
--UGCLogSystem.Log("[BuffAction_RespiratoryRegurgitation:Tick] EXE DetectionTime:%f", DetectionTime)
self.LastDetectionTime = DetectionTime
local RemovePlayer = {}
for i, PlayerParam in pairs(self.PlayerParams) do
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerParam.PlayerKey)
if UE.IsValid(TargetPawn) then
if self.PlayerLastHitTime[PlayerParam.PlayerKey] == nil then
self.PlayerLastHitTime[PlayerParam.PlayerKey] = 0.
end
if NowTime - self.PlayerLastHitTime[PlayerParam.PlayerKey] > PlayerParam.HitDelayExecution then
UGCPawnAttrSystem.SetHealth(TargetPawn, UGCPawnAttrSystem.GetHealth(TargetPawn) + PlayerParam.RecoveryPerSecond / self.DetectionFrequency)
end
else
RemovePlayer[#RemovePlayer + 1] = PlayerParam.PlayerKey
end
end
for i, v in pairs(RemovePlayer) do
self:RemovePlayerKey(v)
end
end
end
end
--- 当玩家死亡时会触发该函数作用于以PlayerKey给玩家Buff的BuffAction以防UGC的Pawn不删除机制所引发的Bug
function BuffAction_RespiratoryRegurgitation:PlayerDeathCallBack(PlayerKey)
self:RemovePlayerKey(PlayerKey)
end
function BuffAction_RespiratoryRegurgitation:RemovePlayerKey(PlayerKey)
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
if UE.IsValid(TargetPawn) then
TargetPawn.OnPostTakeDamage:Remove(self.TargetPlayerTakeDamage, self)
end
for i = #self.PlayerParams, 1, -1 do
if self.PlayerParams[i].PlayerKey == PlayerKey then
table.remove(self.PlayerParams, i)
-- self.PlayerParams[i] = nil
end
end
end
--- SelfRef:ASTExtraBaseCharacter,Damage:float,DamageEvent:FDamageEvent,EventInstigator:AController,DamageCauser:AActor)
function BuffAction_RespiratoryRegurgitation:TargetPlayerTakeDamage(SelfRef, Damage, DamageEvent, EventInstigator, DamageCauser)
UGCLogSystem.Log("[BuffAction_RespiratoryRegurgitation_TargetPlayerTakeDamage] OwnerKey:%d , DamagerKey:%d", SelfRef.PlayerKey, EventInstigator.PlayerKey)
local NowTime = KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
self.PlayerLastHitTime[SelfRef.PlayerKey] = NowTime
end
return BuffAction_RespiratoryRegurgitation