class_name SupplyManagementService extends RefCounted const PurchaseQuoteV2 := preload("res://scripts/supply/supply_purchase_quote_v2.gd") ## Player commands and deterministic replenishment. Vendor purchases arrive in ## the selected warehouse; all transfers inside the tree use real porter tasks. func preview_purchase(runtime: Variant, warehouse_id: StringName, item_id: StringName, quantity: int) -> Dictionary: # Keep the entire ordinary branch literal; only placed UNIQUE Mimi # selects the explicit total-order quote. No attendance/role/floor condition. if not PurchaseQuoteV2.eligible(runtime): return _preview_purchase_v1(runtime, warehouse_id, item_id, quantity) var quote := _preview_purchase_v1(runtime, warehouse_id, item_id, quantity) var item := SupplyCatalog.get_item(item_id) var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id) if facility == null or facility.definition_id != &"warehouse" or item.is_empty() \ or not bool(item.get(&"purchasable", false)) or quantity <= 0 or quantity > 10000: return quote var frozen := PurchaseQuoteV2.make(item_id, quantity, int(item[&"unit_price"])) if frozen.is_empty(): return quote # A09: purchases may use the hidden fund for what the front fund cannot pay. var cash: int = FinancePolicy.available_funds(runtime.economy_service) var space: int = maxi(SupplyCatalog.storage_capacity(facility.definition_id) - SupplyCatalog.inventory_weight(runtime.inventory_service, facility.local_inventory_id) - _incoming_weight(runtime, facility.local_inventory_id), 0) @warning_ignore("integer_division") var slots := space / int(item[&"unit_weight"]) quote[&"purchase_quote"] = frozen quote[&"total_cost"] = frozen[&"effective_total"] quote[&"cash_after"] = cash - int(frozen[&"effective_total"]) quote[&"max_quantity"] = PurchaseQuoteV2.affordable_quantity(cash, slots, int(item[&"unit_price"])) quote[&"ok"] = false quote[&"reason"] = &"" if not facility.allows_logistics(): quote[&"reason"] = &"FACILITY_CLOSED" elif int(frozen[&"effective_total"]) > cash: quote[&"reason"] = &"INSUFFICIENT_FUNDS" elif quantity * int(item[&"unit_weight"]) > space: quote[&"reason"] = &"STORAGE_FULL" else: quote[&"ok"] = true return quote func _preview_purchase_v1(runtime: Variant, warehouse_id: StringName, item_id: StringName, quantity: int) -> Dictionary: var cash: int = FinancePolicy.available_funds(runtime.economy_service) var item := SupplyCatalog.get_item(item_id) var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id) var quote := {&"ok": false, &"reason": &"", &"total_cost": 0, &"cash_after": cash, &"quantity_after": 0, &"max_quantity": 0} if facility == null or facility.definition_id != &"warehouse": quote[&"reason"] = &"NOT_WAREHOUSE" return quote if item.is_empty() or not bool(item.get(&"purchasable", false)): quote[&"reason"] = &"ITEM_NOT_PURCHASABLE" return quote var price := int(item[&"unit_price"]) var space: int = maxi(SupplyCatalog.storage_capacity(facility.definition_id) - SupplyCatalog.inventory_weight(runtime.inventory_service, facility.local_inventory_id) - _incoming_weight(runtime, facility.local_inventory_id), 0) quote[&"max_quantity"] = mini(space / int(item[&"unit_weight"]), maxi(cash, 0) / price) quote[&"quantity_after"] = runtime.inventory_service.total_quantity(facility.local_inventory_id, item_id) + maxi(quantity, 0) quote[&"total_cost"] = maxi(quantity, 0) * price quote[&"cash_after"] = cash - int(quote[&"total_cost"]) if quantity <= 0 or quantity > 10000: quote[&"reason"] = &"INVALID_QUANTITY" elif not facility.allows_logistics(): quote[&"reason"] = &"FACILITY_CLOSED" elif int(quote[&"total_cost"]) > cash: quote[&"reason"] = &"INSUFFICIENT_FUNDS" elif quantity * int(item[&"unit_weight"]) > space: quote[&"reason"] = &"STORAGE_FULL" else: quote[&"ok"] = true return quote func purchase(runtime: Variant, command: SimulationCommand) -> CommandResult: var payload := command.payload if not _text(payload.get(&"warehouse_id")) or not _text(payload.get(&"item_id")) or not _integer(payload.get(&"quantity")): return _failure(command, &"INVALID_PAYLOAD") var warehouse_id := StringName(payload[&"warehouse_id"]) var item_id := StringName(payload[&"item_id"]) var quantity := int(payload[&"quantity"]) return _purchase_paid(runtime, warehouse_id, item_id, quantity, runtime._runtime_event_minute(), StringName("supply.purchase.%d" % command.command_id), command.command_id) func _purchase_paid(runtime: Variant, warehouse_id: StringName, item_id: StringName, quantity: int, minute: int, ledger_key: StringName, command_id: int = 0, record_auto_attempt: bool = false) -> CommandResult: # Shared transaction only; internal replenishment does not enqueue a command. var quote := preview_purchase(runtime, warehouse_id, item_id, quantity) if not bool(quote[&"ok"]): return _purchase_failure(command_id, StringName(quote[&"reason"]), quote) var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id) var item := SupplyCatalog.get_item(item_id) var inventory_before: Dictionary = runtime.inventory_service.create_snapshot() var economy_before: Dictionary = runtime.economy_service.create_snapshot() var plans_before: Dictionary = runtime.auto_purchase_plans.create_snapshot() if record_auto_attempt else {} var stocked: Dictionary = runtime.inventory_service.add_stack(facility.local_inventory_id, item_id, quantity, 100, minute + int(item[&"shelf_life_minutes"]), minute, int(item[&"unit_weight"])) if not bool(stocked.get(&"ok", false)): runtime.inventory_service.restore_snapshot(inventory_before) runtime.economy_service.restore_snapshot(economy_before) return _purchase_failure(command_id, &"INVENTORY_ERROR") var memo: StringName = SupplyAutoPurchasePlans.receipt_memo(item_id, quantity, int(item[&"unit_price"]), int(quote[&"total_cost"])) if record_auto_attempt else &"supply_purchase" if quote.has(&"purchase_quote"): memo = PurchaseQuoteV2.receipt_memo(quote[&"purchase_quote"]) # A09: the hidden fund covers what the front fund cannot pay, in its own posting # before the single-entry purchase (its receipt shape is unchanged). var top_up: CommandResult = runtime.top_up_front_fund(int(quote[&"total_cost"]), minute, StringName("finance.back_top_up.purchase." + String(ledger_key))) if not top_up.is_success(): runtime.inventory_service.restore_snapshot(inventory_before) runtime.economy_service.restore_snapshot(economy_before) return _purchase_failure(command_id, &"PAYMENT_FAILED") var paid: CommandResult = runtime.economy_service.transfer(&"PLAYER_CASH", runtime.OPERATING_EXPENSE_ACCOUNT, int(quote[&"total_cost"]), minute, &"OPERATING_EXPENSE", warehouse_id, ledger_key, memo, &"", false) if not paid.is_success(): runtime.inventory_service.restore_snapshot(inventory_before) runtime.economy_service.restore_snapshot(economy_before) return _purchase_failure(command_id, &"PAYMENT_FAILED") var recorded := true if record_auto_attempt: if quote.has(&"purchase_quote"): recorded = runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, CommandResult.succeeded(0, {&"transaction_id": paid.details[&"transaction_id"], &"quantity": quantity, &"purchase_quote": quote[&"purchase_quote"], &"total_cost": quote[&"total_cost"]}), runtime.economy_service) else: recorded = runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, CommandResult.succeeded(0, {&"transaction_id": paid.details[&"transaction_id"], &"quantity": quantity, &"unit_price": item[&"unit_price"], &"total_cost": quote[&"total_cost"]}), runtime.economy_service) if not recorded: runtime.inventory_service.restore_snapshot(inventory_before) runtime.economy_service.restore_snapshot(economy_before) return _purchase_failure(command_id, &"PAYMENT_FAILED") if not runtime.economy_service.commit_transaction_notification(StringName(paid.details[&"transaction_id"])) \ or (int(top_up.details.get(&"amount", 0)) > 0 and not runtime.economy_service.commit_transaction_notification(StringName(top_up.details[&"transaction_id"]))): runtime.inventory_service.restore_snapshot(inventory_before) runtime.economy_service.restore_snapshot(economy_before) if record_auto_attempt: runtime.auto_purchase_plans.restore_snapshot(plans_before, runtime.facility_service, runtime.economy_service, minute) return _purchase_failure(command_id, &"PAYMENT_FAILED") quote.merge({&"warehouse_id": warehouse_id, &"item_id": item_id, &"quantity": quantity, &"transaction_id": paid.details[&"transaction_id"]}) return CommandResult.succeeded(command_id, quote) func set_auto_purchase(runtime: Variant, command: SimulationCommand) -> CommandResult: var payload := command.payload if not _exact_keys(payload, [&"warehouse_id", &"item_id", &"enabled", &"target_stock"]) \ or not _text(payload[&"warehouse_id"]) or not _text(payload[&"item_id"]) \ or typeof(payload[&"enabled"]) != TYPE_BOOL or typeof(payload[&"target_stock"]) != TYPE_INT: return _failure(command, &"INVALID_PAYLOAD") var changed: Dictionary = runtime.auto_purchase_plans.set_plan( StringName(payload[&"warehouse_id"]), StringName(payload[&"item_id"]), payload[&"enabled"], payload[&"target_stock"], runtime.facility_service) if not bool(changed.get(&"ok", false)): return _failure(command, StringName(changed.get(&"reason", &"INVALID_TARGET")), changed) return CommandResult.succeeded(command.command_id, changed[&"plan"]) func auto_purchase_report(runtime: Variant, warehouse_id: StringName, item_id: StringName) -> Dictionary: var row: Dictionary = runtime.auto_purchase_plans.get_plan(warehouse_id, item_id) var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id) row[&"maximum_target"] = SupplyAutoPurchasePlans.maximum_target(warehouse_id, item_id, runtime.facility_service) row[&"physical_quantity"] = runtime.inventory_service.total_quantity(facility.local_inventory_id, item_id) if facility != null else 0 row[&"incoming_quantity"] = _incoming_quantity(runtime, facility.local_inventory_id, item_id) if facility != null else 0 row[&"deficit"] = maxi(int(row[&"target_stock"]) - int(row[&"physical_quantity"]) - int(row[&"incoming_quantity"]), 0) row[&"quote"] = preview_purchase(runtime, warehouse_id, item_id, int(row[&"deficit"])) if int(row[&"deficit"]) > 0 else {} row[&"reason"] = &"" if not bool(row[&"enabled"]): row[&"state"] = &"DISABLED" elif bool(runtime.get_operations_report().get(&"tick_blocked", false)): row[&"state"] = &"BLOCKED" row[&"reason"] = &"OPERATIONS_BLOCKED" elif int(runtime._state.get_resource(&"mana")) <= 0: row[&"state"] = &"BLOCKED" row[&"reason"] = &"NO_POWER" elif _receiver_will_close(facility, runtime._clock.absolute_minute): row[&"state"] = &"BLOCKED" row[&"reason"] = &"FACILITY_CLOSED" elif int(row[&"last_attempt_minute"]) == runtime._clock.absolute_minute: row[&"state"] = &"ORDERED_THIS_MINUTE" if row[&"last_result"] == SupplyAutoPurchasePlans.RESULT_PURCHASED else &"BLOCKED" if row[&"state"] == &"BLOCKED": row[&"reason"] = row[&"last_result"] elif int(row[&"deficit"]) == 0: row[&"state"] = &"TARGET_REACHED" elif bool((row[&"quote"] as Dictionary).get(&"ok", false)): row[&"state"] = &"READY" else: row[&"state"] = &"BLOCKED" row[&"reason"] = (row[&"quote"] as Dictionary).get(&"reason", &"UNAVAILABLE") return row func advance_auto_purchases(runtime: Variant, minute: int) -> Array[Dictionary]: var results: Array[Dictionary] = [] if bool(runtime.get_operations_report().get(&"tick_blocked", false)) or int(runtime._state.get_resource(&"mana")) <= 0: return results for plan: Dictionary in runtime.auto_purchase_plans.get_plans(): if not bool(plan[&"enabled"]) or int(plan[&"last_attempt_minute"]) >= minute: continue var warehouse_id := StringName(plan[&"warehouse_id"]) var item_id := StringName(plan[&"item_id"]) var row := auto_purchase_report(runtime, warehouse_id, item_id) var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id) if int(row[&"deficit"]) <= 0 or facility == null or not facility.allows_logistics() or _receiver_will_close(facility, minute): continue var ledger_key := SupplyAutoPurchasePlans.order_key(warehouse_id, item_id, minute) var prior_id: StringName = runtime.economy_service.get_transaction_id_for_idempotency_key(ledger_key) var result: CommandResult if prior_id.is_empty(): if row[&"state"] != &"READY" or not bool((row[&"quote"] as Dictionary).get(&"ok", false)): continue result = _purchase_paid(runtime, warehouse_id, item_id, int(row[&"deficit"]), minute, ledger_key, 0, true) else: # A committed key replays its original item/quantity/price, even if # today's quote is unaffordable. It never stocks, charges or notifies. var receipt := SupplyAutoPurchasePlans.receipt_from_ledger(runtime.economy_service, warehouse_id, item_id, minute, prior_id) if receipt.is_empty(): var frozen := PurchaseQuoteV2.receipt_from_ledger(runtime.economy_service, warehouse_id, item_id, minute, prior_id) if frozen.is_empty(): result = _purchase_failure(0, &"REPLAY_MISMATCH") else: result = CommandResult.succeeded(0, {&"transaction_id": prior_id, &"quantity": frozen[&"quantity"], &"purchase_quote": frozen, &"total_cost": frozen[&"effective_total"], &"replayed": true}) else: result = CommandResult.succeeded(0, {&"transaction_id": prior_id, &"quantity": receipt[&"quantity"], &"unit_price": receipt[&"unit_price"], &"total_cost": receipt[&"total_cost"], &"replayed": true}) if (not result.is_success() or not prior_id.is_empty()) and not runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, result, runtime.economy_service): push_error("Automatic purchase could not record its committed attempt.") return results results.append({&"warehouse_id": warehouse_id, &"item_id": item_id, &"minute": minute, &"result": result.to_dictionary()}) return results func _receiver_will_close(facility: FacilityInstance, minute: int) -> bool: # LOGISTICS precedes FACILITY_COMPLETION. Honor an already scheduled close # without applying policy early or changing manual purchase/phase ordering. return facility != null and facility.policy_pending_effective_at >= 0 \ and facility.policy_pending_effective_at <= minute \ and facility.policy_pending.has(&"business_open") \ and not bool(facility.policy_pending[&"business_open"]) func _purchase_failure(command_id: int, reason: StringName, details: Dictionary = {}) -> CommandResult: var result := details.duplicate(true) result[&"reason"] = reason return CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command_id, "Supply command rejected: %s" % reason, result) func _exact_keys(value: Dictionary, expected: Array[StringName]) -> bool: if value.size() != expected.size(): return false for key: Variant in value: if typeof(key) not in [TYPE_STRING, TYPE_STRING_NAME] or StringName(key) not in expected: return false return true func set_production(runtime: Variant, command: SimulationCommand) -> CommandResult: var payload := command.payload if not _text(payload.get(&"facility_id")) or not payload.get(&"enabled") is bool or not _integer(payload.get(&"target_stock")): return _failure(command, &"INVALID_PAYLOAD") var facility_id := StringName(payload[&"facility_id"]) var facility: FacilityInstance = runtime.facility_service.get_instance(facility_id) if facility == null or facility.definition_id != &"kitchen": return _failure(command, &"NOT_KITCHEN") var result: Dictionary = runtime.kitchen_production.set_plan(facility_id, bool(payload[&"enabled"]), int(payload[&"target_stock"])) if not bool(result.get(&"ok", false)): return _failure(command, StringName(result.get(&"code", &"INVALID_TARGET")), result) return CommandResult.succeeded(command.command_id, result) func get_report(runtime: Variant) -> Dictionary: var warehouses: Array[Dictionary] = [] var kitchens: Array[Dictionary] = [] var destinations: Array[Dictionary] = [] for facility: FacilityInstance in _facilities(runtime): var row := _facility_row(runtime, facility) match facility.definition_id: &"warehouse": var quote := preview_purchase(runtime, facility.instance_id, SupplyCatalog.RAW_FOOD, 1) row[&"can_receive"] = bool(quote[&"ok"]) row[&"reason_codes"] = [] if bool(quote[&"ok"]) else [quote[&"reason"]] row[&"auto_purchase_plans"] = [] for item: Dictionary in SupplyCatalog.get_purchase_items(): (row[&"auto_purchase_plans"] as Array).append(auto_purchase_report(runtime, facility.instance_id, StringName(item[&"item_id"]))) warehouses.append(row) &"kitchen": row.merge(runtime.kitchen_production.get_report(facility.instance_id), true) row.merge({&"target_min": 4, &"target_step": 4, &"target_max": SupplyCatalog.KITCHEN_TARGET_MAX, &"inputs": {SupplyCatalog.RAW_FOOD: 4}, &"outputs": {SupplyCatalog.BASIC_MEAL: 4}}, true) row[&"reason_codes"] = [] if row[&"state"] in [&"PRODUCING", &"READY", &"TARGET_REACHED"] else [row[&"state"]] kitchens.append(row) &"cafeteria": row[&"missing_items"] = {SupplyCatalog.BASIC_MEAL: maxi(12 - runtime.inventory_service.available_quantity(facility.local_inventory_id, SupplyCatalog.BASIC_MEAL), 0)} row[&"reason_codes"] = facility.state_reasons.duplicate() if runtime.inventory_service.available_quantity(facility.local_inventory_id, SupplyCatalog.BASIC_MEAL) <= 0: row[&"reason_codes"].append(&"NO_INPUT") destinations.append(row) var bridge_report: Dictionary = runtime.supply_logistics.get_report() return {&"cash": runtime.economy_service.get_balance(&"PLAYER_CASH"), &"back_cash": runtime.economy_service.get_balance(FinancePolicy.BACK_CASH), &"catalog": SupplyCatalog.get_purchase_items(), &"warehouses": warehouses, &"kitchens": kitchens, &"destinations": destinations, &"deliveries": bridge_report.get(&"deliveries", [])} func ensure_deliveries(runtime: Variant, minute: int) -> void: var facilities := _facilities(runtime) for destination: FacilityInstance in facilities: if not destination.allows_logistics(): continue var source_type: StringName var item_id: StringName var target := 0 if destination.definition_id == &"kitchen" and bool(runtime.kitchen_production.get_plan(destination.instance_id).get(&"enabled", false)): source_type = &"warehouse" item_id = SupplyCatalog.RAW_FOOD target = SupplyCatalog.RAW_TARGET elif destination.definition_id == &"cafeteria": source_type = &"kitchen" item_id = SupplyCatalog.BASIC_MEAL target = 12 else: continue var deficit: int = target - runtime.inventory_service.total_quantity(destination.local_inventory_id, item_id) - _incoming_quantity(runtime, destination.local_inventory_id, item_id) var space: int = SupplyCatalog.storage_capacity(destination.definition_id) - SupplyCatalog.inventory_weight(runtime.inventory_service, destination.local_inventory_id) - _incoming_weight(runtime, destination.local_inventory_id) var needed: int = mini(mini(deficit, space), 4) if needed <= 0: continue var sources: Array[Dictionary] = [] for source: FacilityInstance in facilities: if source.definition_id != source_type or not source.allows_logistics(): continue if source_type == &"kitchen" and not _has_production_plan(runtime, source.instance_id): continue var available: int = runtime.inventory_service.available_quantity(source.local_inventory_id, item_id, minute) if available <= 0: continue sources.append({&"facility": source, &"available": available, &"distance": _connection_distance(runtime, source, destination)}) # Prefer a connected nearby supplier; IDs resolve equal routes stably. # If none is connected, retain one visible request for route repair. sources.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: if a[&"distance"] != b[&"distance"]: return a[&"distance"] < b[&"distance"] return String(a[&"facility"].instance_id) < String(b[&"facility"].instance_id)) for source_row: Dictionary in sources: var source: FacilityInstance = source_row[&"facility"] var available := int(source_row[&"available"]) var ids_before: Dictionary = runtime.id_generator.create_snapshot() var request_id := StringName("supply.%s" % runtime.id_generator.next_id(&"logistics_request")) var result: CommandResult = runtime._execute_create_logistics_request(SimulationCommand.new(0, minute, minute, 50, &"create_logistics_request", &"supply", destination.instance_id, {&"request_id": request_id, &"source_inventory_id": source.local_inventory_id, &"destination_inventory_id": destination.local_inventory_id, &"item_requirements": {item_id: mini(needed, available)}, &"priority": 50})) if not result.is_success(): runtime.id_generator.restore_snapshot(ids_before) break func validate_demolition(runtime: Variant, facility_id: StringName) -> Dictionary: var facility: FacilityInstance = runtime.facility_service.get_instance(facility_id) if facility == null: return {&"ok": true} if SupplyCatalog.inventory_weight(runtime.inventory_service, facility.local_inventory_id) > 0: return {&"ok": false, &"reason": &"STOCK_REMAINS"} for request: LogisticsRequest in runtime.logistics_requests.values(): if not request.is_terminal() and facility.local_inventory_id in [request.source_inventory_id, request.destination_inventory_id]: return {&"ok": false, &"reason": &"DELIVERY_ACTIVE"} if facility.definition_id == &"kitchen": var report: Dictionary = runtime.kitchen_production.get_report(facility_id) if bool(report.get(&"enabled", false)) or not report.get(&"active_batch", {}).is_empty(): return {&"ok": false, &"reason": &"PRODUCTION_ACTIVE"} return {&"ok": true} func _facility_row(runtime: Variant, facility: FacilityInstance) -> Dictionary: var definition: FacilityDefinition = runtime.definition_registry.get_facility(facility.definition_id) return {&"facility_id": facility.instance_id, &"display_name": definition.display_name, &"origin": facility.origin, &"layer": facility.origin.z, &"used": SupplyCatalog.inventory_weight(runtime.inventory_service, facility.local_inventory_id), &"capacity": SupplyCatalog.storage_capacity(facility.definition_id), &"stock": _stock(runtime, facility.local_inventory_id)} func _stock(runtime: Variant, inventory_id: StringName) -> Array[Dictionary]: var rows: Array[Dictionary] = [] for item_id: StringName in [SupplyCatalog.RAW_FOOD, SupplyCatalog.BASIC_MEAL]: var total: int = runtime.inventory_service.total_quantity(inventory_id, item_id) var available: int = runtime.inventory_service.available_quantity(inventory_id, item_id) rows.append({&"item_id": item_id, &"total": total, &"available": available, &"reserved": total - available, &"in_transit": _incoming_quantity(runtime, inventory_id, item_id)}) return rows func _incoming_quantity(runtime: Variant, inventory_id: StringName, item_id: StringName) -> int: var quantity := 0 for request: LogisticsRequest in runtime.logistics_requests.values(): if request.is_terminal(): continue if runtime.supply_logistics.is_returning(request.request_id): if request.source_inventory_id == inventory_id: quantity += runtime.inventory_service.total_quantity(StringName("cargo:%s" % request.assigned_carrier_id), item_id) elif request.destination_inventory_id == inventory_id: quantity += int(request.item_requirements.get(item_id, 0)) return quantity func _incoming_weight(runtime: Variant, inventory_id: StringName) -> int: var weight := 0 for request: LogisticsRequest in runtime.logistics_requests.values(): if request.is_terminal(): continue if runtime.supply_logistics.is_returning(request.request_id): if request.source_inventory_id == inventory_id: weight += SupplyCatalog.inventory_weight(runtime.inventory_service, StringName("cargo:%s" % request.assigned_carrier_id)) elif request.destination_inventory_id == inventory_id: weight += request.total_weight return weight func _facilities(runtime: Variant) -> Array[FacilityInstance]: var rows: Array[FacilityInstance] = runtime.facility_service.get_instances() rows.sort_custom(func(a: FacilityInstance, b: FacilityInstance) -> bool: return String(a.instance_id) < String(b.instance_id)) return rows func _failure(command: SimulationCommand, reason: StringName, details: Dictionary = {}) -> CommandResult: var result := details.duplicate(true) result[&"reason"] = reason return CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, "Supply command rejected: %s" % reason, result) func _text(value: Variant) -> bool: return (value is String or value is StringName) and not String(value).is_empty() func _integer(value: Variant) -> bool: return value is int or (value is float and is_finite(value) and value == floor(value) and absf(value) <= 1000000.0) func _has_production_plan(runtime: Variant, facility_id: StringName) -> bool: for plan: Dictionary in runtime.kitchen_production.get_plans(): if StringName(plan[&"facility_id"]) == facility_id: return true return false func _connection_distance(runtime: Variant, source: FacilityInstance, destination: FacilityInstance) -> int: var distance := 1000000 var seen: Dictionary = {} for cell: Vector3i in source.occupied_cells: for delta: Vector3i in [Vector3i.ZERO, Vector3i.LEFT, Vector3i.RIGHT, Vector3i.UP, Vector3i.DOWN]: var start := cell + delta if seen.has(start) or not runtime.path_service.has_cell(start): continue seen[start] = true var route: Dictionary = runtime.supply_logistics.find_facility_access_path(start, destination) if bool(route.get(&"reachable", false)): distance = mini(distance, int(route[&"steps"])) return distance