using System; using System.Collections.Generic; using UnityEngine; namespace Jovian.EncounterSystem { [CreateAssetMenu(fileName = "EncounterTable", menuName = "Jovian/Encounter System/Encounter Table", order = 1)] public class EncounterTable : ScriptableObject { public string id; public List encounters; public IEncounter GetRandomEncounter() { if(encounters == null || encounters.Count == 0) { return null; } return encounters[UnityEngine.Random.Range(0, encounters.Count)]; } public IEncounter GetRandomEncounter(Type type) { if(encounters == null || encounters.Count == 0) { return null; } var encountersOfType = encounters.FindAll(encounter => encounter.GetType() == type); if(encountersOfType.Count > 0) { return encountersOfType[UnityEngine.Random.Range(0, encountersOfType.Count)]; } return null; } /// Random pick limited by a predicate. Used with to exclude gated encounters. public IEncounter GetRandomEncounter(Predicate filter) { if(encounters == null || encounters.Count == 0 || filter == null) { return GetRandomEncounter(); } var pool = encounters.FindAll(filter); if(pool.Count == 0) { return null; } return pool[UnityEngine.Random.Range(0, pool.Count)]; } #if UNITY_EDITOR // Unity's inspector "+" duplicates the previous list element, including nested internalId // GUIDs. Regenerate any duplicates so every encounter carries a unique internalId. private void OnValidate() { if(encounters == null) { return; } var seen = new HashSet(); var changed = false; foreach(var encounter in encounters) { if(encounter?.EncounterDefinition == null) { continue; } var id = encounter.EncounterDefinition.internalId; if(string.IsNullOrEmpty(id) || !seen.Add(id)) { encounter.EncounterDefinition.internalId = Guid.NewGuid().ToString(); seen.Add(encounter.EncounterDefinition.internalId); changed = true; } } if(changed) { UnityEditor.EditorUtility.SetDirty(this); } } #endif } }