Typed owed vessels, ship lab building type, shield vessel gate

Groundwork for #5. vessels_owed carries the VESSEL TYPE rather than a
bare count, so a shield vessel finishing while the player is on a planet
comes back as a shield vessel. Fleet.add_ship takes a type, and vessels
already flying are re-statted when an upgrade is researched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-11 23:10:07 +02:00
commit 19ac758da1
9 changed files with 80 additions and 27 deletions

View file

@ -32,6 +32,18 @@ var anchor: Vector2 = Vector2.ZERO
var steer_direction: Vector2 = Vector2.ZERO
func _ready() -> void:
# Researching a vessel upgrade improves the ships already flying, not
# just the next one built (#5).
GameState.vessel_upgraded.connect(_on_vessel_upgraded)
func _on_vessel_upgraded(_id: String) -> void:
for ship in ships:
if is_instance_valid(ship):
ship.apply_vessel_stats()
func spawn_ships(count: int, center: Vector2 = Vector2.ZERO) -> void:
for ship in ships:
if is_instance_valid(ship):
@ -55,13 +67,16 @@ func spawn_ships(count: int, center: Vector2 = Vector2.ZERO) -> void:
fleet_target = center
func add_ship() -> bool:
func add_ship(vessel_type: String = GameState.VESSEL_INTERCEPTOR) -> bool:
# Adds one vessel in the next free formation slot (bought from a ship
# crafter). Returns false when the wedge is already full.
if ships.size() >= GameState.max_fleet_size():
return false
var offset: Vector2 = GameState.formation[ships.size()]
var ship: Area2D = ship_scene.instantiate()
# Before add_child, so Ship._ready() builds the right vessel - the shield
# ring is created there and only for a shield vessel.
ship.vessel_type = vessel_type
# From the formation origin, not the centroid: with a lopsided layout the
# centroid is already displaced by the average offset, so adding the new
# ship's own offset to it would drop it well outside the wedge.
@ -128,12 +143,12 @@ func _process(delta: float) -> void:
func _claim_owed_ships() -> void:
# Production completes in the GameState autoload, which may well happen
# while the player is on a planet's surface with no Fleet node in
# existence to hand a vessel to. Those ships wait as `ships_owed` until a
# existence to hand a vessel to. Those vessels wait in `vessels_owed`
# fleet with room can take them.
while GameState.ships_owed > 0 and ships.size() < GameState.max_fleet_size():
if not add_ship():
while not GameState.vessels_owed.is_empty() and ships.size() < GameState.max_fleet_size():
if not add_ship(String(GameState.vessels_owed[0])):
return
GameState.ships_owed -= 1
GameState.vessels_owed.pop_front()
func _assign_slot_targets() -> void: