extends RefCounted ## Reproducible, disposable viewing scenario. All buildings, employees, inventory, ## and jobs go through Runtime commands; visitors come from production arrivals. ## The normal new-game state and the player's saves are never changed by this file. var failure := "" var facility_ids: Dictionary = {} var _runtime: Variant var _clock: Variant var _tree: SceneTree var _sequence := 0 func prepare(runtime: Variant, clock: Variant, tree: SceneTree) -> bool: _runtime = runtime _clock = clock _tree = tree _clock.set_paused(true) var operations: Dictionary = _runtime.enable_production_operations() if not bool(operations.get(&"ok", false)): return _fail("Could not enable production operations: %s" % operations) for row: Array in [ [&"reception", Vector3i(-8, 0, 0)], [&"cafeteria", Vector3i(2, 0, 0)], [&"kitchen", Vector3i(2, 0, 1)], ]: if not _build(row[0], row[1]): return false if not await advance(180): return false for facility: Dictionary in _runtime.construction_service.get_facilities(): facility_ids[facility[&"definition_id"]] = facility[&"instance_id"] # Four rooms sit on the completed reception and dining structure. One # continuous, paid staircase in the center joins all three upper landings; # same-floor corridor construction links the rooms on either side. for x: int in [-8, -6, 2, 4]: if not _build(&"standard_room", Vector3i(x, 2, 0)): return false for x: int in range(-4, 2): if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 1, 0)): return false if not await advance(60): return false for x: int in range(-4, 2): if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 2, 0)): return false if not await advance(10): return false # This walkway follows the upper side of the rooms. The final stair segment # gives real guests and the cleaner a legal route to this floor. for x: int in range(-8, 6): if not _build(&"guest_stairs" if x == -4 else &"guest_corridor", Vector3i(x, 3, 0)): return false if not await advance(10): return false for row: Array in [ [&"staff_akane", facility_ids[&"reception"], Vector3i(-8, 0, 0)], [&"staff_chika", facility_ids[&"cafeteria"], Vector3i(2, 0, 0)], [&"staff_iris", facility_ids[&"cafeteria"], Vector3i(4, 0, 0)], [&"staff_eri", &"", Vector3i(0, 0, 0)], ]: if not _command(&"hire_staff_candidate", { &"candidate_id": row[0], &"facility_id": row[1], &"current_cell": row[2], }): return false # A small explicitly seeded pantry is part of the disposable scenario; its # stacks are real and get consumed by the same service pipeline as gameplay. var cafeteria: Variant = _runtime.facility_service.get_instance(facility_ids[&"cafeteria"]) if not _command(&"add_inventory_stack", { &"owner_inventory_id": cafeteria.local_inventory_id, &"item_id": &"ingredient/basic_meal", &"quantity": 32, }): return false if not await advance(1): return false # The cleaner actually accepts, walks to, and completes these queued tasks. for index: int in 6: var target := Vector3i(-8 if index % 2 == 0 else 5, 3, 0) if not _command(&"create_staff_task", { &"task_id": StringName("pixel_view.clean.%02d" % index), &"task_type": &"clean", &"priority": 70 - index, &"options": { &"target_entity_id": facility_ids[&"reception"] if index % 2 == 0 else facility_ids[&"cafeteria"], &"target_cell": target, &"required_role_tags": [&"cleaner"], &"task_tags": [&"cleaning"], &"estimated_minutes": 8, }, }): return false return await advance(1) func advance(minutes: int) -> bool: for index: int in minutes: var before: int = _clock.absolute_minute _clock.advance_minutes(1) if _clock.absolute_minute != before + 1: return _fail("Scenario stopped at %s: %s" % [_clock.formatted_time(), _runtime.get_operations_report()]) var report: Dictionary = _runtime.get_operations_report() if bool(report.get(&"runtime_failure_latched", false)): return _fail("Operations failed: %s" % report) if index % 30 == 29: await _tree.process_frame return true func describe() -> Dictionary: var facilities: Array[Dictionary] = [] for facility: Variant in _runtime.facility_service.get_instances(): facilities.append({ "definition": String(facility.definition_id), "state": int(facility.state), "origin": [facility.origin.x, facility.origin.y, facility.origin.z], }) var actors: Array[Dictionary] = [] for guest: Variant in _runtime.guest_service.get_guests(): actors.append({"id": String(guest.guest_id), "kind": "guest", "state": int(guest.state), "cell": [guest.current_cell.x, guest.current_cell.y, guest.current_cell.z]}) for staff: Variant in _runtime.staff_service.get_staff_members(): actors.append({"id": String(staff.staff_id), "kind": "staff", "state": int(staff.state), "cell": [staff.current_cell.x, staff.current_cell.y, staff.current_cell.z]}) return {"time": _clock.formatted_time(), "minute": _clock.absolute_minute, "facilities": facilities, "actors": actors, "pantry_seed_meals": 32} func _build(definition_id: StringName, cell: Vector3i) -> bool: return _command(&"build_facility", {&"definition_id": definition_id, &"origin": cell}) func _command(type: StringName, payload: Dictionary) -> bool: _sequence += 1 var result: Variant = _runtime.submit_command(type, payload, &"player", &"", 50, -1, StringName("pixel_view.command.%04d" % _sequence)) if not result.is_success(): return _fail("%s failed for %s: %s %s" % [type, payload, result.message, result.details]) return true func _fail(message: String) -> bool: failure = message push_error(message) return false