150 lines
7.9 KiB
GDScript
150 lines
7.9 KiB
GDScript
extends Node
|
|
|
|
var failures: Array[String] = []
|
|
|
|
func check(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append(message)
|
|
push_error(message)
|
|
|
|
func _ready() -> void:
|
|
run.call_deferred()
|
|
|
|
func run() -> void:
|
|
GameState.start_new_run()
|
|
var game: Node = load("res://scenes/game/game.tscn").instantiate()
|
|
get_tree().root.add_child(game)
|
|
get_tree().current_scene = game
|
|
await get_tree().process_frame
|
|
await get_tree().process_frame
|
|
game.set_physics_process(false)
|
|
var ship: Node = game.get_node("PlayerShip")
|
|
ship.set_physics_process(false)
|
|
var inventory: Node = ship.get_node("ShipInventory")
|
|
GameState.captain.credits = 4321
|
|
GameState.captain.minerals.iron = 321
|
|
GameState.captain.expedition.alien_skills["general"] = true
|
|
GameState.captain.expedition.crew["cabin_1"] = {"name":"Test","level":4}
|
|
GameState.captain.skill_offers.assign(["electrician", "lucky"])
|
|
GameState.captain.skill_cooldowns["electrician"] = 12.0
|
|
inventory.ammunition = 123
|
|
inventory.unlocked_weapon_slots = 2
|
|
inventory.weapon_slots[0].damage_min = 13.5
|
|
inventory.weapon_slots[0].damage_max = 29.25
|
|
inventory.weapon_slots[0].special_orbs.assign(["piercing"])
|
|
ship.position = Vector2(840,610)
|
|
ship.hull = 37.0
|
|
GameState.cleared_systems[GameState.system_level] = true
|
|
GameState.cleared_systems[2] = true
|
|
GameState.explored_pois["%d:1" % GameState.system_seed] = true
|
|
GameState.captain.skill_durations["reactor_overload"] = 4.0
|
|
inventory.extension_cooldowns["test"] = 5.0
|
|
GameState.captain.expedition.laboratory_project = "machine_gun"
|
|
GameState.captain.expedition.laboratory_duration = 600
|
|
GameState.captain.expedition.laboratory_remaining = 387.5
|
|
GameState.captain.expedition.alien_project = "hull"
|
|
GameState.captain.expedition.alien_duration = 600
|
|
GameState.captain.expedition.alien_remaining = 245.25
|
|
var enemies_before: int = game.get_remaining_enemies()
|
|
check(GameState.save_game() == OK,"save writes successfully")
|
|
check(GameState.has_save(),"continue detects valid save")
|
|
var saved := GameState.SAVES.read_save()
|
|
check(saved.captain.credits == 4321,"captain credits serialized")
|
|
check(saved.inventory.ammunition == 123,"ammunition serialized")
|
|
GameState.captain.credits = 8765
|
|
check(GameState.save_game() == OK,"second save replaces first")
|
|
check(GameState.SAVES.read_save(GameState.SAVES.BACKUP).captain.credits == 4321,"backup retains previous save")
|
|
game.free()
|
|
check(GameState.continue_game(),"save restores state")
|
|
check(GameState.captain.credits == 8765,"latest credits restored")
|
|
check(GameState.captain.expedition.laboratory_project == "machine_gun" and is_equal_approx(GameState.captain.expedition.laboratory_remaining,387.5),"SAVE preserves laboratory project and exact remaining time")
|
|
check(GameState.captain.expedition.alien_project == "hull" and is_equal_approx(GameState.captain.expedition.alien_remaining,245.25),"SAVE preserves alien project and exact remaining time")
|
|
check(GameState.captain.expedition.crew.cabin_1.level == 4,"crew restored")
|
|
check(GameState.captain.expedition.alien_skills.general,"research restored")
|
|
check(not GameState.cleared_systems.has(GameState.system_level),"current level encounters restart")
|
|
check(GameState.cleared_systems.has(2),"other level progress retained")
|
|
check(not GameState.explored_pois.has("%d:1" % GameState.system_seed),"current level exploration restarts")
|
|
game = load("res://scenes/game/game.tscn").instantiate()
|
|
get_tree().root.add_child(game)
|
|
get_tree().current_scene = game
|
|
await get_tree().process_frame
|
|
await get_tree().process_frame
|
|
ship = game.get_node("PlayerShip")
|
|
inventory = ship.get_node("ShipInventory")
|
|
check(inventory.ammunition == 123,"inventory restored into live ship")
|
|
check(inventory.unlocked_weapon_slots == 2,"unlocked slots restored")
|
|
check(is_equal_approx(inventory.weapon_slots[0].damage_min,13.5),"individual item damage restored")
|
|
check(is_equal_approx(inventory.weapon_slots[0].damage_max,29.25),"individual item roll restored")
|
|
check("piercing" in inventory.weapon_slots[0].special_orbs,"item orb effects restored")
|
|
check(ship.position.distance_to(game.system_data.player_start) < 1,"load starts at level spawn")
|
|
check(is_equal_approx(ship.hull,ship.max_hull),"load restores full hull")
|
|
check(game.get_remaining_enemies() == enemies_before,"enemy population restored")
|
|
check(GameState.captain.skill_cooldowns.is_empty(),"load clears skill cooldowns")
|
|
check(GameState.captain.skill_durations.is_empty(),"load clears temporary effects")
|
|
check(inventory.extension_cooldowns.is_empty(),"load clears extension cooldowns")
|
|
# Surface-save normalization must leave the active live expedition untouched.
|
|
var progress: Resource = GameState.captain.expedition
|
|
progress.active = true
|
|
progress.cargo = {"iron":7}
|
|
progress.cargo_credits = 23
|
|
check(GameState.save_game() == OK,"surface save succeeds")
|
|
check(progress.active and progress.cargo.get("iron",0) == 7,"surface save does not alter live cargo")
|
|
saved = GameState.SAVES.read_save()
|
|
check(not saved.captain.expedition.active,"surface save resumes in orbit")
|
|
check(saved.captain.minerals.iron == 328,"surface cargo retained")
|
|
check(GameState.captain.minerals.iron == 321,"snapshot does not modify live captain")
|
|
progress.active = false
|
|
for code in GameSettings.LOCALES:
|
|
GameSettings.locale = code
|
|
GameSettings.apply()
|
|
check(not str(TranslationServer.translate("Zapisz grę")).is_empty(),"language available: "+code)
|
|
if code != "pl":
|
|
check(str(TranslationServer.translate("Zapisz grę")) != "Zapisz grę","menu is translated: "+code)
|
|
check(str(TranslationServer.translate("Kredyty: 123")) != "Kredyty: 123","formatted strings translated: "+code)
|
|
else:
|
|
check(str(TranslationServer.translate("Zapisz grę")) == "Zapisz grę","Polish menu stays Polish")
|
|
check(str(TranslationServer.translate("Kredyty: 123")) == "Kredyty: 123","Polish formatted text stays Polish")
|
|
GameSettings.locale = "en"
|
|
GameSettings.apply()
|
|
check(str(TranslationServer.translate("Kredyty: 123")) == "Credits: 123","formatted numeric value retained")
|
|
check(str(TranslationServer.translate("Działko plazmowe · poziom 3")) == "Plasma cannon · level 3","formatted phrase and captured item name translated")
|
|
GameSettings.volume = 0.0
|
|
GameSettings.apply()
|
|
check(AudioServer.is_bus_mute(0),"master mute applied")
|
|
check(GameSettings.save_settings() == OK,"settings saved")
|
|
var config := ConfigFile.new()
|
|
check(config.load(GameSettings.PATH) == OK,"settings readable from disk")
|
|
check(config.get_value("language","locale") == "en","language persisted")
|
|
check(is_zero_approx(config.get_value("audio","master")),"volume persisted")
|
|
var options := CanvasLayer.new()
|
|
options.set_script(load("res://scripts/ui/options_dialog.gd"))
|
|
get_tree().root.add_child(options)
|
|
check(options.get("_language").item_count == 5,"all five languages in options")
|
|
options._close()
|
|
await get_tree().process_frame
|
|
var pause_menu := game.get_node("SessionMenu")
|
|
var escape := InputEventKey.new()
|
|
escape.keycode = KEY_ESCAPE
|
|
escape.pressed = true
|
|
Input.parse_input_event(escape)
|
|
await get_tree().process_frame
|
|
check(get_tree().paused,"session menu pauses game")
|
|
check(pause_menu._save(),"manual save button works")
|
|
pause_menu._open_options()
|
|
check(not pause_menu._dialog.visible,"options temporarily hides pause dialog")
|
|
pause_menu._options._close()
|
|
await get_tree().process_frame
|
|
check(pause_menu._dialog.visible and get_tree().paused,"closing options restores paused menu")
|
|
pause_menu._close()
|
|
check(not get_tree().paused,"session menu resumes game")
|
|
# Damaged primary file must fall back to the last verified backup.
|
|
var file := FileAccess.open(GameState.SAVES.PATH,FileAccess.WRITE)
|
|
file.store_string("corrupted test save")
|
|
file.close()
|
|
check(GameState.has_save(),"backup offered when primary corrupted")
|
|
check(GameState.continue_game(),"corrupted primary falls back to backup")
|
|
game.queue_free()
|
|
await get_tree().process_frame
|
|
print("SAVE_SETTINGS_TEST: ", "PASS" if failures.is_empty() else "FAIL", " (",failures.size()," failures)")
|
|
get_tree().quit(0 if failures.is_empty() else 1)
|