Files
gamedev-the-steward/simulation/dialogue/ConversationTurn.gd
T
2026-08-12 20:32:53 +02:00

123 lines
3.0 KiB
GDScript

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
)