Refactor gameplay menus into owned scenes

This commit is contained in:
Loïc Wisniewski 2026-08-31 02:18:08 +02:00
commit a17fe88197
50 changed files with 3449 additions and 3619 deletions

View file

@ -69,34 +69,34 @@ func _process(delta: float) -> bool:
# Gas Bomber is named after a resource and always will be, and
# what #111 removed was the PRICE spelled out underneath.
var fleet_defs: Array = VesselDefinitions.fleet()
for i in range(mini(controller.craft_vessel_labels.size(), fleet_defs.size())):
var caption: String = String(controller.craft_vessel_labels[i].text)
for i in range(mini(controller.craft_menu.vessel_labels.size(), fleet_defs.size())):
var caption: String = String(controller.craft_menu.vessel_labels[i].text)
var expected: String = String(fleet_defs[i].display_name)
if caption != expected:
return _fail("a craft caption reads \"%s\", expected just \"%s\"" \
% [caption, expected])
# Captions must not sit on top of one another, which is what
# made the old single row unreadable.
for i in range(controller.craft_vessel_labels.size()):
for j in range(i + 1, controller.craft_vessel_labels.size()):
var a: Control = controller.craft_vessel_labels[i]
var b: Control = controller.craft_vessel_labels[j]
for i in range(controller.craft_menu.vessel_labels.size()):
for j in range(i + 1, controller.craft_menu.vessel_labels.size()):
var a: Control = controller.craft_menu.vessel_labels[i]
var b: Control = controller.craft_menu.vessel_labels[j]
if Rect2(a.position, a.size).intersects(Rect2(b.position, b.size)):
return _fail("craft captions %d and %d overlap" % [i, j])
print("craft captions: %d, one line each, none overlapping" \
% controller.craft_vessel_labels.size())
% controller.craft_menu.vessel_labels.size())
# --- B. and the price is really there ---------------------
if controller.craft_price_strips.size() != controller.craft_vessel_buttons.size():
if controller.craft_menu.price_tags.size() != controller.craft_menu.vessel_buttons.size():
return _fail("%d price strips for %d vessels" \
% [controller.craft_price_strips.size(),
controller.craft_vessel_buttons.size()])
% [controller.craft_menu.price_tags.size(),
controller.craft_menu.vessel_buttons.size()])
var priced: int = 0
var stacked: int = 0
for i in range(controller.craft_price_strips.size()):
for i in range(controller.craft_menu.price_tags.size()):
var definition: Resource = VesselDefinitions.fleet()[i]
var costs: Dictionary = game_state.product_costs(definition.definition_id)
var strip: Control = controller.craft_price_strips[i]
var strip: Control = controller.craft_menu.price_tags[i]
if costs.is_empty():
continue
if strip.is_free():
@ -122,7 +122,7 @@ func _process(delta: float) -> bool:
% [definition.definition_id, box.position.x, box.end.x, strip.size.x])
# ...and the price sits with the button it is about, not
# adrift below the caption.
var button: Control = controller.craft_vessel_buttons[i]
var button: Control = controller.craft_menu.vessel_buttons[i]
var gap: float = strip.position.y - (button.position.y + button.size.y)
if gap > 80.0:
return _fail("%s's price sits %.0fpx below its button" \
@ -135,10 +135,10 @@ func _process(delta: float) -> bool:
% [priced, stacked])
# --- F. #147 - and the rows do not run into each other -------
for i in range(controller.craft_vessel_buttons.size()):
for j in range(i + 1, controller.craft_vessel_buttons.size()):
for part in [controller.craft_vessel_buttons,
controller.craft_vessel_labels, controller.craft_price_strips]:
for i in range(controller.craft_menu.vessel_buttons.size()):
for j in range(i + 1, controller.craft_menu.vessel_buttons.size()):
for part in [controller.craft_menu.vessel_buttons,
controller.craft_menu.vessel_labels, controller.craft_menu.price_tags]:
if i >= part.size() or j >= part.size():
continue
var a: Control = part[i]
@ -146,9 +146,9 @@ func _process(delta: float) -> bool:
if Rect2(a.position, a.size).intersects(Rect2(b.position, b.size)):
return _fail("craft entries %d and %d overlap" % [i, j])
# A price must not reach the button of the row below it.
var mine: Control = controller.craft_price_strips[i]
for k in range(controller.craft_vessel_buttons.size()):
var other: Control = controller.craft_vessel_buttons[k]
var mine: Control = controller.craft_menu.price_tags[i]
for k in range(controller.craft_menu.vessel_buttons.size()):
var other: Control = controller.craft_menu.vessel_buttons[k]
if other.position.y > mine.position.y \
and Rect2(mine.position, mine.size).intersects(
Rect2(other.position, other.size)):
@ -157,26 +157,26 @@ func _process(delta: float) -> bool:
# --- C. the hangar ---------------------------------------
controller._layout_hangar()
if controller.hangar_divider_y <= 0.0:
if controller.hangar_menu.divider_y <= 0.0:
return _fail("the hangar laid out with no divider between its halves")
var available_bottom: float = 0.0
var fleet_top: float = 1.0e9
for label in controller.hangar_available_labels:
for label in controller.hangar_menu.available_labels:
available_bottom = maxf(available_bottom, label.position.y + label.size.y)
for slot in controller.hangar_fleet_slots:
for slot in controller.hangar_menu.fleet_slots:
fleet_top = minf(fleet_top, slot.position.y)
if not (controller.hangar_divider_y > available_bottom - 40.0
and controller.hangar_divider_y < fleet_top):
if not (controller.hangar_menu.divider_y > available_bottom - 40.0
and controller.hangar_menu.divider_y < fleet_top):
return _fail("the divider at %.0f is not between the two grids (%.0f / %.0f)" \
% [controller.hangar_divider_y, available_bottom, fleet_top])
% [controller.hangar_menu.divider_y, available_bottom, fleet_top])
# Two lines of caption. The font is 24-ish, so anything under
# about 44 cannot show a second line at all.
var caption_height: float = controller.hangar_available_labels[0].size.y
var caption_height: float = controller.hangar_menu.available_labels[0].size.y
if caption_height < 44.0:
return _fail("hangar captions are %.0fpx tall - a two-word name is clipped" \
% caption_height)
print("hangar: %.0fpx captions, divider at %.0f between %.0f and %.0f" \
% [caption_height, controller.hangar_divider_y, available_bottom, fleet_top])
% [caption_height, controller.hangar_menu.divider_y, available_bottom, fleet_top])
# --- D. #143 - and the caption stays in its box --------------
# The caption is two lines before autowrap and three after it in
@ -185,8 +185,8 @@ func _process(delta: float) -> bool:
# the box now, and the box clips, so nothing can reach the next
# row however the vessel names grow.
controller._refresh_hangar()
for pair in [[controller.hangar_available_labels, controller.hangar_available_slots],
[controller.hangar_fleet_labels, controller.hangar_fleet_slots]]:
for pair in [[controller.hangar_menu.available_labels, controller.hangar_menu.available_slots],
[controller.hangar_menu.fleet_labels, controller.hangar_menu.fleet_slots]]:
for i in range(pair[0].size()):
var caption: Label = pair[0][i]
if not caption.clip_text:
@ -205,7 +205,7 @@ func _process(delta: float) -> bool:
and Rect2(caption.position, caption.size).intersects(below):
return _fail("caption \"%s\" runs into the icon below it" \
% caption.text.replace("\n", " / "))
var probe: Label = controller.hangar_available_labels[0]
var probe: Label = controller.hangar_menu.available_labels[0]
print("captions fitted to %dpx and clipped; \"%s\" fits its %.0fpx box" \
% [probe.get_theme_font_size("font_size"),
probe.text.replace("\n", " / "), probe.size.y])