Randoloot/tests/levels/exploration_death_restart_test.gd
2026-10-17 16:51:07 +02:00

76 lines
3.4 KiB
GDScript

extends Node
const GAME := preload("res://scenes/game/game.tscn")
func pois(game: Node) -> Array[Node]:
var found: Array[Node] = []
for poi in get_tree().get_nodes_in_group("exploration_pois"):
if game.is_ancestor_of(poi) and not poi.is_queued_for_deletion():
found.append(poi)
return found
func freeze(game: Node) -> void:
game.set_physics_process(false)
game.get_node("PlayerShip").set_physics_process(false)
game.get_node("PlayerShip/WeaponController").set_physics_process(false)
for enemy in get_tree().get_nodes_in_group("enemies"):
enemy.set_physics_process(false)
func _ready() -> void:
await get_tree().process_frame
for rank in range(4):
GameState.start_new_run()
GameState.system_seed = 987654
GameState.captain.skills["miner"] = rank
GameState.captain.skills["explorer"] = 2
GameState.explored_pois["other-system:0"] = true
var game := GAME.instantiate() as Node2D
get_tree().root.add_child(game)
get_tree().current_scene = game
freeze(game)
var before := {}
for poi in pois(game):
before[poi.get("poi_id")] = {"kind": poi.get("kind"), "position": poi.position, "mineral": poi.get("_mineral")}
assert(before.values().filter(func(p): return p["kind"] == "wreck").size() >= 2)
assert(before.values().filter(func(p): return p["kind"] == "asteroid").size() >= 6)
for poi in pois(game):
if poi.get("kind") in ["asteroid", "wreck"]:
# Test reward retention independently of the debris renderer.
assert(poi.call("claim"))
var minerals_before := GameState.captain.minerals.duplicate()
var seed_before := GameState.system_seed
var bonus_before := int(GameState.exploration_wreck_bonuses[seed_before])
var ship := game.get_node("PlayerShip")
var inventory := ship.get_node("ShipInventory") as ShipInventory
inventory.energy_banks = 7
ship.call("_destroy_ship")
assert(ship.get("_is_destroyed"))
var old_instance_id := game.get_instance_id()
ship.call("_restart_level_after_destruction")
await get_tree().process_frame
await get_tree().process_frame
var restarted := get_tree().current_scene
assert(is_instance_valid(restarted) and restarted.get_instance_id() != old_instance_id)
freeze(restarted)
var after := pois(restarted)
assert(after.size() == before.size(), "Death must restore all asteroids and wrecks; miner rank %d: %d vs %d" % [rank, after.size(), before.size()])
for poi in after:
var original: Dictionary = before[poi.get("poi_id")]
assert(original["kind"] == poi.get("kind"))
if poi.get("kind") == "asteroid":
assert(original["position"] != poi.position)
elif int(str(poi.get("poi_id")).get_slice(":", 1)) < 1000:
assert(original["position"] == poi.position)
assert(GameState.asteroid_retry_seeds.has(seed_before))
assert(GameState.captain.minerals == minerals_before)
assert(GameState.captain.get_skill_rank("miner") == rank)
assert(GameState.system_seed == seed_before)
assert(GameState.exploration_wreck_bonuses[seed_before] == bonus_before)
assert(GameState.explored_pois.has("other-system:0"))
assert(restarted.get_node("PlayerShip/ShipInventory").energy_banks == 7)
get_tree().current_scene = self
restarted.queue_free()
await get_tree().process_frame
print("EXPLORATION_DEATH_RESTART_TEST: PASS (actual death and scene reload at miner ranks 0/1/2/3, exhausted boards restored, rerolled asteroid positions/minerals, explorer snapshot, rewards/equipment retained)")
get_tree().quit()