extends Node const CAPTAIN_PROGRESS := preload("res://scripts/captain/captain_progress.gd") var captain: CaptainProgress = CAPTAIN_PROGRESS.new() var selected_ship_path: String = "" var restart_inventory: Dictionary = {} var system_level: int = 1 var system_seed: int = 0 var active_distant_map: Dictionary = {} var distant_home: Dictionary = {} var return_to_freighter := false var distant_warp_arrival := false var hull_bastion_used := false var highest_system := 1 var system_seeds: Dictionary = {} var cleared_systems: Dictionary = {} var _production_signal_time := 0.0 var explored_pois: Dictionary = {} var asteroid_retry_seeds: Dictionary = {} var exploration_wreck_bonuses: Dictionary = {} var hud_panel_state: Dictionary = {} const SAVES := preload("res://scripts/game/save_service.gd") var _autosave_time := 0.0 var last_save_error: Error = OK func save_game() -> Error: last_save_error = SAVES.write(self, get_tree().current_scene) return last_save_error func has_save() -> bool: return SAVES.available() func continue_game() -> bool: return SAVES.restore_state(self) func save_named_game(save_name: String, slot_id: String = "") -> Error: if save_name.strip_edges().is_empty(): return ERR_INVALID_PARAMETER last_save_error = SAVES.write(self, get_tree().current_scene, save_name, slot_id) return last_save_error func load_game(slot_id: String) -> bool: return SAVES.restore_state(self, slot_id) func depart_distant(map_id: String) -> bool: if not active_distant_map.is_empty() or not captain.expedition.distant_maps.has(map_id): return false var map: Dictionary = captain.expedition.distant_maps[map_id] var cost: int = preload("res://scripts/planets/distant_expeditions.gd").fuel_cost(map) if captain.expedition.deuter < cost: return false distant_home = {"level":system_level,"seed":system_seed,"hull_bastion_used":hull_bastion_used} hull_bastion_used = false active_distant_map = map.duplicate(true) captain.expedition.distant_maps.erase(map_id) captain.expedition.deuter -= cost system_level = int(map.level) system_seed = int(map.seed) captain.expedition.emit_changed() return true func restore_distant_home() -> void: if distant_home.is_empty(): return system_level = int(distant_home.level) system_seed = int(distant_home.seed) hull_bastion_used = bool(distant_home.get("hull_bastion_used",false)) active_distant_map.clear() distant_home.clear() distant_warp_arrival = false func create_system_seed() -> int: var rng := RandomNumberGenerator.new() rng.randomize() return maxi(1, rng.randi()) func reset_current_system_exploration() -> void: # Keep the system and rewards, but regenerate asteroid placement and minerals. var previous: int = asteroid_retry_seeds.get(system_seed, system_seed) var next_seed := create_system_seed() while next_seed == previous: next_seed = create_system_seed() asteroid_retry_seeds[system_seed] = next_seed var prefix := "%d:" % system_seed for id in explored_pois.keys(): if str(id).begins_with(prefix): explored_pois.erase(id) func start_new_run() -> void: _autosave_time = 0.0 hull_bastion_used = false captain = CAPTAIN_PROGRESS.new() system_level = 1 highest_system = 1 active_distant_map.clear() distant_home.clear() return_to_freighter = false distant_warp_arrival = false system_seeds.clear() cleared_systems.clear() _production_signal_time = 0 system_seed = create_system_seed() restart_inventory.clear() explored_pois.clear() asteroid_retry_seeds.clear() exploration_wreck_bonuses.clear() hud_panel_state.clear() func _ready() -> void: process_mode = Node.PROCESS_MODE_ALWAYS var game_window := get_tree().root game_window.content_scale_size = Vector2i(1280, 720) game_window.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS game_window.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND func remember_system() -> void: highest_system = maxi(highest_system, system_level) system_seeds[system_level] = system_seed func can_visit_system(level: int) -> bool: return level >= 1 and level <= highest_system and level <= 120 func seed_for_system(level: int) -> int: if not system_seeds.has(level): system_seeds[level] = create_system_seed() return int(system_seeds[level]) func _process(delta: float) -> void: advance_play_time(delta, get_tree().current_scene) var scene := get_tree().current_scene if scene == null or not scene.has_node("PlayerShip"): return _autosave_time += delta if _autosave_time >= 60.0 and not captain.expedition.active: _autosave_time = 0.0 save_game() func advance_play_time(delta: float, scene: Node) -> void: if scene == null or not scene.has_node("PlayerShip"): return if bool(scene.get_node("PlayerShip").get("_is_destroyed")): return var expedition := scene.get_node_or_null("PlanetExpeditions") var location_open := expedition != null and is_instance_valid(expedition.screen) if get_tree().paused and not location_open: return var researching := preload("res://scripts/planets/laboratory.gd").advance(captain.expedition,delta) var alien_was_active: bool = not captain.expedition.alien_project.is_empty() researching = preload("res://scripts/planets/alien_research.gd").advance(captain.expedition,delta) or researching if alien_was_active and captain.expedition.alien_project.is_empty(): captain.emit_changed() var inventory := scene.get_node_or_null("PlayerShip/ShipInventory") if inventory != null: inventory._recalculate_ship_stats() var network := preload("res://scripts/planets/mining_network.gd") if network.advance(captain.expedition, delta) <= 0 and not researching: return _production_signal_time += delta if _production_signal_time >= 1.0: _production_signal_time = fmod(_production_signal_time, 1.0) captain.expedition.emit_changed()