feat: generate world-backed situations and commitments
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
class_name QuestJournalSystem
|
||||
extends RefCounted
|
||||
|
||||
var _entries_by_id: Dictionary = {}
|
||||
var _entry_id_by_situation: Dictionary = {}
|
||||
var _next_entry_id := 0
|
||||
|
||||
|
||||
func add_situation(
|
||||
situation: SituationStateRecord,
|
||||
definition: SituationDefinition,
|
||||
alternative_id: StringName,
|
||||
current_tick: int
|
||||
) -> QuestJournalEntryStateRecord:
|
||||
if (
|
||||
situation == null
|
||||
or definition == null
|
||||
or not situation.is_active()
|
||||
or situation.get_definition_id() != definition.situation_definition_id
|
||||
or definition.get_alternative(alternative_id) == null
|
||||
or current_tick < situation.get_created_tick()
|
||||
or _entry_id_by_situation.has(situation.get_situation_id())
|
||||
or not situation.select_alternative(alternative_id)
|
||||
):
|
||||
return null
|
||||
var entry := QuestJournalEntryStateRecord.create(
|
||||
_next_entry_id,
|
||||
situation.get_situation_id(),
|
||||
definition.situation_definition_id,
|
||||
current_tick,
|
||||
alternative_id
|
||||
)
|
||||
_entries_by_id[_next_entry_id] = entry
|
||||
_entry_id_by_situation[situation.get_situation_id()] = _next_entry_id
|
||||
_next_entry_id += 1
|
||||
return entry
|
||||
|
||||
|
||||
func synchronize(
|
||||
situation: SituationStateRecord, current_tick: int
|
||||
) -> QuestJournalEntryStateRecord:
|
||||
if situation == null:
|
||||
return null
|
||||
var entry := get_for_situation(situation.get_situation_id())
|
||||
if entry == null or not entry.is_active() or situation.is_active():
|
||||
return null
|
||||
var status := QuestJournalEntryStateRecord.STATUS_ARCHIVED
|
||||
if situation.get_status() == SituationStateRecord.STATUS_RESOLVED:
|
||||
status = QuestJournalEntryStateRecord.STATUS_COMPLETED
|
||||
elif situation.get_status() == SituationStateRecord.STATUS_EXPIRED:
|
||||
status = QuestJournalEntryStateRecord.STATUS_FAILED
|
||||
return entry if entry.close(status, current_tick) else null
|
||||
|
||||
|
||||
func derive_progress(
|
||||
entry: QuestJournalEntryStateRecord,
|
||||
situation_system: SituationSystem,
|
||||
world_events: WorldEventStore,
|
||||
state_facts: Dictionary
|
||||
) -> SituationProgressSnapshot:
|
||||
if entry == null or situation_system == null:
|
||||
return SituationProgressSnapshot.new()
|
||||
return situation_system.derive_progress(
|
||||
situation_system.get_by_id(entry.get_situation_id()),
|
||||
world_events,
|
||||
state_facts,
|
||||
entry.get_selected_alternative_id()
|
||||
)
|
||||
|
||||
|
||||
func restore(records: Array[QuestJournalEntryStateRecord], restored_next_id: int) -> bool:
|
||||
var by_id: Dictionary = {}
|
||||
var by_situation: Dictionary = {}
|
||||
var next_id := maxi(restored_next_id, 0)
|
||||
for record in records:
|
||||
if (
|
||||
record == null
|
||||
or by_id.has(record.get_entry_id())
|
||||
or by_situation.has(record.get_situation_id())
|
||||
):
|
||||
return false
|
||||
by_id[record.get_entry_id()] = record
|
||||
by_situation[record.get_situation_id()] = record.get_entry_id()
|
||||
next_id = maxi(next_id, record.get_entry_id() + 1)
|
||||
_entries_by_id = by_id
|
||||
_entry_id_by_situation = by_situation
|
||||
_next_entry_id = next_id
|
||||
return true
|
||||
|
||||
|
||||
func get_by_id(entry_id: int) -> QuestJournalEntryStateRecord:
|
||||
return _entries_by_id.get(entry_id) as QuestJournalEntryStateRecord
|
||||
|
||||
|
||||
func get_for_situation(situation_id: int) -> QuestJournalEntryStateRecord:
|
||||
if not _entry_id_by_situation.has(situation_id):
|
||||
return null
|
||||
return get_by_id(int(_entry_id_by_situation[situation_id]))
|
||||
|
||||
|
||||
func get_all_sorted() -> Array[QuestJournalEntryStateRecord]:
|
||||
var records: Array[QuestJournalEntryStateRecord] = []
|
||||
for record in _entries_by_id.values():
|
||||
records.append(record)
|
||||
records.sort_custom(
|
||||
func(first: QuestJournalEntryStateRecord, second: QuestJournalEntryStateRecord) -> bool:
|
||||
return first.get_entry_id() < second.get_entry_id()
|
||||
)
|
||||
return records
|
||||
|
||||
|
||||
func get_active_sorted() -> Array[QuestJournalEntryStateRecord]:
|
||||
var records: Array[QuestJournalEntryStateRecord] = []
|
||||
for record in get_all_sorted():
|
||||
if record.is_active():
|
||||
records.append(record)
|
||||
return records
|
||||
Reference in New Issue
Block a user