class_name AnimalDefinition extends Resource const BEHAVIOR_GRAZER_ROUTINE := &"grazer_routine" @export var animal_definition_id: StringName @export var species_id: StringName @export var display_name: String @export var behavior_id: StringName = BEHAVIOR_GRAZER_ROUTINE @export var supported_action_ids: Array[StringName] = [] @export var presentation_cue_id: StringName @export_range(0.1, 10.0, 0.1) var movement_speed := 1.6 func validate() -> Array[String]: var errors: Array[String] = [] if not is_valid_stable_id(animal_definition_id): errors.append("animal_definition_id is invalid") if not is_valid_stable_id(species_id): errors.append("species_id is invalid for '%s'" % animal_definition_id) if display_name.strip_edges().is_empty(): errors.append("display_name is empty for '%s'" % animal_definition_id) if behavior_id != BEHAVIOR_GRAZER_ROUTINE: errors.append( "behavior_id '%s' is unsupported for '%s'" % [behavior_id, animal_definition_id] ) if not is_valid_stable_id(presentation_cue_id): errors.append("presentation_cue_id is invalid for '%s'" % animal_definition_id) if not is_finite(movement_speed) or movement_speed <= 0.0: errors.append("movement_speed must be positive for '%s'" % animal_definition_id) var seen: Dictionary = {} for action_id in supported_action_ids: if not is_valid_stable_id(action_id): errors.append("supported action ID is invalid for '%s'" % animal_definition_id) elif seen.has(action_id): errors.append( "duplicate supported action '%s' for '%s'" % [action_id, animal_definition_id] ) else: seen[action_id] = true return errors func supports_action(action_id: StringName) -> bool: return action_id in supported_action_ids static func is_valid_stable_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() > 96: return false for character in text: var code := character.unicode_at(0) if not ( (code >= 48 and code <= 57) or (code >= 65 and code <= 90) or (code >= 97 and code <= 122) or character in ["_", "-", ".", ":"] ): return false return true