114 lines
5.4 KiB
Lua
114 lines
5.4 KiB
Lua
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 |