Take planets by killing what defends them

#211 conquest is the fight now: a planet registers the garrison its setup
authors, each defender's own death counts against it, and the last one takes
the world. The capture points - stand in a ring, wait out a timer, once per
ring - are gone, along with the editor palette that placed them.
#212 conquest opens a dialog on the surface naming the research points
recovered; the award travels with the signal, after it is banked.
#209 the prologue's charted sectors go with the breach, so the map the
survivors keep is of where they now are - and "chart 30 sectors" is no
longer complete before they have flown anywhere.
#218 enemy variety is gated on the FLEET, not on wave strength: a starting
fleet meets chasers only at any wave number, and each vessel past three
opens one more kind.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
Loïc Wisniewski 2026-09-05 13:31:25 +02:00
commit 6e13b6397c
42 changed files with 540 additions and 749 deletions

View file

@ -1,12 +1,14 @@
class_name PlanetSetupHost
extends Node2D
# Instantiates the contents of a PlanetSetup onto a landed surface: one
# CapturePoint per authored point - registering/restoring conquest progress
# through GameState so re-landing on a partly-taken planet keeps its
# progress - and one enemy per authored spawn.
# Instantiates the contents of a PlanetSetup onto a landed surface: one enemy
# per authored spawn, registered with GameState as the planet's garrison so
# that killing the last of them takes the planet.
#
# #211 removed the capture points this used to place alongside them. Holding a
# ring for four seconds, once per ring, was a second task laid on top of the
# fight the player had already won; conquest is the fight now.
const CAPTURE_POINT_SCENE: PackedScene = preload("res://surface/CapturePoint.tscn")
const ENEMY_SCENE: PackedScene = preload("res://enemies/Enemy.tscn")
var setup: Resource
@ -19,42 +21,26 @@ func apply_setup(new_setup: Resource) -> void:
if setup == null:
return
GameState.register_capture_points(GameState.planet_id, setup.capture_points.size(),
GameState.planet_definition_id, int(setup.research_point_reward))
for i in range(setup.capture_points.size()):
_add_capture_point(i, setup.capture_points[i])
if _garrison_is_defeated():
# Registered with the count about to be placed, every landing. A planet
# already taken keeps that status and gets no garrison at all.
GameState.register_planet_garrison(GameState.planet_id,
setup.enemy_spawns.size(), GameState.planet_definition_id,
int(setup.research_point_reward))
if GameState.is_planet_conquered(GameState.planet_id):
return
for spawn in setup.enemy_spawns:
_add_enemy(spawn)
# A conquered planet stays conquered. Its garrison was destroyed to take it,
# so re-landing must not quietly restore it - the capture points already come
# back marked captured, and enemies standing on a planet the player owns read
# as the conquest having been undone.
#
# Guarded on there being capture points to take, not on the conquered flag
# alone: register_capture_points() treats a setup with none as vacuously
# conquered (see PlanetSurfaceController's note on unregistered planets), and
# a setup that authored enemies but no capture points is a garrison nobody
# can ever have beaten. Suppressing those would delete them on first sight.
func _garrison_is_defeated() -> bool:
return not setup.capture_points.is_empty() \
and GameState.is_planet_conquered(GameState.planet_id)
func _add_capture_point(index: int, at: Vector2) -> void:
var point: Node = CAPTURE_POINT_SCENE.instantiate()
point.point_index = index
point.position = at
add_child(point)
if GameState.is_point_captured(GameState.planet_id, index):
point.mark_captured()
func _add_enemy(spawn: Resource) -> void:
var enemy: Node = ENEMY_SCENE.instantiate()
enemy.enemy_id = spawn.enemy_id
enemy.position = spawn.position
# The planet is captured by the count reaching zero, so the tally is bound
# to the enemy's own death rather than to whatever killed it. Bound to the
# id captured NOW: the player may have left the surface by the time a
# straggler dies, and the planet that was being fought over is this one.
var planet_key: String = GameState.planet_id
enemy.destroyed.connect(func():
GameState.mark_garrison_enemy_destroyed(planet_key))
add_child(enemy)