using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using BaseGames.Core;
using BaseGames.Core.Events;
using BaseGames.Core.Save;
namespace BaseGames.World.Map
{
///
/// 运行时地图管理器(架构 15_MapShopModule §1.2)。
/// 挂在 Persistent 场景 [GameManagers] 下,通过事件驱动记录已探索/已完整地图的房间。
/// 实现 ISaveable 持久化探索进度。
///
[DefaultExecutionOrder(-700)]
public class MapManager : MonoBehaviour, ISaveable, IMapService
{
[SerializeField] private MapDatabaseSO _database;
[Header("Event Channels")]
[SerializeField] private StringEventChannelSO _onRoomEntered; // 订阅 EVT_RoomEntered
[SerializeField] private StringEventChannelSO _onMapUpdated; // 发布:房间发现时
[SerializeField] private StringEventChannelSO _onRegionChanged; // 发布:玩家首次进入新区域时(EVT_RegionChanged)
// 三级可见性:
// Unknown → 未进入过(默认)
// Explored → 进入过(显示轮廓/格子)
// Mapped → 完整地图信息(购买 MapFragment 或存档点揭示)
private HashSet _exploredRooms = new();
private HashSet _mappedRooms = new();
private string _currentRegionId;
private readonly CompositeDisposable _subs = new();
private void Awake()
{
if (ServiceLocator.GetOrDefault() != null) { Destroy(gameObject); return; }
ServiceLocator.Register(this);
}
private void OnEnable()
{
_onRoomEntered?.Subscribe(OnRoomEntered).AddTo(_subs);
ServiceLocator.GetOrDefault()?.Register(this);
}
private void OnDisable()
{
_subs.Clear();
ServiceLocator.GetOrDefault()?.Unregister(this);
}
// ── ISaveable ─────────────────────────────────────────────────────────
public void OnSave(SaveData data)
{
data.Map.ExploredRooms ??= new List();
data.Map.ExploredRooms.Clear();
data.Map.ExploredRooms.AddRange(_exploredRooms);
data.Map.MappedRooms ??= new List();
data.Map.MappedRooms.Clear();
data.Map.MappedRooms.AddRange(_mappedRooms);
}
public void OnLoad(SaveData data)
{
_exploredRooms = new HashSet(data.Map.ExploredRooms ?? new System.Collections.Generic.List());
_mappedRooms = new HashSet(data.Map.MappedRooms ?? new System.Collections.Generic.List());
}
// ── 事件驱动房间发现 ──────────────────────────────────────────────────
private void OnRoomEntered(string roomId)
{
bool changed = _exploredRooms.Add(roomId);
if (changed) _onMapUpdated?.Raise(roomId);
// 区域变化检测:RegionId 非空且与上一次不同时广播 EVT_RegionChanged
var regionId = _database?.GetRoom(roomId)?.RegionId;
if (!string.IsNullOrEmpty(regionId) && regionId != _currentRegionId)
{
_currentRegionId = regionId;
_onRegionChanged?.Raise(regionId);
}
}
/// 标记为已完整获取地图信息(购买 MapFragment SO 触发)。
public void SetMapped(string roomId)
{
_exploredRooms.Add(roomId);
if (_mappedRooms.Add(roomId))
_onMapUpdated?.Raise(roomId);
}
// ── 查询 API ──────────────────────────────────────────────────────────
public bool IsExplored(string roomId) => _exploredRooms.Contains(roomId);
public bool IsMapped(string roomId) => _mappedRooms.Contains(roomId);
public string CurrentRegionId => _currentRegionId;
public MapDatabaseSO Database => _database;
private void OnDestroy()
{
ServiceLocator.Unregister(this);
}
}
}