using System; using System.Collections.Generic; using System.Linq; namespace Jovian.EncounterSystem { /// Tag for a quest log entry. public enum QuestLogEventType { Started, Advanced, Completed } /// /// One chronological entry in the quest log. Names are cached alongside ids so a loaded save /// can display the log even if the underlying encounter has since been renamed or removed. /// [Serializable] public class QuestLogEntry { public QuestLogEventType type; public string encounterInternalId; public string encounterName; public string fromEncounterName; } /// /// Chronological, serializable record of quest events. Subscribes to /// events at construction time — build it before any encounter fires so nothing is missed. /// /// /// This is the save payload for quest progression. On load, call with the /// saved entries and then with /// to rehydrate the gating set. /// public class QuestLog { private readonly List entries = new(); /// The log in chronological order. public IReadOnlyList Entries => entries; /// Subscribe to 's quest events; every fire appends an entry. public QuestLog(QuestProgress progress) { progress.QuestStarted += quest => Record(QuestLogEventType.Started, null, quest); progress.QuestAdvanced += (from, to) => Record(QuestLogEventType.Advanced, from, to); progress.QuestCompleted += quest => Record(QuestLogEventType.Completed, null, quest); } /// Return a copy of the current entries suitable for serialization. public List CreateSnapshot() { return new List(entries); } /// Replace the current entries with those from a save. Pass the list straight from /// the save payload. public void Restore(IEnumerable saved) { entries.Clear(); if(saved == null) { return; } entries.AddRange(saved); } /// Enumerate the distinct encounter ids present in the log — what /// needs on load. public IEnumerable ResolvedEncounterIds() { return entries .Select(entry => entry.encounterInternalId) .Where(id => !string.IsNullOrEmpty(id)); } private void Record(QuestLogEventType type, IEncounter from, IEncounter to) { entries.Add(new QuestLogEntry { type = type, encounterInternalId = to?.EncounterDefinition?.internalId, encounterName = to?.EncounterDefinition?.name, fromEncounterName = from?.EncounterDefinition?.name }); } } }