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
|