namespace BaseGames.World.Map
{
///
/// IMapService 无状态扩展方法,集中可复用的查询逻辑。
/// MapPanel、MinimapHUD 等所有消费方均调用此处,避免分散的重复实现。
///
/// RegionNameEntry 字典构建与解析逻辑(BuildRegionDict / ResolveRegionDisplayName)
/// 也集中在此,供 RegionNameDisplay 和 MapProgressDisplay 共享,消除 DRY 违反。
///
///
public static class MapServiceExtensions
{
///
/// 将 RegionNameEntry 数组构建为 O(1) 查询字典。
/// RegionNameDisplay / MapProgressDisplay 共享此实现,避免重复代码。
///
public static System.Collections.Generic.Dictionary BuildRegionDict(
RegionNameEntry[] entries)
{
var dict = new System.Collections.Generic.Dictionary();
if (entries == null) return dict;
foreach (var e in entries)
if (!string.IsNullOrEmpty(e.RegionId))
dict[e.RegionId] = e;
return dict;
}
///
/// 将 regionId 解析为玩家可读的显示名。
/// 优先读 LocKey,其次 DisplayName,最后回退到 regionId 本身。
///
public static string ResolveRegionDisplayName(
System.Collections.Generic.Dictionary dict,
string regionId)
{
if (dict != null && dict.TryGetValue(regionId, out var e))
return e.GetDisplayName();
return regionId;
}
///
/// 根据探索状态推导房间三级可见性(Explored > Mapped > Unknown)。
///
public static RoomVisibility GetVisibility(this IMapService svc, string roomId)
{
if (svc == null) return RoomVisibility.Unknown;
if (svc.IsExplored(roomId)) return RoomVisibility.Explored;
if (svc.IsMapped(roomId)) return RoomVisibility.Mapped;
return RoomVisibility.Unknown;
}
///
/// 在指定世界坐标处创建地图标记。
/// 通过 将世界坐标转换为
/// 房间 ID 和归一化位置;坐标不在任何已知房间内时返回 null。
///
public static BaseGames.Core.Save.MapPin CreatePinAtWorldPos(
this IPinService pinSvc,
IPlayerPositionProvider playerProvider,
UnityEngine.Vector3 worldPos,
BaseGames.Core.Save.PinType type = BaseGames.Core.Save.PinType.Marker,
string note = "")
{
if (pinSvc == null || playerProvider == null) return null;
if (!playerProvider.TryGetRoomAtWorldPos(worldPos, out var roomId, out var normPos)) return null;
return pinSvc.CreatePin(roomId, normPos.x, normPos.y, type, note);
}
}
}