class_name AnimalCatalog extends Resource @export var animals: Array[AnimalDefinition] = [] var _definitions_by_id: Dictionary = {} var _definition_ids: Array[StringName] = [] var _errors: Array[String] = [] static func create_core() -> AnimalCatalog: var content := ContentCatalog.create_core() if content == null or not content.is_valid(): return null var catalog := AnimalCatalog.new() catalog.animals = content.get_animals() return catalog if catalog.rebuild().is_empty() else null func rebuild() -> Array[String]: _definitions_by_id.clear() _definition_ids.clear() _errors.clear() for definition in animals: if definition == null: _errors.append("Animal catalog contains a null definition") continue for error in definition.validate(): _errors.append("Animal '%s': %s" % [definition.animal_definition_id, error]) if _definitions_by_id.has(definition.animal_definition_id): _errors.append("Duplicate animal definition '%s'" % definition.animal_definition_id) else: _definitions_by_id[definition.animal_definition_id] = definition _definition_ids.append(definition.animal_definition_id) _definition_ids.sort_custom(_id_less) _errors.sort() return get_errors() func is_valid() -> bool: return rebuild().is_empty() func get_errors() -> Array[String]: return _errors.duplicate() func has_definition(animal_definition_id: StringName) -> bool: _ensure_built() return _definitions_by_id.has(animal_definition_id) func get_definition(animal_definition_id: StringName) -> AnimalDefinition: _ensure_built() return _definitions_by_id.get(animal_definition_id) as AnimalDefinition func matches_identity(animal_definition_id: StringName, species_id: StringName) -> bool: var definition := get_definition(animal_definition_id) return definition != null and definition.species_id == species_id func get_definition_ids() -> Array[StringName]: _ensure_built() return _definition_ids.duplicate() func get_definitions_for_behavior(behavior_id: StringName) -> Array[AnimalDefinition]: _ensure_built() var result: Array[AnimalDefinition] = [] for definition_id in _definition_ids: var definition := _definitions_by_id[definition_id] as AnimalDefinition if definition.behavior_id == behavior_id: result.append(definition) return result func find_definition_for_species(species_id: StringName) -> AnimalDefinition: _ensure_built() for definition_id in _definition_ids: var definition := _definitions_by_id[definition_id] as AnimalDefinition if definition.species_id == species_id: return definition return null func _ensure_built() -> void: if _definitions_by_id.is_empty() and not animals.is_empty(): rebuild() static func _id_less(left: StringName, right: StringName) -> bool: return String(left) < String(right)