Files
TheTree_mock/tests/fixtures/required_kitchen_setup.gd
Takeshi b84bade045 Save The Tree implementation and acceptance work in progress
Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
2026-10-11 15:58:00 +09:00

60 lines
4.8 KiB
GDScript

extends RefCounted
## Test-only public setup. Paid real kitchen/door; controlled model staff is
## explicitly separate from the new candidate's normally hired/commuting UI pair.
static func ensure(runtime: Variant, clock: Variant, cafe_id: StringName, physical_staff := true) -> Dictionary:
var cafe: FacilityInstance = runtime.facility_service.get_instance(cafe_id)
if cafe == null: return {&"ok": false, &"reason": &"NO_DINING_FIXTURE"}
if not runtime.facility_service.has_method(&"get_kitchen_placement_report"): return {&"ok": false, &"reason": &"NO_PLACEMENT_REPORT"}
var kitchen: FacilityInstance
var build_minutes := 0
var gold_cost := 0
var material_cost := 0
kitchen = _matching_kitchen(runtime, cafe_id)
if kitchen == null:
var definition: FacilityDefinition = runtime.definition_registry.get_facility(&"kitchen")
var result: CommandResult = runtime.submit_command(&"build_facility", {&"definition_id": &"kitchen", &"origin": Vector3i(cafe.origin.x, cafe.origin.y, WorldService.LAYER_BACK)})
if not result.is_success(): return {&"ok": false, &"reason": &"KITCHEN_BUILD_REJECTED", &"details": result.details}
build_minutes = definition.build_minutes
gold_cost += int(definition.construction_cost.get(&"gold", 0))
material_cost += int(definition.construction_cost.get(&"materials", 0))
var has_door := false
for facility: Dictionary in runtime.construction_service.get_facilities():
has_door = has_door or facility[&"definition_id"] == &"staff_door"
if not has_door:
var definition: FacilityDefinition = runtime.definition_registry.get_facility(&"staff_door")
var result: CommandResult = runtime.submit_command(&"build_facility", {&"definition_id": &"staff_door", &"origin": Vector3i(0, 0, WorldService.LAYER_BACK)})
if not result.is_success(): return {&"ok": false, &"reason": &"DOOR_BUILD_REJECTED", &"details": result.details}
build_minutes = maxi(build_minutes, definition.build_minutes)
gold_cost += int(definition.construction_cost.get(&"gold", 0))
material_cost += int(definition.construction_cost.get(&"materials", 0))
if build_minutes > 0: clock.advance_minutes(build_minutes)
if kitchen == null:
kitchen = _matching_kitchen(runtime, cafe_id)
if kitchen == null: return {&"ok": false, &"reason": &"KITCHEN_NOT_COMPLETE"}
var worker_id := StringName("fixture.kitchen.worker.%s" % cafe_id)
if physical_staff:
var registered: CommandResult = runtime.submit_command(&"register_staff", {&"staff_id": worker_id, &"role_id": &"cook", &"options": {&"state": StaffRuntime.State.OFF_DUTY, &"current_cell": kitchen.origin, &"role_tags": [&"cook"], &"permitted_task_tags": [&"cooking", &"work"], &"skills": {&"operation": 50}}})
if not registered.is_success(): return {&"ok": false, &"reason": &"WORKER_REGISTER_REJECTED", &"details": registered.details}
var minute: int = posmod(clock.absolute_minute, 1440)
var shift: CommandResult = runtime.submit_command(&"create_staff_shift", {&"staff_id": worker_id, &"template_id": &"FLEX", &"start_day": clock.absolute_minute / 1440, &"start_minute_of_day": minute, &"end_minute_of_day": 1439, &"facility_id": kitchen.instance_id})
if not shift.is_success(): return {&"ok": false, &"reason": &"WORKER_SHIFT_REJECTED", &"details": shift.details}
clock.advance_one_minute()
else:
# Preserve the existing S2/business legacy logical-attendance test contract;
# Only logical attendance is set here: registering a physical staff actor
# would enable Runtime projection and erase the old model staff on tick.
# This is a controlled public command fixture, not genuine hired commute.
var staffed: CommandResult = runtime.submit_command(&"set_facility_conditions", {&"facility_id": kitchen.instance_id, &"conditions": {&"active_staff_ids": [worker_id]}})
if not staffed.is_success(): return {&"ok": false, &"reason": &"LOGICAL_STAFF_REJECTED"}
var linked: CommandResult = runtime.submit_command(&"set_facility_conditions", {&"facility_id": cafe_id, &"conditions": {&"related_facility_id": kitchen.instance_id}})
return {&"ok": linked.is_success() and cafe.related_facility_operating, &"reason": &"" if linked.is_success() else &"LINK_REJECTED", &"kitchen_id": kitchen.instance_id, &"worker_id": worker_id, &"gold_cost": gold_cost, &"material_cost": material_cost, &"physical_staff": physical_staff}
# A geometrically valid, non-suspended kitchen may be staffed by this controlled
# fixture. Being merely BACK or already available elsewhere is not eligibility.
static func _matching_kitchen(runtime: Variant, cafe_id: StringName) -> FacilityInstance:
for instance: FacilityInstance in runtime.facility_service.get_instances():
var report: Dictionary = runtime.facility_service.get_kitchen_placement_report(cafe_id, instance.instance_id)
if bool(report.get(&"valid_placement", false)) and instance.suspension_reason.is_empty():
return instance
return null