#147: one resource per line, and the price back under its button

Both halves of the report had the same cause: a craft cell laid out with
more slack than its row pitch had room for.

The caption box was 62px for a one-line vessel name, which pushed the price
70px clear of the button it belonged to - "far from the button they are
about". And the price was given 184px of width in a 190px column, so a
two-resource price ran out of its own box and into its neighbour's.

Prices now put each resource on its own line. Not only where they would
otherwise overflow, which was my first attempt: two resources came to 174px
in a 184px box, so it fitted - until the player was holding three figures
rather than one, and then it did not. A layout that is correct until you get
rich is not correct, and the ticket asked for the line break outright.

The caption is one line tall now with the price directly under it, and rows
are placed off a MEASURED band rather than a written-down pair of tops - the
same fix #144 needed for the build menu, and now the same code. A
centre-anchored grid under a top-anchored header has a gap between them that
is half the panel height, so it can never be a constant.

The test pins what the ticket describes rather than the numbers behind it: a
multi-resource price is stacked, its content stays inside its own box, it
sits within 80px of its button, and no craft entry overlaps another - the
price of one row into the button of the next included, which the old
geometry did by 14px whatever was priced.
This commit is contained in:
Loïc Wisniewski 2026-08-29 13:05:46 +02:00
commit 080e3bb928
3 changed files with 181 additions and 40 deletions

View file

@ -12,6 +12,9 @@ extends SceneTree
# B. #111 - and a price strip really carries the vessel's cost
# D. #143 - a hangar caption fits the box it was given and cannot draw
# outside it, so it never lands on the icon of the row below
# E. #147 - a price with several resources goes one per line and stays
# inside its own box, close to the button it is about
# F. #147 - and no craft entry overlaps another
# C. #120 - the hangar's captions have room for two lines, and there is a
# rule between what is parked and what is flying
# D. #112 - every skill node has a mark, and a node that unlocks a
@ -89,6 +92,7 @@ func _process(delta: float) -> bool:
% [controller.craft_price_strips.size(),
controller.craft_vessel_buttons.size()])
var priced: int = 0
var stacked: int = 0
for i in range(controller.craft_price_strips.size()):
var definition: Resource = VesselDefinitions.fleet()[i]
var costs: Dictionary = game_state.product_costs(definition.definition_id)
@ -99,9 +103,57 @@ func _process(delta: float) -> bool:
return _fail("%s costs %s and its strip is empty" \
% [definition.definition_id, str(costs)])
priced += 1
# --- E. #147 - a price stays inside its own box ----------
# A two-resource price used to be laid out across a strip
# narrower than it needed, so it ran off the end and into the
# vessel beside it.
if costs.size() > 1 and not strip.is_stacked():
return _fail("%s is priced in %d resources on one line - they will not fit %.0fpx" \
% [definition.definition_id, costs.size(), strip.size.x])
if costs.size() > 1:
stacked += 1
if strip.wanted_height() > strip.size.y + 0.5:
return _fail("%s's price needs %.0fpx and its box is %.0f" \
% [definition.definition_id, strip.wanted_height(), strip.size.y])
for child in strip.get_children():
var box: Rect2 = Rect2((child as Control).position, (child as Control).size)
if box.position.x < -0.5 or box.end.x > strip.size.x + 0.5:
return _fail("%s's price runs from %.0f to %.0f in a %.0fpx strip" \
% [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 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" \
% [definition.definition_id, gap])
if priced == 0:
return _fail("no vessel showed a price at all")
print("%d vessels show their price as glyphs" % priced)
if stacked == 0:
return _fail("no vessel costs more than one resource - E proves nothing")
print("%d vessels show their price as glyphs, %d of them stacked one per line" \
% [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]:
if i >= part.size() or j >= part.size():
continue
var a: Control = part[i]
var b: Control = part[j]
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]
if other.position.y > mine.position.y \
and Rect2(mine.position, mine.size).intersects(
Rect2(other.position, other.size)):
return _fail("the price under vessel %d runs into vessel %d's button" % [i, k])
print("craft grid: nothing overlapping, prices under their own buttons")
# --- C. the hangar ---------------------------------------
controller._layout_hangar()