extends SceneTree # Forgejo #23 + #25: the mothership hangar presents vessels by type, tapping # an available type crews one, tapping a fleet type stores one, and contextual # world buttons each get their own touch berth. var game_state: Node var scene: Node var fleet: Node var controller: Node var stage: int = 0 var elapsed: float = 0.0 func _initialize() -> void: game_state = root.get_node("GameState") game_state.buildings.clear() game_state.extractors.clear() game_state.transporters.clear() game_state.stored_vessels.clear() game_state.rocks = 100 # #219: fleet capacity is built now - one berth free, one per Fleet # Office. This test flies more than one vessel, so it needs the offices # standing before the fleet spawns into them. load("res://tests/_berths.gd").grant(root.get_node("GameState"), 6) scene = load("res://world/Main.tscn").instantiate() root.add_child(scene) fleet = scene.get_node("Fleet") controller = scene.get_node("BuildController") func _process(delta: float) -> bool: elapsed += delta if stage == 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() fleet.spawn_ships(1, Vector2.ZERO) fleet.add_ship(GameState.VESSEL_SHIELD) game_state.stored_vessels = [GameState.VESSEL_INTERCEPTOR, GameState.VESSEL_SHIELD, GameState.VESSEL_TRANSPORTER] controller._on_hangar_pressed() elapsed = 0.0 stage = 1 return false if stage == 1: if elapsed < 0.2: return false # Available cards name the vessel and count what can be crewed. var available_label: Label = controller.hangar_menu.available_labels[0] if "Interceptor" not in available_label.text or "1 available" not in available_label.text: _fail("available interceptor card says '%s'" % available_label.text) return true if controller._hangar_types().has(GameState.VESSEL_TRANSPORTER) \ or fleet.add_ship(GameState.VESSEL_TRANSPORTER): _fail("a logistics transporter was exposed as a fleet vessel") return true controller._on_hangar_crew_type(0) if fleet.ships.size() != 3 or game_state.stored_vessels.has(GameState.VESSEL_INTERCEPTOR): _fail("tapping an available interceptor did not crew it") return true controller._on_hangar_store_type(1) if fleet.ships.size() != 2 or not game_state.stored_vessels.has(GameState.VESSEL_SHIELD): _fail("tapping the shield fleet card did not store it") return true # The safety rule prevents an empty deployed fleet. controller._on_hangar_store_type(0) controller._on_hangar_store_type(0) if fleet.ships.size() != 1: _fail("hangar allowed the last deployed ship to be stored") return true # Context actions are compact until expanded. A mothership unfolds # research and hangar; transfer stays as a persistent shortcut beside # Build and is not duplicated in the foldout. var mothership: Node2D = load("res://buildings/Building.tscn").instantiate() mothership.set("building_type", GameState.BUILDING_MOTHERSHIP) mothership._ready() controller.current_building = mothership controller.context_actions_expanded = true controller.transfer_button.visible = controller._has_transfer_context() controller._layout_context_buttons() var buttons: Array = [controller.building_action_button, controller.hangar_button] # Rendered width, not the authored rect: #228 shrinks the HUD on a # short canvas by scaling the node and leaving its rect alone, so # offset_right overstates where a button actually ends. for i in range(buttons.size() - 1): var ends: float = buttons[i].offset_left + buttons[i].size.x * buttons[i].scale.x if ends > buttons[i + 1].offset_left: _fail("context buttons %d and %d overlap" % [i, i + 1]) return true controller._collapse_context_actions() if controller.building_action_button.visible or controller.hangar_button.visible: _fail("collapsing the context button left an action visible") return true if not controller.transfer_button.visible \ or controller.transfer_button.offset_top != controller.build_button.offset_top \ or controller.transfer_button.offset_left <= controller.build_button.offset_left: _fail("transfer shortcut is not beside Build") return true mothership.free() print("hangar crews and stores typed vessels; contextual actions expand and collapse") print("TEST_HANGAR_MANAGEMENT: PASS") quit(0) return true return false func _fail(message: String) -> void: print("TEST_HANGAR_MANAGEMENT: FAIL (%s)" % message) quit(1)