diff --git a/BuildController.gd b/BuildController.gd index aba4f36..8ac9ed7 100644 --- a/BuildController.gd +++ b/BuildController.gd @@ -297,6 +297,12 @@ func _on_action_pressed() -> void: _refresh_load_ore() _refresh_skill_menu() elif current_building.building_type == GameState.BUILDING_SHIP_CRAFTER: + # Remembered explicitly: _process() clears current_building while any + # menu is open, so by the next frame the panel would no longer know + # which crafter it belongs to. Losing this line makes every button in + # the panel bail out at its `== 0` guard while the panel itself still + # opens - which reads as "the buttons do nothing". + craft_building_id = current_building.building_id craft_menu.visible = true _refresh_craft_status() elif current_building.building_type == GameState.BUILDING_SHIP_LAB: @@ -640,6 +646,7 @@ func _refresh_craft_status() -> void: func _on_craft_interceptor() -> void: if craft_building_id == 0: + _say("No crafter selected - reopen this panel from the building") return # Still refused when there is nowhere to put the vessel - queueing an # order that can never be delivered would just bank vessels_owed forever. @@ -679,6 +686,7 @@ func _report_order(product: String) -> void: func _on_store_ore() -> void: if craft_building_id == 0: + _say("No crafter selected - reopen this panel from the building") return if GameState.fleet_cargo <= 0: _say("The fleet is carrying nothing - load ore at the mothership first") @@ -689,6 +697,7 @@ func _on_store_ore() -> void: func _on_craft_transporter() -> void: if craft_building_id == 0: + _say("No crafter selected - reopen this panel from the building") return if not GameState.queue_order(craft_building_id, GameState.PRODUCT_TRANSPORTER): # Two different refusals, and the player needs to know WHICH. @@ -801,6 +810,7 @@ func _refresh_lab() -> void: func _on_craft_shield() -> void: if craft_building_id == 0: + _say("No crafter selected - reopen this panel from the building") return if not GameState.shield_vessel_unlocked(): _say("Shield vessels must be unlocked at a ship lab first") diff --git a/tests/test_crafter_feedback.gd b/tests/test_crafter_feedback.gd index dad13d2..87f7d0b 100644 --- a/tests/test_crafter_feedback.gd +++ b/tests/test_crafter_feedback.gd @@ -20,11 +20,20 @@ extends SceneTree # overwritten on the very next frame, which is what made a working # button look dead # 5. the message is the FIRST line, not buried under the standing state +# 6. the panel is opened the way the GAME opens it - park the fleet on the +# crafter and press the action button - and every button then works +# +# Point 6 exists because this test used to set craft_building_id by hand. +# That skipped the one step that was actually broken: opening the panel +# stopped recording WHICH crafter, so every handler bailed out at its `== 0` +# guard while the panel still opened. Reported four times as "the buttons do +# nothing", and invisible to every test that set the id itself. var game_state: Node var scene: Node var controller: Node var crafter_id: int = 0 +var fleet: Node var stage: int = 0 var elapsed: float = 0.0 @@ -42,6 +51,15 @@ func _initialize() -> void: scene = load("res://Main.tscn").instantiate() root.add_child(scene) controller = scene.get_node("BuildController") + fleet = scene.get_node("Fleet") + + +func _tap(button: Control) -> void: + for pressed in [true, false]: + var ev: InputEventScreenTouch = InputEventScreenTouch.new() + ev.pressed = pressed + ev.position = button.size / 2.0 + button._gui_input(ev) func _first_line() -> String: @@ -54,17 +72,37 @@ func _process(delta: float) -> bool: 0: scene.get_node("AsteroidField").set_process(false) scene.get_node("EnemySpawner").set_process(false) + for a in get_nodes_in_group("asteroids"): + if is_instance_valid(a): + a.queue_free() scene.get_node("BuildingField").place(GameState.BUILDING_SHIP_CRAFTER, Vector2(500.0, 0.0)) crafter_id = int(game_state.buildings[-1].id) + # Park the fleet ON it and let the action button debounce in. + for ship in fleet.ships: + ship.position = Vector2(500.0, 0.0) + fleet.move_to(Vector2(500.0, 0.0)) elapsed = 0.0 stage = 1 return false 1: - if elapsed < 0.3: + if elapsed < 1.2: return false - controller.craft_building_id = crafter_id - controller.craft_menu.visible = true - controller._refresh_craft_status() + # --- 6. open it the way the game does ------------------------ + if controller.current_building == null: + print("TEST_CRAFTER_FEEDBACK: FAIL (fleet parked on the crafter never registered)") + quit(1) + return true + _tap(controller.action_button) + if not controller.craft_menu.visible: + print("TEST_CRAFTER_FEEDBACK: FAIL (the action button did not open the crafter panel)") + quit(1) + return true + if controller.craft_building_id != crafter_id: + print("craft_building_id=%d, crafter is %d" % [controller.craft_building_id, crafter_id]) + print("TEST_CRAFTER_FEEDBACK: FAIL (opening the panel did not record which crafter - every button will bail out)") + quit(1) + return true + print("panel opened from the building, bound to crafter %d" % controller.craft_building_id) # --- 1. store with an empty hold ---------------------------- controller._on_store_ore()