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

57 lines
1.5 KiB
GDScript

class_name ConversationSemantic
extends RefCounted
const MAX_ID_LENGTH := 96
const MAX_TRACE_SIZE := 32
static func is_valid_id(value: Variant) -> bool:
if value is not String and value is not StringName:
return false
var text := String(value)
if text.is_empty() or text.length() > MAX_ID_LENGTH:
return false
for character in text:
if not _is_safe_id_character(character):
return false
return true
static func normalize_id_array(value: Variant, allow_empty: bool = true) -> Variant:
if value is not Array and value is not PackedStringArray:
return null
var normalized: Array[StringName] = []
var seen: Dictionary = {}
for item in value:
if not is_valid_id(item):
return null
var semantic_id := StringName(item)
if seen.has(semantic_id):
continue
seen[semantic_id] = true
normalized.append(semantic_id)
if not allow_empty and normalized.is_empty():
return null
return normalized
static func normalize_trace(value: Variant) -> Variant:
var normalized: Variant = normalize_id_array(value)
if normalized == null or normalized.size() > MAX_TRACE_SIZE:
return null
return normalized
static func duplicate_entity(entity: WorldEntityRef) -> WorldEntityRef:
return entity.duplicate_ref() if entity != null else null
static func _is_safe_id_character(character: String) -> bool:
var code := character.unicode_at(0)
return (
(code >= 48 and code <= 57)
or (code >= 65 and code <= 90)
or (code >= 97 and code <= 122)
or character in ["_", "-", ".", ":"]
)