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
});
}
}
}