#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
119 lines
5.2 KiB
GDScript
119 lines
5.2 KiB
GDScript
extends SceneTree
|
|
|
|
# Headless test: run with
|
|
# godot --headless -s res://tests/test_lab_research_reward.gd
|
|
# A harder enemy research lab should be worth more research points, and how
|
|
# hard a lab is depends on the layout authored for it - how many capture
|
|
# points, how many defenders - which the planet TYPE cannot know. So the
|
|
# reward is a per-map value set in the map editor, falling back to the
|
|
# planet type's flat rate when a setup does not express an opinion.
|
|
#
|
|
# Covers:
|
|
# A. a setup carries its own reward and it survives a save/load round trip
|
|
# B. a map's reward overrides the planet type's flat rate on conquest
|
|
# C. a setup that says nothing (0) still gets the type's rate, so every
|
|
# map authored before this existed keeps its old value
|
|
# D. the editor's control cycles the value and reports it
|
|
|
|
var game_state: Node
|
|
var editor: Node
|
|
var stage: int = 0
|
|
var elapsed: float = 0.0
|
|
|
|
|
|
func _initialize() -> void:
|
|
game_state = root.get_node("GameState")
|
|
game_state.reset_new_game()
|
|
# #108: reset_new_game() arms the prologue, and the prologue opens with a
|
|
# convoy rather than the game's own starting fleet. This test is about
|
|
# what the GAME starts from, which is where the prologue hands over -
|
|
# see test_intro_scene.gd for the prologue itself.
|
|
game_state.intro_active = false
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
elapsed += delta
|
|
match stage:
|
|
0:
|
|
# --- A. the field exists and round-trips ---------------------
|
|
var setup: Resource = load("res://surface/PlanetSetup.gd").new()
|
|
setup.setup_id = "reward_probe"
|
|
setup.display_name = "Reward Probe"
|
|
setup.surface_profile_id = "rocky"
|
|
setup.research_point_reward = 5
|
|
var path: String = "user://test_reward_probe.tres"
|
|
if ResourceSaver.save(setup, path) != OK:
|
|
return _fail("could not save a setup carrying a research reward")
|
|
var reloaded: Resource = ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_IGNORE)
|
|
if reloaded == null or int(reloaded.research_point_reward) != 5:
|
|
return _fail("the reward did not survive a save/load round trip")
|
|
DirAccess.remove_absolute(ProjectSettings.globalize_path(path))
|
|
print("a setup carries its own reward (%d) across a save/load" % reloaded.research_point_reward)
|
|
|
|
# --- B. the map's reward beats the planet type's rate --------
|
|
# A research_lab planet's own definition pays a flat 1.
|
|
var flat_rate: int = int(load("res://planets/ResearchLabPlanetDefinition.tres").conquest_research_points)
|
|
game_state.research_points = 0
|
|
game_state.register_planet_garrison("hard_lab", 2, "research_lab", 6)
|
|
game_state.mark_garrison_enemy_destroyed("hard_lab")
|
|
game_state.mark_garrison_enemy_destroyed("hard_lab")
|
|
if game_state.research_points != 6:
|
|
return _fail("a hard lab authored at 6 points awarded %d" % game_state.research_points)
|
|
if flat_rate >= 6:
|
|
return _fail("the planet type's flat rate (%d) is not below the authored one - this test proves nothing" % flat_rate)
|
|
print("a hard lab authored at 6 pays 6, over the planet type's flat %d" % flat_rate)
|
|
|
|
# --- C. silence still means the type's rate ------------------
|
|
game_state.research_points = 0
|
|
game_state.register_planet_garrison("plain_lab", 1, "research_lab", 0)
|
|
game_state.mark_garrison_enemy_destroyed("plain_lab")
|
|
if game_state.research_points != flat_rate:
|
|
return _fail("a setup with no authored reward paid %d, expected the type's %d" \
|
|
% [game_state.research_points, flat_rate])
|
|
print("a setup with no opinion still pays the planet type's %d" % flat_rate)
|
|
|
|
# A harder map must never be worth LESS than an easier one.
|
|
if 6 <= flat_rate:
|
|
return _fail("authoring a harder lab did not raise its worth")
|
|
|
|
editor = load("res://surface/PlanetSetupEditor.tscn").instantiate()
|
|
root.add_child(editor)
|
|
current_scene = editor
|
|
elapsed = 0.0
|
|
stage = 1
|
|
return false
|
|
1:
|
|
# --- D. the editor can set it --------------------------------
|
|
if elapsed < 0.2:
|
|
return false
|
|
editor.new_setup("reward_edit", "Reward Edit", "rocky")
|
|
var seen: Array = []
|
|
for i in range(editor.REWARD_OPTIONS.size()):
|
|
seen.append(int(editor.current_setup.research_point_reward))
|
|
editor._on_reward_pressed()
|
|
# Cycling the whole list must come back round to where it began.
|
|
if int(editor.current_setup.research_point_reward) != seen[0]:
|
|
return _fail("cycling every reward option did not return to the start")
|
|
if seen.size() != editor.REWARD_OPTIONS.size() or seen.max() <= 0:
|
|
return _fail("the reward control did not offer a range of values: %s" % [seen])
|
|
editor.current_setup.research_point_reward = 3
|
|
editor._refresh_reward_label()
|
|
if not "3" in editor.reward_value_label.text:
|
|
return _fail("the editor does not report the chosen reward: '%s'" % editor.reward_value_label.text)
|
|
editor.current_setup.research_point_reward = 0
|
|
editor._refresh_reward_label()
|
|
if not "DEFAULT" in editor.reward_value_label.text:
|
|
return _fail("the editor does not distinguish 'use the planet type's rate': '%s'" \
|
|
% editor.reward_value_label.text)
|
|
print("the map editor cycles %s and reports the choice" % [seen])
|
|
|
|
print("TEST_LAB_RESEARCH_REWARD: PASS")
|
|
quit(0)
|
|
return true
|
|
return false
|
|
|
|
|
|
func _fail(message: String) -> bool:
|
|
print("TEST_LAB_RESEARCH_REWARD: FAIL (%s)" % message)
|
|
quit(1)
|
|
return true
|