using BaseGames.Core.Events;
using UnityEngine;
namespace BaseGames.Combat
{
///
/// 致命陷阱(地刺、深渊等)——触碰即造成伤害、可无视无敌帧的固定危险区域:
///
/// ① 玩家 HurtBox 触碰时,通过 HurtBox.ReceiveDamage() 造成一次伤害
/// 并携带 IgnoreIFrame 标记(无视翻滚/受击无敌帧,保证陷阱的绝对威胁性)。
/// ② 若伤害导致玩家死亡 → PlayerController.TakeDamage 已 Raise EVT_PlayerDied,
/// 走完整死亡流程(死亡动画 → 重载场景)。
/// ③ 若玩家存活 → 本组件 Raise EVT_PlayerDied,强制返回最近检查点,
/// 同样触发 DeathRespawnService(无死亡演出,只是重新加载)。
///
/// 可下劈(Pogo):
/// - 将 _canPogo = true,并在地刺顶部添加子 GameObject:
/// · 挂 HurtBox 组件(EnemyHurtBox 层)
/// · 父链上无 IDamageable → ReceiveDamage 无副作用(HP 不扣除)
/// · 玩家下劈 HitBox 命中该 HurtBox → HitBox.OnHitConfirmed →
/// WeaponHitBoxInstance.OnDownHitConfirmed → DownAttackState.OnDownHitConfirmed
/// → Move.Jump() 完成弹跳,无需额外代码。
/// - _canPogo = false 则不添加顶部 HurtBox,下劈时玩家仍受地刺伤害。
///
[RequireComponent(typeof(Collider2D))]
public class LethalTrap : MonoBehaviour
{
[Header("伤害")]
[Tooltip("每次触碰造成的伤害量(建议设为 1,确保任意陷阱触碰即扟一格血量)")]
[SerializeField] private int _damage = 1;
[Header("检测")]
[Tooltip("勾选 PlayerHurtBox 层")]
[SerializeField] private LayerMask _playerLayers;
[Header("事件")]
[Tooltip("EVT_PlayerDied — 触发后由 DeathRespawnService 接管回到检查点")]
[SerializeField] private VoidEventChannelSO _onPlayerDied;
[Header("设计")]
[Tooltip("true = 顶部有 HurtBox 子节点可下劈弹跳(需手动添加 Pogo Surface 子节点)")]
[SerializeField] private bool _canPogo = true;
private bool _triggered;
private void Awake()
{
var col = GetComponent();
if (!col.isTrigger)
{
col.isTrigger = true;
Debug.LogWarning($"[LethalTrap] {name}: Collider2D.isTrigger 已自动设为 true。", this);
}
}
private void OnEnable() => _triggered = false;
private void OnTriggerEnter2D(Collider2D other)
{
if (_triggered) return;
if ((_playerLayers.value & (1 << other.gameObject.layer)) == 0) return;
_triggered = true;
// ── 1. 通过 HurtBox 流水线造成伤害(含防御计算,携带 IgnoreIFrame)────────
bool playerDiedFromDamage = false;
if (_damage > 0)
{
var hurtBox = other.GetComponent();
if (hurtBox != null)
{
var info = new DamageInfo.Builder()
.SetRaw(_damage)
.SetFlags(DamageFlags.IgnoreIFrame) // 无视无敌帧(翻滚/受击)
.SetSourceId("lethal_trap")
.Build();
hurtBox.ReceiveDamage(info);
// 检测伤害后玩家存活状态:
// 若已死亡,PlayerController.TakeDamage 已在同帧内 Raise EVT_PlayerDied;
// 若存活,需由本组件 Raise 使其回到检查点。
var damageable = other.transform.root.GetComponentInParent();
playerDiedFromDamage = damageable != null && !damageable.IsAlive;
}
}
// ── 2. 若玩家存活(或无 HurtBox / damage=0),强制触发检查点回溯 ───────────
if (!playerDiedFromDamage)
_onPlayerDied?.Raise();
}
#if UNITY_EDITOR
[UnityEngine.ContextMenu("打印 Pogo 提示")]
private void PrintPogoInfo()
{
Debug.Log(
_canPogo
? $"[LethalTrap] {name}: _canPogo=true。请在顶部添加子 GO + HurtBox(EnemyHurtBox 层) + Collider2D(isTrigger=true),父链上无 IDamageable。"
: $"[LethalTrap] {name}: _canPogo=false,无下劈弹跳。",
this);
}
#endif
}
}