using BaseGames.Combat;
using BaseGames.Core;
using BaseGames.Core.Save;
using MoreMountains.Feedbacks;
using UnityEngine;
namespace BaseGames.World
{
///
/// 假墙(秘密通道)。外观与普通墙相同,可通过攻击/接近揭示并穿越。
/// 揭示后禁用碰撞体(不销毁),状态持久化到 WorldSaveData。
///
[RequireComponent(typeof(Collider2D))]
public class FalseWall : MonoBehaviour, IDamageable, ISaveable
{
public enum RevealCondition { Proximity, AttackOnce, AlwaysOpen }
[Header("识别")]
[SerializeField] private string _wallId;
[Header("揭示条件")]
[SerializeField] private RevealCondition _revealCondition = RevealCondition.AttackOnce;
[SerializeField] private float _proximityRadius = 2.0f;
[Header("组件引用")]
[SerializeField] private Collider2D _wallCollider;
[SerializeField] private SpriteRenderer _renderer;
[SerializeField] private MMF_Player _revealFeedback;
private bool _isRevealed;
// ── IDamageable ───────────────────────────────────────────────────────
public bool IsInvincible => _isRevealed;
public int Defense => 0;
public void TakeDamage(DamageInfo info)
{
if (_isRevealed || _revealCondition != RevealCondition.AttackOnce) return;
Reveal();
}
// ── Unity Lifecycle ───────────────────────────────────────────────────
private void Awake()
{
ServiceLocator.GetOrDefault()?.Register(this);
}
private void OnDestroy()
{
ServiceLocator.GetOrDefault()?.Unregister(this);
}
private void Start()
{
if (_revealCondition == RevealCondition.AlwaysOpen)
{
SetPassThroughImmediate();
_isRevealed = true;
return;
}
}
// ── ISaveable ─────────────────────────────────────────────────────────
public void OnSave(SaveData data)
{
if (_isRevealed && !string.IsNullOrEmpty(_wallId)
&& !data.World.OpenedDoors.Contains(_wallId))
data.World.OpenedDoors.Add(_wallId);
}
public void OnLoad(SaveData data)
{
if (string.IsNullOrEmpty(_wallId)) return;
_isRevealed = data.World.OpenedDoors.Contains(_wallId);
if (_isRevealed) SetPassThroughImmediate();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (_isRevealed || _revealCondition != RevealCondition.Proximity) return;
if (!other.CompareTag("Player")) return;
// Proximity 模式:仅播放 Shimmer 暗示,碰撞仍启用
_revealFeedback?.PlayFeedbacks();
}
// ── Implementation ────────────────────────────────────────────────────
private void Reveal()
{
_isRevealed = true;
_revealFeedback?.PlayFeedbacks();
SetPassThroughImmediate();
}
private void SetPassThroughImmediate()
{
if (_wallCollider != null)
_wallCollider.enabled = false;
// 切换 Sprite 到透明/揭示帧(由子类或动画处理)
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(0.6f, 0.2f, 1f, 0.8f);
var col = GetComponent();
if (col != null)
Gizmos.DrawWireCube(transform.position, col.bounds.size);
if (_revealCondition == RevealCondition.Proximity)
{
Gizmos.color = new Color(0.6f, 0.2f, 1f, 0.2f);
Gizmos.DrawWireSphere(transform.position, _proximityRadius);
}
}
#endif
}
}