Show buildings on the world map, and extractors on their planets
Forgejo #11: buildings the player has placed now appear on the world map. They are placed freely in space rather than tied to a chunk, so they get their own pass in WorldMapContent._draw() rather than riding along with the chunk markers. Each type has its own shape and colour, mirroring Building.gd's constants so a marker reads as the same building you built. Forgejo #9: a planet with an extractor built on it now shows it, in both places you look at a planet - an amber derrick on its outline in space, and a matching badge on its world-map marker. The extractor lives on PlanetSurface.tscn, a scene you are not looking at from space, so an already-mined planet was otherwise indistinguishable from an untouched one until you landed on it. The positioning steps are factored out (building_markers(), chunk_has_extractor_badge(), extractor_derrick_tip()) so headless tests can assert on them - --headless has no GPU and draws no pixels, so there is nothing to check in _draw() itself. Both features were also rendered for real via tests/screenshot.sh and looked at. extractor_derrick_tip() exists because the first version of the "derrick is not buried inside the planet" check measured the furthest of all four derrick points, which passes a derrick pointing straight into the ground: the base corners sit a half-width off the rim vertex and clear the outline on their own. Mutation-testing caught it. screenshot.sh now clears a stale /tmp/.X99-lock. A run killed mid-screenshot leaves it behind and Xvfb then refuses :99, which resurfaces later as Godot's misleading "X11 Display is not available". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b641fa5891
commit
8dd5d7b78f
13 changed files with 472 additions and 0 deletions
56
Planet.gd
56
Planet.gd
|
|
@ -20,6 +20,20 @@ extends Node2D
|
|||
|
||||
var shape_points: PackedVector2Array = PackedVector2Array()
|
||||
|
||||
# An extractor is built down on this planet's SURFACE, in a different scene
|
||||
# the player is no longer looking at, so from space nothing distinguished a
|
||||
# planet already being mined from an untouched one - you had to land to find
|
||||
# out. This is a derrick planted on the rim: the same amber the world map
|
||||
# uses for its extractor badge, so the two read as the same fact.
|
||||
const EXTRACTOR_MARKER_COLOR: Color = Color(1.0, 0.85, 0.3)
|
||||
const DERRICK_HEIGHT: float = 44.0
|
||||
const DERRICK_HALF_WIDTH: float = 16.0
|
||||
|
||||
# Resolved once in _ready() rather than polled: building an extractor happens
|
||||
# on PlanetSurface.tscn, and coming back to space rebuilds Main.tscn from
|
||||
# scratch, so a Planet node never outlives a change to its own answer.
|
||||
var shows_extractor: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
add_to_group("planets")
|
||||
|
|
@ -32,8 +46,50 @@ func _ready() -> void:
|
|||
var angle: float = (float(i) / point_count) * TAU
|
||||
var radius: float = rng.randf_range(70.0, 100.0)
|
||||
shape_points.append(Vector2(cos(angle), sin(angle)) * radius)
|
||||
shows_extractor = GameState.has_extractor_at(planet_name)
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func extractor_derrick_anchor() -> Vector2:
|
||||
# The rim vertex the derrick stands on: the shape's own topmost point,
|
||||
# rather than a fixed radius, so it sits ON the outline whatever lumpy
|
||||
# shape the seed drew instead of floating off it or sinking inside it.
|
||||
var base: Vector2 = Vector2(0.0, -100.0)
|
||||
for p in shape_points:
|
||||
if p.y < base.y:
|
||||
base = p
|
||||
return base
|
||||
|
||||
|
||||
func extractor_derrick_tip() -> Vector2:
|
||||
# Exposed separately from the polygon because "does the derrick clear the
|
||||
# planet's outline" is a question about the TIP alone. The base corners
|
||||
# sit a half-width off to either side, so they are sqrt(|base|^2 + w^2)
|
||||
# from the centre and can clear the rim on their own even when the tower
|
||||
# points straight into the ground.
|
||||
var base: Vector2 = extractor_derrick_anchor()
|
||||
var out: Vector2 = base.normalized()
|
||||
if out == Vector2.ZERO:
|
||||
out = Vector2.UP
|
||||
return base + out * DERRICK_HEIGHT
|
||||
|
||||
|
||||
func extractor_derrick_points() -> PackedVector2Array:
|
||||
var base: Vector2 = extractor_derrick_anchor()
|
||||
var out: Vector2 = base.normalized()
|
||||
if out == Vector2.ZERO:
|
||||
out = Vector2.UP
|
||||
var side: Vector2 = Vector2(-out.y, out.x)
|
||||
var tip: Vector2 = extractor_derrick_tip()
|
||||
return PackedVector2Array([
|
||||
base - side * DERRICK_HALF_WIDTH,
|
||||
tip - side * (DERRICK_HALF_WIDTH * 0.35),
|
||||
tip + side * (DERRICK_HALF_WIDTH * 0.35),
|
||||
base + side * DERRICK_HALF_WIDTH,
|
||||
])
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
NeonDraw.draw_glowing_polygon(self, shape_points, Color(0.6, 0.55, 0.5), 1.0)
|
||||
if shows_extractor:
|
||||
NeonDraw.draw_glowing_polygon(self, extractor_derrick_points(), EXTRACTOR_MARKER_COLOR, 1.0)
|
||||
|
|
|
|||
Loading…
Reference in a new issue