|
|
|
@@ -0,0 +1,132 @@
|
|
|
|
|
extends SceneTree
|
|
|
|
|
|
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _initialize() -> void:
|
|
|
|
|
call_deferred("_run")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _run() -> void:
|
|
|
|
|
var manager := _create_manager(961)
|
|
|
|
|
var bush := ResourceNode.new()
|
|
|
|
|
bush.name = "RegrowBush"
|
|
|
|
|
bush.node_id = &"regrow_bush"
|
|
|
|
|
bush.action_id = SimulationIds.ACTION_GATHER_FOOD
|
|
|
|
|
bush.resource_id = SimulationIds.RESOURCE_FOOD
|
|
|
|
|
bush.initial_amount = 2.0
|
|
|
|
|
bush.max_amount = 5.0
|
|
|
|
|
bush.regrow_rate = 0.1
|
|
|
|
|
bush.debug_label_enabled = false
|
|
|
|
|
var interaction_point := Marker3D.new()
|
|
|
|
|
interaction_point.name = "InteractionPoint"
|
|
|
|
|
interaction_point.position = Vector3.ZERO
|
|
|
|
|
bush.add_child(interaction_point)
|
|
|
|
|
root.add_child(bush)
|
|
|
|
|
await process_frame
|
|
|
|
|
_check(
|
|
|
|
|
manager.register_resource_node(bush), "Regrowth test should bind a real finite ResourceNode"
|
|
|
|
|
)
|
|
|
|
|
var state: ResourceStateRecord = manager.get_resource_state(bush.node_id)
|
|
|
|
|
_check(
|
|
|
|
|
(
|
|
|
|
|
is_equal_approx(state.get_amount_remaining(), 2.0)
|
|
|
|
|
and is_equal_approx(state.get_max_amount(), 5.0)
|
|
|
|
|
and is_equal_approx(state.get_regrow_rate(), 0.1)
|
|
|
|
|
),
|
|
|
|
|
"Regrowth metadata should bind from the authored node"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
_check(
|
|
|
|
|
is_equal_approx(manager.harvest_resource_node(bush), 2.0),
|
|
|
|
|
"Harvesting should deplete the regrowing bush into carried inventory"
|
|
|
|
|
)
|
|
|
|
|
_check(
|
|
|
|
|
is_equal_approx(state.get_amount_remaining(), 0.0),
|
|
|
|
|
"The regrowing bush should reach zero after harvesting"
|
|
|
|
|
)
|
|
|
|
|
manager.simulate_tick()
|
|
|
|
|
manager.simulate_tick()
|
|
|
|
|
_check(
|
|
|
|
|
is_equal_approx(state.get_amount_remaining(), 0.2),
|
|
|
|
|
"Regrowing resources should recover exactly their rate per simulation tick"
|
|
|
|
|
)
|
|
|
|
|
for _tick in 50:
|
|
|
|
|
manager.simulate_tick()
|
|
|
|
|
_check(
|
|
|
|
|
(
|
|
|
|
|
is_equal_approx(state.get_amount_remaining(), 5.0)
|
|
|
|
|
and state.get_amount_remaining() <= state.get_max_amount()
|
|
|
|
|
),
|
|
|
|
|
"Regrowth should stop at the authored maximum without creating extra food"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
manager.simulate_tick()
|
|
|
|
|
var saved_json: String = manager.serialize_state()
|
|
|
|
|
var restored := _create_manager(962)
|
|
|
|
|
_check(
|
|
|
|
|
restored.restore_state_from_json(saved_json),
|
|
|
|
|
"Regrowing resource state should survive save and restore"
|
|
|
|
|
)
|
|
|
|
|
_check(
|
|
|
|
|
(
|
|
|
|
|
restored.get_state_checksum() == manager.get_state_checksum()
|
|
|
|
|
and is_equal_approx(
|
|
|
|
|
restored.get_resource_state(bush.node_id).get_amount_remaining(), 5.0
|
|
|
|
|
)
|
|
|
|
|
and is_equal_approx(restored.get_resource_state(bush.node_id).get_regrow_rate(), 0.1)
|
|
|
|
|
),
|
|
|
|
|
"Restore should preserve the regrow amount, cap, and checksum"
|
|
|
|
|
)
|
|
|
|
|
restored.free()
|
|
|
|
|
|
|
|
|
|
var v3_data: Dictionary = state.to_dictionary()
|
|
|
|
|
v3_data["schema_version"] = ResourceStateRecord.REGROW_LEGACY_SCHEMA_VERSION
|
|
|
|
|
v3_data.erase("max_amount")
|
|
|
|
|
v3_data.erase("regrow_rate")
|
|
|
|
|
var migrated := ResourceStateRecord.from_dictionary(v3_data)
|
|
|
|
|
_check(
|
|
|
|
|
(
|
|
|
|
|
migrated != null
|
|
|
|
|
and is_equal_approx(migrated.get_max_amount(), 5.0)
|
|
|
|
|
and is_equal_approx(migrated.get_regrow_rate(), 0.0)
|
|
|
|
|
),
|
|
|
|
|
"Resource v3 should migrate with its current amount as cap and no regrowth"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
bush.queue_free()
|
|
|
|
|
manager.free()
|
|
|
|
|
_finish()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _create_manager(seed_value: int = 961) -> Node:
|
|
|
|
|
var manager: Node = load("res://simulation/SimulationManager.gd").new()
|
|
|
|
|
manager.simulation_seed = seed_value
|
|
|
|
|
manager.debug_logs = false
|
|
|
|
|
var home_positions: Array[Vector3] = [
|
|
|
|
|
Vector3(0.0, 0.0, 0.0),
|
|
|
|
|
Vector3(2.0, 0.0, 0.0),
|
|
|
|
|
Vector3(10.0, 0.0, 0.0),
|
|
|
|
|
Vector3(12.0, 0.0, 0.0),
|
|
|
|
|
Vector3(30.0, 0.0, 30.0),
|
|
|
|
|
Vector3(40.0, 0.0, 40.0),
|
|
|
|
|
]
|
|
|
|
|
manager.home_positions = home_positions
|
|
|
|
|
root.add_child(manager)
|
|
|
|
|
manager.set_process(false)
|
|
|
|
|
return manager
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _finish() -> void:
|
|
|
|
|
if failures.is_empty():
|
|
|
|
|
print("[TEST] Resource regrowth passed: bounded recovery -> cap -> restore")
|
|
|
|
|
quit(0)
|
|
|
|
|
return
|
|
|
|
|
for failure in failures:
|
|
|
|
|
push_error("[TEST] " + failure)
|
|
|
|
|
quit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _check(condition: bool, message: String) -> void:
|
|
|
|
|
if not condition:
|
|
|
|
|
failures.append(message)
|