--- scripts/core/bob_quest_check.gd +++ scripts/core/bob_quest_check.gd @@ -188,12 +188,66 @@ check(GameState.recipe_is_unlocked("bob_special"), "the recipe is not unlocked by Bob's visit") check(not room.customer_profile_is_available("regular"), "an ordinary customer walks in beside Bob") # Servi à table: il donne le lance-œufs. + _fixed_meal_wait(room, bob) Registry.run_hook("customer_profiles", "bob_guest", "on_served") await _play("bob_reward") check(int(_value(STATE)) == 2 and GameState.weapon_is_owned("egg_launcher"), "serving Bob does not give the egg launcher") room.customers.erase(bob) entry.customers[0] = null bob.free() + +# Exercise the restaurant's real order, stock and cooking paths. +func _fixed_meal_wait(room: Node, bob: Customer) -> void: + var stock := GameState.ingredients.duplicate() + var recipe_id := str(DataCatalog.CUSTOMER_PROFILES.bob_guest.fixed_recipe) + var requirements: Dictionary = DataCatalog.RECIPES[recipe_id].ingredients + var normal_order := bob.max_patience * float(GameState.resolve_game_variable("patience_coef_order", 0.6)) + var normal_meal := bob.max_patience * float(GameState.resolve_game_variable("patience_coef_service", 1.0)) + GameState.ingredients.clear() + room.customer_seated(bob) + check(bob.service_phase == Customer.ServicePhase.THINKING and is_equal_approx(bob.patience, bob.thinking_seconds), + "a missing fixed meal shortens the customer's thinking time") + room.customer_finished_thinking(bob) + check(bob.requested_recipe == recipe_id and is_equal_approx(bob.phase_allowed, normal_order * 0.25), + "Bob does not get a quarter of the ordering wait without his ingredients") + bob.take_order_by() + check(is_equal_approx(bob.phase_allowed, normal_meal * 0.25), + "Bob does not get a quarter of the meal wait without his ingredients") + bob._process(1.0) + var spent := bob.phase_allowed - bob.patience + room._release_unservable_waiting_customers() + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.patience, normal_meal * 0.25 - spent), + "rechecking an unavailable meal restarts or repeatedly shortens the wait") + for ingredient_id: String in requirements: + GameState.ingredients[ingredient_id] = int(requirements[ingredient_id]) + var missing := str(requirements.keys()[0]) + GameState.ingredients[missing] = int(requirements[missing]) - 1 + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.phase_allowed, normal_meal * 0.25), + "a partially stocked fixed meal gets the full wait") + GameState.ingredients[missing] = int(requirements[missing]) + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.phase_allowed, normal_meal) and is_equal_approx(bob.patience, normal_meal - spent), + "restocking does not restore the normal wait while preserving time spent") + room.start_cooking(recipe_id, 0) + check(room.station_is_busy(0) and not GameState.can_cook(recipe_id), "the fixed meal did not consume its last ingredients") + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.phase_allowed, normal_meal), "a fixed meal in the oven shortens the wait") + room.stations[0].remaining = 0.0 + room._finish_dish(0) + room.stations[0].recipe = "" + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.phase_allowed, normal_meal), "a cooked fixed meal shortens the wait") + for node: Node in GameState.scoped_nodes(room, "dish"): + if node is Dish and node.recipe_id == recipe_id: + node.free() + room._release_unservable_waiting_customers() + check(is_equal_approx(bob.phase_allowed, normal_meal * 0.25) and is_equal_approx(bob.patience, normal_meal * 0.25 - spent), + "losing the final portion does not shorten the wait without resetting it") + bob._process(bob.patience / bob._patience_drain() + 0.01) + check(bob.state == Customer.State.LEAVING, "Bob stays at the restaurant after the shortened wait expires") + GameState.ingredients = stock # --- 4. La planque ------------------------------------------------------------------ func _hideout() -> void: