feat: define action completion costs
This commit is contained in:
@@ -82,6 +82,15 @@ func _test_selection_and_execution_are_separate() -> void:
|
||||
unfunded_selection.action_id == SimulationIds.ACTION_GATHER_WOOD,
|
||||
"A guard should gather wood instead of selecting patrol when its material cost is unavailable"
|
||||
)
|
||||
_check(
|
||||
(
|
||||
unfunded_selection.rejections.has(SimulationIds.ACTION_PATROL)
|
||||
and "Needs 1 Wood" in String(
|
||||
unfunded_selection.rejections[SimulationIds.ACTION_PATROL]
|
||||
)
|
||||
),
|
||||
"Selection should expose a readable definition-backed rejection reason"
|
||||
)
|
||||
|
||||
|
||||
func _test_target_resolution_and_travel_are_separate() -> void:
|
||||
|
||||
@@ -204,6 +204,16 @@ func _test_wood_work_requires_material() -> void:
|
||||
),
|
||||
"Patrol should not consume partial wood or create safety when its full cost cannot be paid"
|
||||
)
|
||||
var blocked_events: Array[EconomicEventRecord] = manager.get_npc_events(npc.id, 2)
|
||||
_check(
|
||||
(
|
||||
not blocked_events.is_empty()
|
||||
and StringName(blocked_events[0].data["event_type"])
|
||||
== SimulationIds.EVENT_TASK_BLOCKED
|
||||
and "needs 1 Wood" in String(blocked_events[0].data.get("action_name", ""))
|
||||
),
|
||||
"An unpaid completion cost should create a readable blocked-task fact"
|
||||
)
|
||||
|
||||
manager.add_wood(1.5)
|
||||
_check(
|
||||
|
||||
@@ -63,7 +63,8 @@ func _run() -> void:
|
||||
SimulationIds.ACTION_GATHER_FOOD,
|
||||
-1.0,
|
||||
"Test shortage reason",
|
||||
{SimulationIds.ACTION_GATHER_FOOD: 4.5}
|
||||
{SimulationIds.ACTION_GATHER_FOOD: 4.5, SimulationIds.ACTION_PATROL: -1000000.0},
|
||||
{SimulationIds.ACTION_PATROL: "Needs 1 Wood (0.5 available)"}
|
||||
)
|
||||
manager.latest_decisions[npc.id] = test_decision
|
||||
manager.emit_signal("npc_decision_recorded", npc, test_decision)
|
||||
@@ -75,6 +76,14 @@ func _run() -> void:
|
||||
and npc.npc_name in inspector_label.text,
|
||||
"NPC inspector should show the selected villager's real decision reason"
|
||||
)
|
||||
_check(
|
||||
(
|
||||
"Unavailable" in inspector_label.text
|
||||
and "Patrol — Needs 1 Wood" in inspector_label.text
|
||||
and "-1000000" not in inspector_label.text
|
||||
),
|
||||
"NPC inspector should explain rejected actions without sentinel utility scores"
|
||||
)
|
||||
var carried_food: MeshInstance3D = visual.get_node("CarriedFood")
|
||||
_check(not carried_food.visible, "NPC should begin without a carried-food prop")
|
||||
npc.add_inventory(SimulationIds.RESOURCE_FOOD, 1.0)
|
||||
|
||||
@@ -65,6 +65,22 @@ func _test_definition_backed_behavior() -> void:
|
||||
study.preferred_profession_id == SimulationIds.PROFESSION_SCHOLAR,
|
||||
"Study should reference the stable scholar profession ID"
|
||||
)
|
||||
_check(
|
||||
(
|
||||
study.completion_cost_resource_id == SimulationIds.RESOURCE_WOOD
|
||||
and is_equal_approx(study.completion_cost_amount, 1.0)
|
||||
and study.has_completion_cost()
|
||||
),
|
||||
"Study should declare its completion cost through definition metadata"
|
||||
)
|
||||
var patrol := SimulationDefinitions.get_action(SimulationIds.ACTION_PATROL)
|
||||
_check(
|
||||
(
|
||||
patrol.completion_cost_resource_id == SimulationIds.RESOURCE_WOOD
|
||||
and is_equal_approx(patrol.completion_cost_amount, 1.0)
|
||||
),
|
||||
"Patrol should share the proven one-wood completion-cost contract"
|
||||
)
|
||||
var gather := SimulationDefinitions.get_action(SimulationIds.ACTION_GATHER_FOOD)
|
||||
_check(
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user