class_name ConversationActStateRecord extends RefCounted const SCHEMA_VERSION := 1 const MAX_TOPICS := 8 var data: Dictionary func _init(record_data: Dictionary = {}) -> void: data = record_data.duplicate(true) static func create( act_id: int, tick: int, speaker: WorldEntityRef, listener: WorldEntityRef, intent_id: StringName, topic_ids: Array[StringName] = [] ) -> ConversationActStateRecord: if ( act_id < 0 or tick < 0 or speaker == null or listener == null or not speaker.is_valid() or not listener.is_valid() or speaker.equals(listener) or not ConversationIntentIds.is_supported(intent_id) or topic_ids.size() > MAX_TOPICS ): return null var normalized_topics: Array[String] = [] var seen: Dictionary = {} for topic_id in topic_ids: if topic_id.is_empty() or seen.has(topic_id): return null seen[topic_id] = true normalized_topics.append(String(topic_id)) return ( ConversationActStateRecord . new( { "schema_version": SCHEMA_VERSION, "act_id": act_id, "tick": tick, "speaker": speaker.to_dictionary(), "listener": listener.to_dictionary(), "intent_id": String(intent_id), "topic_ids": normalized_topics, } ) ) static func from_dictionary(record_data: Dictionary) -> ConversationActStateRecord: if ( int(record_data.get("schema_version", -1)) != SCHEMA_VERSION or not record_data.has_all( ["act_id", "tick", "speaker", "listener", "intent_id", "topic_ids"] ) or not record_data["speaker"] is Dictionary or not record_data["listener"] is Dictionary or not record_data["topic_ids"] is Array ): return null var topics: Array[StringName] = [] for topic in record_data["topic_ids"]: if not topic is String and not topic is StringName: return null topics.append(StringName(topic)) return create( int(record_data["act_id"]), int(record_data["tick"]), WorldEntityRef.from_dictionary(record_data["speaker"]), WorldEntityRef.from_dictionary(record_data["listener"]), StringName(record_data["intent_id"]), topics ) func get_act_id() -> int: return int(data["act_id"]) func get_tick() -> int: return int(data["tick"]) func get_speaker() -> WorldEntityRef: return WorldEntityRef.from_dictionary(data["speaker"]) func get_listener() -> WorldEntityRef: return WorldEntityRef.from_dictionary(data["listener"]) func get_intent_id() -> StringName: return StringName(data["intent_id"]) func get_topic_ids() -> Array[StringName]: var result: Array[StringName] = [] for topic in data["topic_ids"]: result.append(StringName(topic)) return result func to_dictionary() -> Dictionary: return data.duplicate(true)