feat: define reusable animal archetypes
This commit is contained in:
@@ -4,12 +4,14 @@ extends RefCounted
|
||||
signal changed(state: AnimalStateRecord)
|
||||
signal fed(state: AnimalStateRecord, actor_id: int)
|
||||
|
||||
const SCHEMA_VERSION := 2
|
||||
const SCHEMA_VERSION := 3
|
||||
const ROUTINE_SCHEMA_VERSION := 2
|
||||
const LEGACY_SCHEMA_VERSION := 1
|
||||
const HUNGER_PER_TICK := 0.125
|
||||
const FEED_THRESHOLD := 65.0
|
||||
const HUNGER_RELIEF := 55.0
|
||||
const NEVER_FED_TICK := -1
|
||||
const LEGACY_DEFINITION_BY_SPECIES := {"goat": "domestic_goat"}
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
@@ -25,6 +27,7 @@ static func create_from_node(node: AnimalNode) -> AnimalStateRecord:
|
||||
{
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"animal_id": String(node.animal_id),
|
||||
"animal_definition_id": String(node.animal_definition_id),
|
||||
"display_name": node.display_name,
|
||||
"species_id": String(node.species_id),
|
||||
"position":
|
||||
@@ -49,6 +52,8 @@ static func from_dictionary(record_data: Dictionary) -> AnimalStateRecord:
|
||||
var version := int(record_data.get("schema_version", -1))
|
||||
if version == LEGACY_SCHEMA_VERSION:
|
||||
record_data = _migrate_legacy(record_data)
|
||||
elif version == ROUTINE_SCHEMA_VERSION:
|
||||
record_data = _migrate_definition_identity(record_data)
|
||||
elif version != SCHEMA_VERSION:
|
||||
return null
|
||||
if not (
|
||||
@@ -56,6 +61,7 @@ static func from_dictionary(record_data: Dictionary) -> AnimalStateRecord:
|
||||
. has_all(
|
||||
[
|
||||
"animal_id",
|
||||
"animal_definition_id",
|
||||
"display_name",
|
||||
"species_id",
|
||||
"position",
|
||||
@@ -75,6 +81,7 @@ static func from_dictionary(record_data: Dictionary) -> AnimalStateRecord:
|
||||
):
|
||||
return null
|
||||
var animal_id := String(record_data["animal_id"])
|
||||
var animal_definition_id := String(record_data["animal_definition_id"])
|
||||
var display_name := String(record_data["display_name"])
|
||||
var species_id := String(record_data["species_id"])
|
||||
var saved_position = record_data["position"]
|
||||
@@ -87,9 +94,12 @@ static func from_dictionary(record_data: Dictionary) -> AnimalStateRecord:
|
||||
var has_travel_target := bool(record_data["has_travel_target"])
|
||||
var next_routine_tick := int(record_data["next_routine_tick"])
|
||||
var enabled := bool(record_data["enabled"])
|
||||
if animal_id.is_empty() or display_name.is_empty() or species_id.is_empty():
|
||||
return null
|
||||
if StringName(species_id) != SimulationIds.SPECIES_GOAT:
|
||||
if (
|
||||
not AnimalDefinition.is_valid_stable_id(animal_id)
|
||||
or not AnimalDefinition.is_valid_stable_id(animal_definition_id)
|
||||
or display_name.is_empty()
|
||||
or not AnimalDefinition.is_valid_stable_id(species_id)
|
||||
):
|
||||
return null
|
||||
if not saved_position is Array or saved_position.size() != 3:
|
||||
return null
|
||||
@@ -120,6 +130,7 @@ static func from_dictionary(record_data: Dictionary) -> AnimalStateRecord:
|
||||
var normalized := record_data.duplicate(true)
|
||||
normalized["schema_version"] = SCHEMA_VERSION
|
||||
normalized["animal_id"] = animal_id
|
||||
normalized["animal_definition_id"] = animal_definition_id
|
||||
normalized["display_name"] = display_name
|
||||
normalized["species_id"] = species_id
|
||||
normalized["position"] = [
|
||||
@@ -145,7 +156,8 @@ func apply_definition(node: AnimalNode) -> bool:
|
||||
if node == null or node.animal_id != get_animal_id():
|
||||
return false
|
||||
return (
|
||||
node.display_name == get_display_name()
|
||||
node.animal_definition_id == get_animal_definition_id()
|
||||
and node.display_name == get_display_name()
|
||||
and node.species_id == get_species_id()
|
||||
and node.can_npcs_feed == can_npc_feed()
|
||||
and node.can_player_feed == can_player_feed_animal()
|
||||
@@ -156,6 +168,10 @@ func get_animal_id() -> StringName:
|
||||
return StringName(data["animal_id"])
|
||||
|
||||
|
||||
func get_animal_definition_id() -> StringName:
|
||||
return StringName(data["animal_definition_id"])
|
||||
|
||||
|
||||
func get_display_name() -> String:
|
||||
return String(data["display_name"])
|
||||
|
||||
@@ -350,10 +366,18 @@ func to_dictionary() -> Dictionary:
|
||||
|
||||
static func _migrate_legacy(record_data: Dictionary) -> Dictionary:
|
||||
var migrated := record_data.duplicate(true)
|
||||
migrated["schema_version"] = SCHEMA_VERSION
|
||||
migrated["schema_version"] = ROUTINE_SCHEMA_VERSION
|
||||
migrated["routine_site_id"] = ""
|
||||
migrated["travel_target_site_id"] = ""
|
||||
migrated["travel_target_position"] = [0.0, 0.0, 0.0]
|
||||
migrated["has_travel_target"] = false
|
||||
migrated["next_routine_tick"] = 0
|
||||
return _migrate_definition_identity(migrated)
|
||||
|
||||
|
||||
static func _migrate_definition_identity(record_data: Dictionary) -> Dictionary:
|
||||
var migrated := record_data.duplicate(true)
|
||||
migrated["schema_version"] = SCHEMA_VERSION
|
||||
var species_id := String(migrated.get("species_id", ""))
|
||||
migrated["animal_definition_id"] = String(LEGACY_DEFINITION_BY_SPECIES.get(species_id, ""))
|
||||
return migrated
|
||||
|
||||
Reference in New Issue
Block a user