94 lines
2.7 KiB
GDScript
94 lines
2.7 KiB
GDScript
class_name AnimalCatalog
|
|
extends Resource
|
|
|
|
const CORE_CATALOG_PATH := "res://simulation/animals/definitions/core_animals.tres"
|
|
|
|
@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 catalog := load(CORE_CATALOG_PATH) as AnimalCatalog
|
|
if catalog != null:
|
|
catalog.rebuild()
|
|
return catalog
|
|
|
|
|
|
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)
|