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:
parent
78836882af
commit
6e13b6397c
42 changed files with 540 additions and 749 deletions
|
|
@ -5,14 +5,14 @@ extends SceneTree
|
|||
# Drives PlanetSetupEditor's model directly (place/move/delete/save/reload)
|
||||
# rather than through touch input - see the ticket's own note that the
|
||||
# touch layer can stay out of the headless test. Verifies:
|
||||
# 1. placing capture points and enemies updates current_setup
|
||||
# 1. placing enemies updates current_setup
|
||||
# 2. moving and deleting update it correctly, including index shifting
|
||||
# 3. saving writes a real res://PlanetSetups/<id>.tres and the registry
|
||||
# picks it up
|
||||
# 4. reopening that file in a fresh editor instance round-trips the
|
||||
# exact points/enemies, and they can be moved/deleted again
|
||||
# 5. the palette has one entry per EnemyDefinitions entry plus the
|
||||
# capture point, generated from the registry rather than hardcoded
|
||||
# enemy kind, generated from the registry rather than hardcoded
|
||||
|
||||
const TEST_SETUP_ID: String = "test_editor_setup"
|
||||
const TEST_SETUP_PATH: String = "res://PlanetSetups/test_editor_setup.tres"
|
||||
|
|
@ -37,32 +37,29 @@ func _process(delta: float) -> bool:
|
|||
if elapsed < 0.1:
|
||||
return false
|
||||
|
||||
var expected_palette_size: int = 1 + EnemyDefinitions.all().size()
|
||||
if editor._palette_buttons.size() != expected_palette_size:
|
||||
return _fail("palette has %d entries, expected 1 + %d enemy definitions" % [
|
||||
# #211 took the capture-point tile out: the palette is exactly the
|
||||
# enemy registry now.
|
||||
if editor._palette_buttons.size() != EnemyDefinitions.all().size():
|
||||
return _fail("palette has %d entries, expected %d enemy definitions" % [
|
||||
editor._palette_buttons.size(), EnemyDefinitions.all().size()
|
||||
])
|
||||
|
||||
editor.new_setup(TEST_SETUP_ID, "Test Editor Setup", "rocky")
|
||||
editor.add_capture_point(Vector2(100, 200))
|
||||
editor.add_capture_point(Vector2(-300, 50))
|
||||
editor.add_capture_point(Vector2(0, -400))
|
||||
editor.add_enemy("chaser", Vector2(100, 200))
|
||||
editor.add_enemy("chaser", Vector2(500, 500))
|
||||
editor.add_enemy("sniper", Vector2(-500, -500))
|
||||
|
||||
if editor.current_setup.capture_points.size() != 3:
|
||||
return _fail("placing 3 capture points did not land 3")
|
||||
if editor.current_setup.enemy_spawns.size() != 3:
|
||||
return _fail("placing 3 enemies did not land 3")
|
||||
|
||||
editor.move_enemy(0, Vector2(150, 250))
|
||||
if editor.current_setup.enemy_spawns[0].position != Vector2(150, 250):
|
||||
return _fail("move_enemy did not update the position")
|
||||
|
||||
editor.remove_enemy(1) # removes the second chaser
|
||||
if editor.current_setup.enemy_spawns.size() != 2:
|
||||
return _fail("placing 2 enemies did not land 2")
|
||||
|
||||
editor.move_capture_point(0, Vector2(150, 250))
|
||||
if editor.current_setup.capture_points[0] != Vector2(150, 250):
|
||||
return _fail("move_capture_point did not update the position")
|
||||
|
||||
editor.remove_enemy(0) # removes the chaser spawn
|
||||
if editor.current_setup.enemy_spawns.size() != 1:
|
||||
return _fail("remove_enemy did not shrink enemy_spawns")
|
||||
if editor.current_setup.enemy_spawns[0].enemy_id != "sniper":
|
||||
if editor.current_setup.enemy_spawns[1].enemy_id != "sniper":
|
||||
return _fail("remove_enemy removed the wrong entry (index did not shift)")
|
||||
|
||||
var result: Dictionary = editor.save_setup()
|
||||
|
|
@ -97,20 +94,19 @@ func _process(delta: float) -> bool:
|
|||
return false
|
||||
if not editor.load_setup(TEST_SETUP_ID):
|
||||
return _fail("reopening the saved setup failed")
|
||||
var points: PackedVector2Array = editor.current_setup.capture_points
|
||||
var spawns: Array = editor.current_setup.enemy_spawns
|
||||
if points.size() != 3 or points[0] != Vector2(150, 250) \
|
||||
or points[1] != Vector2(-300, 50) or points[2] != Vector2(0, -400):
|
||||
return _fail("reopened capture points did not match what was saved: %s" % [points])
|
||||
if spawns.size() != 1 or spawns[0].enemy_id != "sniper" or spawns[0].position != Vector2(-500, -500):
|
||||
if spawns.size() != 2 or spawns[0].enemy_id != "chaser" \
|
||||
or spawns[0].position != Vector2(150, 250) \
|
||||
or spawns[1].enemy_id != "sniper" \
|
||||
or spawns[1].position != Vector2(-500, -500):
|
||||
return _fail("reopened enemy spawns did not match what was saved")
|
||||
|
||||
# The reopened items can still be moved and deleted.
|
||||
editor.move_enemy(0, Vector2(-600, -600))
|
||||
if editor.current_setup.enemy_spawns[0].position != Vector2(-600, -600):
|
||||
return _fail("could not move an item after reopening")
|
||||
editor.remove_capture_point(1)
|
||||
if editor.current_setup.capture_points.size() != 2:
|
||||
editor.remove_enemy(1)
|
||||
if editor.current_setup.enemy_spawns.size() != 1:
|
||||
return _fail("could not delete an item after reopening")
|
||||
|
||||
print("TEST_SETUP_EDITOR: PASS")
|
||||
|
|
|
|||
Loading…
Reference in a new issue