class_name ConversationTurn extends RefCounted var _conversation_id: StringName var _revision := 0 var _speaker: WorldEntityRef var _listener: WorldEntityRef var _act: ConversationAct var _options: Array[ConversationOption] = [] var _causal_topic_ids: Array[StringName] = [] var _reason_trace: Array[StringName] = [] var _terminal := false func _init( conversation_id: StringName = &"", revision: int = 0, speaker: WorldEntityRef = null, listener: WorldEntityRef = null, act: ConversationAct = null, options: Array[ConversationOption] = [], causal_topic_ids: Array[StringName] = [], reason_trace: Array[StringName] = [], terminal: bool = false ) -> void: _conversation_id = conversation_id _revision = revision _speaker = ConversationSemantic.duplicate_entity(speaker) _listener = ConversationSemantic.duplicate_entity(listener) _act = act.copy() if act != null else null for option in options: _options.append(option.copy() if option != null else null) _causal_topic_ids = causal_topic_ids.duplicate() _reason_trace = reason_trace.duplicate() _terminal = terminal func is_valid() -> bool: if ( not ConversationSemantic.is_valid_id(_conversation_id) or _revision <= 0 or _speaker == null or not _speaker.is_valid() or _listener == null or not _listener.is_valid() or _speaker.equals(_listener) or _act == null or not _act.is_valid() or not _act.get_speaker().equals(_speaker) or not _act.get_listener().equals(_listener) or ConversationSemantic.normalize_id_array(_causal_topic_ids) == null or ConversationSemantic.normalize_trace(_reason_trace) == null ): return false var seen: Dictionary = {} for option in _options: if option == null or not option.is_valid() or seen.has(option.get_option_id()): return false if not option.get_speaker().equals(_listener) or not option.get_listener().equals(_speaker): return false seen[option.get_option_id()] = true return not _terminal or _options.is_empty() func get_conversation_id() -> StringName: return _conversation_id func get_revision() -> int: return _revision func get_speaker() -> WorldEntityRef: return ConversationSemantic.duplicate_entity(_speaker) func get_listener() -> WorldEntityRef: return ConversationSemantic.duplicate_entity(_listener) func get_act() -> ConversationAct: return _act.copy() if _act != null else null func get_options() -> Array[ConversationOption]: var result: Array[ConversationOption] = [] for option in _options: result.append(option.copy()) return result func get_option(option_id: StringName) -> ConversationOption: for option in _options: if option.get_option_id() == option_id: return option.copy() return null func get_causal_topic_ids() -> Array[StringName]: return _causal_topic_ids.duplicate() func get_reason_trace() -> Array[StringName]: return _reason_trace.duplicate() func is_terminal() -> bool: return _terminal func copy() -> ConversationTurn: return ConversationTurn.new( _conversation_id, _revision, _speaker, _listener, _act, _options, _causal_topic_ids, _reason_trace, _terminal )