Buy fleet berths with Fleet Offices
#219: fleet capacity is a built, supplied thing rather than a researched one. The eight fleet-size doctrines are gone; capacity is one berth free plus one per Fleet Office standing. An office charges every 25s for the vessel in its berth, priced off that vessel's own build cost so an expensive hull is expensive to keep, and drawn from its own store the way a gas burner draws gas. An office that cannot pay goes dark, its vessel is scuttled, and the player is told through the same queue quest lines use - which reaches them on a planet surface too. An empty berth is idle rather than starved: an office is only failing while there is something in it to fail, and holding it disabled would leave a berth that could never be crewed and so could never be paid for again. Ships have no hit points and a shield absorbs a hit wholesale, so the lost vessel is scuttled rather than damaged - otherwise a shielded hull would survive its own eviction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
parent
6e13b6397c
commit
1f5fecd371
60 changed files with 695 additions and 243 deletions
|
|
@ -9,7 +9,8 @@ extends SceneTree
|
|||
# holes where they used to be - it is repacked from whatever is researched.
|
||||
#
|
||||
# Verifies:
|
||||
# 1. with nothing researched only the mothership is offered (it is
|
||||
# 1. with nothing researched only the mothership and the Fleet Office are
|
||||
# offered (the mothership is
|
||||
# deliberately never gated - it is where research happens)
|
||||
# 2. researching a structure adds it, and it is placed, not left at
|
||||
# whatever offsets it happened to have in the scene file
|
||||
|
|
@ -79,21 +80,36 @@ func _process(delta: float) -> bool:
|
|||
|
||||
# --- 1. nothing researched ----------------------------------
|
||||
controller._refresh_build_status()
|
||||
# #219 put the Fleet Office beside the mothership at the opening:
|
||||
# it is the only way the fleet grows now, so gating it behind
|
||||
# research would gate fleet size behind research again - which is
|
||||
# the thing that ticket removed.
|
||||
var opening: Array = [GameState.BUILDING_MOTHERSHIP,
|
||||
GameState.BUILDING_FLEET_OFFICE]
|
||||
var shown: Array = _shown()
|
||||
if shown.size() != 1 or shown[0][0] != GameState.BUILDING_MOTHERSHIP:
|
||||
var names: Array = []
|
||||
for e in shown:
|
||||
names.append(e[0])
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (unresearched structures on offer: %s)" % [names])
|
||||
var shown_ids: Array = []
|
||||
for e in shown:
|
||||
shown_ids.append(e[0])
|
||||
shown_ids.sort()
|
||||
opening.sort()
|
||||
if shown_ids != opening:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (opening offer was %s, expected %s)" \
|
||||
% [shown_ids, opening])
|
||||
quit(1)
|
||||
return true
|
||||
# --- 4. and it is centred, being alone on its row -----------
|
||||
var only: Array = _slots()[0]
|
||||
if absf(only[1]) > 0.01:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (the only entry sits at x=%.1f instead of centred)" % only[1])
|
||||
# --- 4. and the row is centred as a whole -------------------
|
||||
# Two entries now, so "centred" is the pair straddling the middle
|
||||
# rather than one sitting on it. The rule being checked is the
|
||||
# same one: a short row is not left hanging off to one side.
|
||||
var slots: Array = _slots()
|
||||
var spread: float = 0.0
|
||||
for slot in slots:
|
||||
spread += float(slot[1])
|
||||
if absf(spread) > 0.01:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (the opening row is off-centre by %.1f)" % spread)
|
||||
quit(1)
|
||||
return true
|
||||
print("nothing researched -> only the mothership, centred")
|
||||
print("nothing researched -> the mothership and a Fleet Office, centred")
|
||||
|
||||
# --- 2. research three more ---------------------------------
|
||||
game_state.unlocked = ["shipyards", "logistics", "coordination"]
|
||||
|
|
@ -101,9 +117,11 @@ func _process(delta: float) -> bool:
|
|||
stage = 1
|
||||
return false
|
||||
1:
|
||||
# Three doctrines add three structures to the two the opening
|
||||
# already offers (#219's Fleet Office is one of those two).
|
||||
var shown2: Array = _shown()
|
||||
if shown2.size() != 4:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (researched 3, expected 4 entries, got %d)" % shown2.size())
|
||||
if shown2.size() != 5:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (researched 3, expected 5 entries, got %d)" % shown2.size())
|
||||
quit(1)
|
||||
return true
|
||||
for e in shown2:
|
||||
|
|
@ -117,23 +135,30 @@ func _process(delta: float) -> bool:
|
|||
var columns: int = controller.menu_columns(slots.size())
|
||||
var rows: int = controller.menu_rows(slots.size())
|
||||
if columns != 2:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (4 entries laid out in %d columns)" % columns)
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (%d entries laid out in %d columns)" \
|
||||
% [slots.size(), columns])
|
||||
quit(1)
|
||||
return true
|
||||
for i in range(slots.size()):
|
||||
var want_row: float = controller.menu_row_top(i / columns, rows, columns)
|
||||
var row: int = i / columns
|
||||
var want_row: float = controller.menu_row_top(row, rows, columns)
|
||||
if absf(slots[i][0] - want_row) > 0.01:
|
||||
print("slot %d at y=%.1f, expected row %d at y=%.1f" % [i, slots[i][0], i / columns, want_row])
|
||||
print("slot %d at y=%.1f, expected row %d at y=%.1f" % [i, slots[i][0], row, want_row])
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (a gap was left where a hidden entry used to be)")
|
||||
quit(1)
|
||||
return true
|
||||
# Each ROW is centred on however many it holds, so a final row
|
||||
# with one entry sits in the middle rather than in column 0.
|
||||
# Written the way the layout writes it, so an odd count is not
|
||||
# a special case here that is ordinary there.
|
||||
var in_row: int = mini(slots.size() - row * columns, columns)
|
||||
var spacing: float = controller.menu_column_spacing(columns)
|
||||
var want_x: float = -spacing * 0.5 if i % 2 == 0 else spacing * 0.5
|
||||
var want_x: float = (float(i % columns) - (float(in_row) - 1.0) * 0.5) * spacing
|
||||
if absf(slots[i][1] - want_x) > 0.01:
|
||||
print("TEST_BUILD_MENU_HIDES_LOCKED: FAIL (entry %d at x=%.1f, expected %.1f)" % [i, slots[i][1], want_x])
|
||||
quit(1)
|
||||
return true
|
||||
print("4 entries packed into consecutive slots, no gaps")
|
||||
print("%d entries packed into consecutive slots, no gaps" % slots.size())
|
||||
|
||||
# --- 6. #136: nothing overlaps, with EVERY structure on offer -
|
||||
# The bug the ticket reported: the row list ran out and the last
|
||||
|
|
|
|||
Loading…
Reference in a new issue