feat: add witnessed knowledge and wind ambience
This commit is contained in:
@@ -2,9 +2,11 @@ class_name SimulationStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_NAME := "the_steward.simulation"
|
||||
const SCHEMA_VERSION := 3
|
||||
const SCHEMA_VERSION := 5
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const PREVIOUS_SCHEMA_VERSION := 2
|
||||
const EVENT_LEGACY_SCHEMA_VERSION := 2
|
||||
const RELATIONSHIP_LEGACY_SCHEMA_VERSION := 3
|
||||
const PREVIOUS_SCHEMA_VERSION := 4
|
||||
|
||||
var simulation: Dictionary
|
||||
var village: VillageStateRecord
|
||||
@@ -12,6 +14,8 @@ var npcs: Array[NPCStateRecord] = []
|
||||
var resources: Array[ResourceStateRecord] = []
|
||||
var storages: Array[StorageStateRecord] = []
|
||||
var economic_events: Array[EconomicEventRecord] = []
|
||||
var relationships: Array[RelationshipStateRecord] = []
|
||||
var event_knowledge: Array[KnownEventStateRecord] = []
|
||||
|
||||
|
||||
func to_dictionary() -> Dictionary:
|
||||
@@ -28,6 +32,12 @@ func to_dictionary() -> Dictionary:
|
||||
var event_data: Array[Dictionary] = []
|
||||
for event_record in economic_events:
|
||||
event_data.append(event_record.to_dictionary())
|
||||
var relationship_data: Array[Dictionary] = []
|
||||
for relationship_record in relationships:
|
||||
relationship_data.append(relationship_record.to_dictionary())
|
||||
var knowledge_data: Array[Dictionary] = []
|
||||
for known_event_record in event_knowledge:
|
||||
knowledge_data.append(known_event_record.to_dictionary())
|
||||
|
||||
return {
|
||||
"schema": SCHEMA_NAME,
|
||||
@@ -37,7 +47,9 @@ func to_dictionary() -> Dictionary:
|
||||
"npcs": npc_data,
|
||||
"resources": resource_data,
|
||||
"storages": storage_data,
|
||||
"economic_events": event_data
|
||||
"economic_events": event_data,
|
||||
"relationships": relationship_data,
|
||||
"event_knowledge": knowledge_data
|
||||
}
|
||||
|
||||
|
||||
@@ -56,12 +68,32 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
if record_data.get("schema", "") != SCHEMA_NAME:
|
||||
return null
|
||||
var version := int(record_data.get("schema_version", -1))
|
||||
if version in [LEGACY_SCHEMA_VERSION, PREVIOUS_SCHEMA_VERSION]:
|
||||
if (
|
||||
version
|
||||
in [
|
||||
LEGACY_SCHEMA_VERSION,
|
||||
EVENT_LEGACY_SCHEMA_VERSION,
|
||||
RELATIONSHIP_LEGACY_SCHEMA_VERSION,
|
||||
PREVIOUS_SCHEMA_VERSION,
|
||||
]
|
||||
):
|
||||
record_data = _migrate_legacy(record_data, version)
|
||||
elif version != SCHEMA_VERSION:
|
||||
return null
|
||||
if not record_data.has_all(
|
||||
["simulation", "village", "npcs", "resources", "storages", "economic_events"]
|
||||
if not (
|
||||
record_data
|
||||
. has_all(
|
||||
[
|
||||
"simulation",
|
||||
"village",
|
||||
"npcs",
|
||||
"resources",
|
||||
"storages",
|
||||
"economic_events",
|
||||
"relationships",
|
||||
"event_knowledge",
|
||||
]
|
||||
)
|
||||
):
|
||||
return null
|
||||
|
||||
@@ -100,11 +132,15 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
var resource_data = record_data["resources"]
|
||||
var storage_data = record_data["storages"]
|
||||
var event_data = record_data["economic_events"]
|
||||
var relationship_data = record_data["relationships"]
|
||||
var knowledge_data = record_data["event_knowledge"]
|
||||
if (
|
||||
not npc_data is Array
|
||||
or not resource_data is Array
|
||||
or not storage_data is Array
|
||||
or not event_data is Array
|
||||
or not relationship_data is Array
|
||||
or not knowledge_data is Array
|
||||
):
|
||||
return null
|
||||
|
||||
@@ -152,6 +188,7 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
record.storages.append(storage_record)
|
||||
|
||||
var event_ids := {}
|
||||
var event_records_by_id := {}
|
||||
var highest_event_id := -1
|
||||
for item in event_data:
|
||||
if not item is Dictionary:
|
||||
@@ -163,11 +200,69 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
if event_ids.has(event_id):
|
||||
return null
|
||||
event_ids[event_id] = true
|
||||
event_records_by_id[event_id] = event_record
|
||||
highest_event_id = maxi(highest_event_id, event_id)
|
||||
record.economic_events.append(event_record)
|
||||
if int(record.simulation["next_event_id"]) <= highest_event_id:
|
||||
return null
|
||||
|
||||
var knowledge_keys := {}
|
||||
for item in knowledge_data:
|
||||
if not item is Dictionary:
|
||||
return null
|
||||
var known_event_record := KnownEventStateRecord.from_dictionary(item)
|
||||
if known_event_record == null:
|
||||
return null
|
||||
var knower_id := known_event_record.get_knower_id()
|
||||
var known_event_id := known_event_record.get_event_id()
|
||||
if not npc_ids.has(knower_id) or not event_ids.has(known_event_id):
|
||||
return null
|
||||
var knowledge_key := "%d:%d" % [knower_id, known_event_id]
|
||||
if knowledge_keys.has(knowledge_key):
|
||||
return null
|
||||
knowledge_keys[knowledge_key] = true
|
||||
record.event_knowledge.append(known_event_record)
|
||||
|
||||
var relationship_keys := {}
|
||||
for item in relationship_data:
|
||||
if not item is Dictionary:
|
||||
return null
|
||||
var relationship_record := RelationshipStateRecord.from_dictionary(item)
|
||||
if relationship_record == null:
|
||||
return null
|
||||
var observer_id := relationship_record.get_observer_id()
|
||||
var subject_id := relationship_record.get_subject_id()
|
||||
if not npc_ids.has(observer_id) or not npc_ids.has(subject_id):
|
||||
return null
|
||||
var relationship_key := "%d:%d" % [observer_id, subject_id]
|
||||
if relationship_keys.has(relationship_key):
|
||||
return null
|
||||
var cause_event_id := relationship_record.get_last_trust_cause_event_id()
|
||||
if (
|
||||
cause_event_id != RelationshipStateRecord.NO_CAUSE_EVENT
|
||||
and not event_ids.has(cause_event_id)
|
||||
):
|
||||
return null
|
||||
if (
|
||||
cause_event_id != RelationshipStateRecord.NO_CAUSE_EVENT
|
||||
and not knowledge_keys.has("%d:%d" % [observer_id, cause_event_id])
|
||||
):
|
||||
return null
|
||||
if cause_event_id != RelationshipStateRecord.NO_CAUSE_EVENT:
|
||||
var cause_event := event_records_by_id[cause_event_id] as EconomicEventRecord
|
||||
if (
|
||||
int(cause_event.data["actor_id"]) != subject_id
|
||||
or (
|
||||
StringName(cause_event.data["event_type"])
|
||||
!= SimulationIds.EVENT_STORAGE_DEPOSITED
|
||||
)
|
||||
or StringName(cause_event.data["item_id"]) != SimulationIds.RESOURCE_FOOD
|
||||
or float(cause_event.data["amount"]) <= 0.0
|
||||
):
|
||||
return null
|
||||
relationship_keys[relationship_key] = true
|
||||
record.relationships.append(relationship_record)
|
||||
|
||||
return record
|
||||
|
||||
|
||||
@@ -196,8 +291,89 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
|
||||
. to_dictionary()
|
||||
)
|
||||
]
|
||||
migrated["economic_events"] = []
|
||||
var simulation_data: Dictionary = migrated.get("simulation", {})
|
||||
simulation_data["next_event_id"] = 0
|
||||
migrated["simulation"] = simulation_data
|
||||
if version in [LEGACY_SCHEMA_VERSION, EVENT_LEGACY_SCHEMA_VERSION]:
|
||||
migrated["economic_events"] = []
|
||||
var simulation_data: Dictionary = migrated.get("simulation", {})
|
||||
simulation_data["next_event_id"] = 0
|
||||
migrated["simulation"] = simulation_data
|
||||
if (
|
||||
version
|
||||
in [LEGACY_SCHEMA_VERSION, EVENT_LEGACY_SCHEMA_VERSION, RELATIONSHIP_LEGACY_SCHEMA_VERSION]
|
||||
):
|
||||
migrated["relationships"] = _migrate_npc_familiarity(legacy_data.get("npcs", []))
|
||||
migrated["event_knowledge"] = _migrate_relationship_causes(migrated.get("relationships", []))
|
||||
return migrated
|
||||
|
||||
|
||||
static func _migrate_npc_familiarity(npc_data: Variant) -> Array[Dictionary]:
|
||||
var migrated_relationships: Array[Dictionary] = []
|
||||
if not npc_data is Array:
|
||||
return migrated_relationships
|
||||
for npc_item in npc_data:
|
||||
if not npc_item is Dictionary:
|
||||
continue
|
||||
var observer_id := int(npc_item.get("id", -1))
|
||||
var familiarity = npc_item.get("familiarity", [])
|
||||
if familiarity is Array:
|
||||
for pair in familiarity:
|
||||
if not pair is Dictionary:
|
||||
continue
|
||||
migrated_relationships.append(
|
||||
(
|
||||
RelationshipStateRecord
|
||||
. create(
|
||||
observer_id, int(pair.get("id", -1)), float(pair.get("score", 0.0))
|
||||
)
|
||||
. to_dictionary()
|
||||
)
|
||||
)
|
||||
elif familiarity is Dictionary:
|
||||
for subject_id in familiarity:
|
||||
migrated_relationships.append(
|
||||
(
|
||||
RelationshipStateRecord
|
||||
. create(observer_id, int(subject_id), float(familiarity[subject_id]))
|
||||
. to_dictionary()
|
||||
)
|
||||
)
|
||||
migrated_relationships.sort_custom(_relationship_dictionary_sort)
|
||||
return migrated_relationships
|
||||
|
||||
|
||||
static func _relationship_dictionary_sort(first: Dictionary, second: Dictionary) -> bool:
|
||||
if int(first["observer_id"]) != int(second["observer_id"]):
|
||||
return int(first["observer_id"]) < int(second["observer_id"])
|
||||
return int(first["subject_id"]) < int(second["subject_id"])
|
||||
|
||||
|
||||
static func _migrate_relationship_causes(relationship_data: Variant) -> Array[Dictionary]:
|
||||
var migrated_knowledge: Array[Dictionary] = []
|
||||
var known_keys := {}
|
||||
if not relationship_data is Array:
|
||||
return migrated_knowledge
|
||||
for relationship_item in relationship_data:
|
||||
if not relationship_item is Dictionary:
|
||||
continue
|
||||
var observer_id := int(relationship_item.get("observer_id", -1))
|
||||
var cause_event_id := int(
|
||||
relationship_item.get(
|
||||
"last_trust_cause_event_id", RelationshipStateRecord.NO_CAUSE_EVENT
|
||||
)
|
||||
)
|
||||
if observer_id < 0 or cause_event_id < 0:
|
||||
continue
|
||||
var knowledge_key := "%d:%d" % [observer_id, cause_event_id]
|
||||
if known_keys.has(knowledge_key):
|
||||
continue
|
||||
known_keys[knowledge_key] = true
|
||||
migrated_knowledge.append(
|
||||
KnownEventStateRecord.create(observer_id, cause_event_id).to_dictionary()
|
||||
)
|
||||
migrated_knowledge.sort_custom(_knowledge_dictionary_sort)
|
||||
return migrated_knowledge
|
||||
|
||||
|
||||
static func _knowledge_dictionary_sort(first: Dictionary, second: Dictionary) -> bool:
|
||||
if int(first["knower_id"]) != int(second["knower_id"]):
|
||||
return int(first["knower_id"]) < int(second["knower_id"])
|
||||
return int(first["event_id"]) < int(second["event_id"])
|
||||
|
||||
Reference in New Issue
Block a user