using System;
using System.Collections.Generic;
using Lean.Pool;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class TimeSubmodule : AttackAreaSubmoduleBase
{
public float lifeTime;
public float delayTime;
public float enablingTimer;
public float remainingEnableTime;
public float remainingLifeTime;
private bool hasInvokedEnableAction;
public Action enableAction;
public Action timeOutAction;
///
/// enable 阶段开始前允许反应的提前量(秒),默认 0 表示无提前 grace window。
///
public float reactionGraceBefore;
public TimeSubmodule(AttackAreaBase attackArea, float lifeTime, Action timeOutAction = null) : base(attackArea)
{
this.isEnabling = true;
this.lifeTime = lifeTime;
this.remainingLifeTime = lifeTime;
this.enablingTimer = 0;
if (attackArea is NormalArea)
{
this.remainingEnableTime = 0.04f;
}
else if (attackArea is Projectile)
{
this.remainingEnableTime = lifeTime;
}
else
{
this.remainingEnableTime = lifeTime;
}
this.timeOutAction = timeOutAction ?? (() =>
{
if (attackArea is Projectile projectile)
{
projectile.Explode(projectile.transform.position);
}
else
{
LeanPool.Despawn(attackArea.topParent.gameObject);
}
});
this.reactionGraceBefore = 0f;
}
public TimeSubmodule(AttackAreaBase attackArea, float lifeTime, float delayTime, float enableTime,
Action enableAction, Action timeOutAction, float graceBefore = 0f) : base(attackArea)
{
this.isEnabling = true;
this.lifeTime = lifeTime;
this.delayTime = delayTime;
this.attackArea.isEnabling = delayTime <= 0;
this.timeOutAction = timeOutAction ?? (() =>
{
if (attackArea is Projectile projectile)
{
projectile.Explode(projectile.transform.position);
}
else
{
LeanPool.Despawn(attackArea.topParent.gameObject);
}
});
if (this.attackArea.isEnabling)
{
enableAction?.Invoke();
hasInvokedEnableAction = true;
}
this.remainingLifeTime = lifeTime;
this.enablingTimer = 0;
this.remainingEnableTime = enableTime;
this.enableAction = enableAction;
this.reactionGraceBefore = graceBefore;
}
///
/// 判断当前时刻是否处于反应窗口内(包含 grace 区间和 enable 阶段本身)。
/// before grace: delay 阶段末尾的 reactionGraceBefore 秒内。
/// after grace: enable 结束后的 reactionGraceAfter 秒内。
///
public bool IsReactionActive()
{
// 在 enable 阶段本身,反应始终可用
if (attackArea.isEnabling)
{
return true;
}
// before grace: delay 尚未结束,但已进入 grace 窗口
if (delayTime > 0f && reactionGraceBefore > 0f && delayTime <= reactionGraceBefore)
{
return true;
}
// 过渡帧桥接:delay 刚结束(delayTime 被扣至 <=0),但 enable 阶段尚未在下一帧
// 的 timeSm.Update() 中激活。此帧 isEnabling 为 false 且 delayTime 不再 >0,
// 若不补此条件会导致 1 帧的反应窗口真空,玩家的完美闪避/格挡可能被跳过。
if (reactionGraceBefore > 0f && delayTime <= 0f && !hasInvokedEnableAction)
{
return true;
}
return false;
}
}
public partial class TimeSubmodule
{
public void Update()
{
if (!isEnabling) return;
if (delayTime > 0)
{
delayTime -= attackArea.creator.selfTimeSm.DeltaTime;
return;
}
if (!hasInvokedEnableAction)
{
attackArea.isEnabling = true;
enableAction?.Invoke();
hasInvokedEnableAction = true;
}
if (remainingLifeTime <= 0)
{
this.isEnabling = false;
timeOutAction?.Invoke();
}
if (remainingEnableTime <= 0)
{
attackArea.isEnabling = false;
}
enablingTimer += attackArea.creator.selfTimeSm.DeltaTime;
remainingLifeTime -= attackArea.creator.selfTimeSm.DeltaTime;
remainingEnableTime -= attackArea.creator.selfTimeSm.DeltaTime;
}
public void ModifyLifeTime(float modifyValue)
{
lifeTime += modifyValue;
remainingLifeTime += modifyValue;
}
}
}