using Jovian.EncounterSystem; using Jovian.ZoneSystem; using UnityEngine; namespace Nox.Game { public class EncounterHandler { private readonly ZoneSystem zoneSystem; private readonly EncounterRegistry encounterRegistry; private readonly EncounterView encounterView; private string previousZoneId; public EncounterHandler(ZoneSystem zoneSystem, EncounterRegistry encounterRegistry, EncounterPrefabs encounterPrefabs) { this.zoneSystem = zoneSystem; this.encounterRegistry = encounterRegistry; encounterView = new EncounterView(encounterPrefabs); } public bool AskForRandomEncounter(ZoneContext zoneContext, string encounterTableId, out IEncounter encounter) { return ResolveEncounter(zoneContext, encounterTableId, out encounter); } public bool AskForRandomEncounterOfType(ZoneContext zoneContext, string encounterTableId, out IEncounter encounter, IEncounterKind encounterKind) { return ResolveEncounter(zoneContext, encounterTableId, out encounter, encounterKind); } public bool AskForEncounter(string encounterId, out IEncounter encounter) { return encounterRegistry.GetEncounters().TryGetValue(encounterId, out encounter); } private bool ResolveEncounter(ZoneContext zoneContext, string encounterTableId, out IEncounter encounter, IEncounterKind encounterKind = null) { encounter = null; if(zoneContext.isSafe) { return false; } var randomChance = Random.Range(0f, 1f); var shouldTrigger = randomChance <= zoneContext.finalEncounterChance; if(!shouldTrigger) { return false; } if(encounterKind == null) { encounter = encounterRegistry.GetRandomEncounter(encounterTableId); return encounter != null; } encounter = encounterRegistry.GetRandomEncounter(encounterTableId, encounterKind); return encounter != null; } private void VerifyZones(Vector3 position) { var zoneContext = zoneSystem.QueryZone(position); if(string.IsNullOrEmpty(zoneContext.resolvedZoneId)) { return; } var currentZoneId = zoneContext.resolvedZoneId; if(currentZoneId != previousZoneId) { if(!string.IsNullOrEmpty(currentZoneId)) { Debug.Log($"Entered zone: {currentZoneId} (encounter: {zoneContext.encounterTableId}, safe: {zoneContext.isSafe})"); if(ResolveEncounter(zoneContext, zoneContext.encounterTableId, out var encounter)) { TriggerEncounter(encounter); } } else if(!string.IsNullOrEmpty(previousZoneId)) { Debug.Log($"Left zone: {previousZoneId}"); } previousZoneId = currentZoneId; } } private void TriggerEncounter(IEncounter encounter) { switch(encounter.EncounterDefinition.Kind) { case CombatKind: return; default: encounterView?.SetCurrentEncounter(encounter); encounterView?.Show(); break; } } public void CheckForEncounters(Vector3 position) { VerifyZones(position); } public void Tick() { } public void Dispose() { // nothing here } } }