Let the fleet grow past twenty vessels
max_fleet_size() clamped itself to DEFAULT_FORMATION.size(), so the ceiling on the fleet was a property of the LAYOUT - the wedge ran out of authored positions at twenty - rather than a rule anyone decided on. Capacity is the supplied Fleet Offices and nothing else now. Dropping the clamp alone would index off the end of the formation array, so the wedge continues by rule instead of stopping: formation_slot() grows it on demand, each further pair stepping 30 further out and 40 further back, which is what the authored rows already do - the first twenty slots come back unchanged. A grown slot is rotated by formation_rotation so a fleet that outgrows the array after the player has pivoted does not sprout hulls facing the original heading, and that angle is saved with the layout. Two "fleet is full" messages pointed at the vanished ceiling. Both now say what actually buys a berth, and the hangar's stops claiming it is research, which it has not been since #219. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QR2Mdk42ghEpeyXPe4UFyn
This commit is contained in:
parent
f1292db40a
commit
93bfe62e76
7 changed files with 113 additions and 23 deletions
|
|
@ -21,7 +21,8 @@ extends SceneTree
|
|||
# B. each supplied office adds exactly one berth, and the cap bites
|
||||
# C. an office that cannot pay loses its vessel, and says so
|
||||
# D. a restocked office goes back to work without being rebuilt
|
||||
# E. capacity can never outrun the formation's defined positions
|
||||
# E. the wedge has a place for every slot, however far out it is
|
||||
# F. and nothing caps the fleet at the twenty positions the wedge authors
|
||||
|
||||
var game_state: Node
|
||||
var scene: Node
|
||||
|
|
@ -107,10 +108,35 @@ func _process(delta: float) -> bool:
|
|||
GameState.BASE_FLEET_SIZE + i + 1])
|
||||
print("3 supplied offices -> %d berths" % game_state.max_fleet_size())
|
||||
|
||||
# --- E. and never more than the formation can seat ------------
|
||||
if game_state.max_fleet_size() > GameState.DEFAULT_FORMATION.size():
|
||||
return _fail("capacity %d exceeds the %d positions the formation defines" \
|
||||
% [game_state.max_fleet_size(), GameState.DEFAULT_FORMATION.size()])
|
||||
# --- E. the wedge has a place for every slot ------------------
|
||||
# The formation used to be the fleet's real ceiling: it defined
|
||||
# twenty positions and capacity clamped itself to them. It now
|
||||
# continues by rule instead, so what is pinned here is that the
|
||||
# rule keeps the authored shape - the far slots are distinct,
|
||||
# and each pair still steps 30 out and 40 back from the last.
|
||||
var authored: int = GameState.DEFAULT_FORMATION.size()
|
||||
var probe: int = authored * 3
|
||||
var seen: Dictionary = {}
|
||||
for i in range(probe):
|
||||
var slot: Vector2 = game_state.formation_slot(i)
|
||||
var key: String = "%.1f,%.1f" % [slot.x, slot.y]
|
||||
if seen.has(key):
|
||||
return _fail("slot %d sits on top of slot %d at %s" % [i, int(seen[key]), key])
|
||||
seen[key] = i
|
||||
for i in range(authored):
|
||||
if not game_state.formation_slot(i).is_equal_approx(GameState.DEFAULT_FORMATION[i]):
|
||||
return _fail("growing the wedge moved authored slot %d to %s" \
|
||||
% [i, game_state.formation_slot(i)])
|
||||
for i in range(authored, probe - 2):
|
||||
var here: Vector2 = game_state.formation_slot(i)
|
||||
var behind: Vector2 = game_state.formation_slot(i + 2)
|
||||
var step: Vector2 = Vector2(GameState.FORMATION_PAIR_STEP.x * signf(here.x),
|
||||
GameState.FORMATION_PAIR_STEP.y)
|
||||
if not (behind - here).is_equal_approx(step):
|
||||
return _fail("slot %d steps %s from slot %d, expected %s" \
|
||||
% [i + 2, behind - here, i, step])
|
||||
print("the wedge continues past its %d authored slots, %d checked and all distinct" \
|
||||
% [authored, probe])
|
||||
|
||||
scene = load("res://world/Main.tscn").instantiate()
|
||||
root.add_child(scene)
|
||||
|
|
@ -187,6 +213,32 @@ func _process(delta: float) -> bool:
|
|||
return _fail("a supplied office lost its vessel anyway")
|
||||
print("restocked and re-crewed: the office pays and the vessel stays")
|
||||
|
||||
# --- F. and nothing caps the fleet at twenty ------------------
|
||||
# Offices past the wedge's authored positions buy real berths,
|
||||
# and the fleet really flies them: every hull gets a place of
|
||||
# its own rather than piling onto the last defined slot.
|
||||
var target: int = GameState.DEFAULT_FORMATION.size() + 4
|
||||
while game_state.max_fleet_size() < target:
|
||||
var extra: int = game_state.add_building(GameState.BUILDING_FLEET_OFFICE,
|
||||
Vector2(600.0 * float(game_state.max_fleet_size()), 900.0))
|
||||
_stock(extra, 500)
|
||||
if game_state.max_fleet_size() != target:
|
||||
return _fail("%d supplied offices gave %d berths, expected %d" \
|
||||
% [game_state.fleet_offices().size(), game_state.max_fleet_size(), target])
|
||||
while fleet.ships.size() < target:
|
||||
if not fleet.add_ship(GameState.VESSEL_INTERCEPTOR):
|
||||
return _fail("berth %d could not be crewed" % (fleet.ships.size() + 1))
|
||||
var places: Dictionary = {}
|
||||
for i in range(fleet.ships.size()):
|
||||
var offset: Vector2 = fleet.formation_offsets[i]
|
||||
var place: String = "%.1f,%.1f" % [offset.x, offset.y]
|
||||
if places.has(place):
|
||||
return _fail("vessel %d flies the same place as vessel %d" \
|
||||
% [i, int(places[place])])
|
||||
places[place] = i
|
||||
print("%d berths, %d vessels, %d distinct places - no ceiling at %d" \
|
||||
% [target, fleet.ships.size(), places.size(), GameState.DEFAULT_FORMATION.size()])
|
||||
|
||||
print("TEST_FLEET_GROWTH: PASS")
|
||||
quit(0)
|
||||
return true
|
||||
|
|
|
|||
Loading…
Reference in a new issue