using System.Collections.Generic;
using UnityEngine;
namespace Jovian.ZoneSystem {
public class ZoneSystem {
private readonly ZonesObjectHolder zonesObjectHolder;
public ZoneSystem(ZonesObjectHolder zonesObjectHolder) {
this.zonesObjectHolder = zonesObjectHolder;
Refresh();
}
///
/// Returns the resolved ZoneContext at the given world position.
/// This is the only call your encounter/travel system needs to make.
///
public ZoneContext QueryZone(Vector3 worldPos) {
var overlapping = GetOverlappingZones(worldPos);
return ZoneResolver.Resolve(overlapping);
}
///
/// Returns all ZoneData assets whose polygons contain worldPos.
/// Ordered by descending priority — useful if you need the raw list
/// before resolution (e.g. for debug UI).
///
public List GetOverlappingZones(Vector3 worldPos) {
var result = new List();
foreach(var zone in zonesObjectHolder.Zones) {
if(zone == null || zone.data == null) {
continue;
}
if(zone.Contains(worldPos, zonesObjectHolder.mapPlane)) {
result.Add(zone.data);
}
}
result.Sort((a, b) => b.priority.CompareTo(a.priority));
return result;
}
///
/// Returns true if worldPos is inside any zone that is an Override+Safe zone
/// (i.e. a town or safe area). Cheap shortcut before rolling encounters.
///
public bool IsInSafeZone(Vector3 worldPos) {
foreach(var zone in zonesObjectHolder.Zones) {
if(zone == null || zone.data == null) {
continue;
}
if(zone.data.role == ZoneRole.Override &&
zone.data.isSafeZone &&
zone.Contains(worldPos, zonesObjectHolder.mapPlane)) {
return true;
}
}
return false;
}
///
/// Registers a single ZoneInstance dynamically (e.g. spawned at runtime).
///
internal void Register(ZoneInstance zone) {
if(!zonesObjectHolder.Zones.Contains(zone)) {
zone.RebuildBoundsCache();
zonesObjectHolder.Zones.Add(zone);
}
}
///
/// Unregisters a ZoneInstance (e.g. before it is destroyed at runtime).
///
public void Unregister(ZoneInstance zone) {
zonesObjectHolder.Zones.Remove(zone);
}
///
/// Re-scans the scene for all ZoneInstances and rebuilds their bounds caches.
/// Call this if you add or remove zones at runtime.
///
private void Refresh() {
zonesObjectHolder.Zones.Clear();
ZoneInstance[] found = Object.FindObjectsByType(FindObjectsSortMode.None);
foreach(ZoneInstance z in found) {
z.RebuildBoundsCache();
zonesObjectHolder.Zones.Add(z);
}
}
}
}