139 lines
3.9 KiB
GDScript
139 lines
3.9 KiB
GDScript
class_name MainMenu
|
|
extends Control
|
|
|
|
signal load_game_request(save_data: SaveData, slot_index: int)
|
|
signal quit_request
|
|
|
|
const USER_SETTINGS_PATH: String = "user://settings.ini"
|
|
const SAVES_DIR: String = "user://saves/"
|
|
const SAVE_DATA_PATH: String = SAVES_DIR + "%s/save_data.tres"
|
|
|
|
@onready var continue_button: Button = %ContinueButton
|
|
@onready var load_button: Button = %LoadButton
|
|
@onready var new_game_button: Button = %NewGameButton
|
|
@onready var options_button: Button = %OptionsButton
|
|
@onready var quit_button: Button = %QuitButton
|
|
|
|
@onready var saves_scroll_container: ScrollContainer = %SavesScrollContainer
|
|
@onready var saves_container: VBoxContainer = %SavesContainer
|
|
@onready var settings_menu: SettingsMenu = %SettingsMenu
|
|
|
|
|
|
static func get_save_slots() -> PackedInt32Array:
|
|
if not DirAccess.dir_exists_absolute(SAVES_DIR):
|
|
return []
|
|
|
|
var dirs: PackedStringArray = DirAccess.get_directories_at(SAVES_DIR)
|
|
var index: int = 0
|
|
|
|
while index < dirs.size():
|
|
var dir_name: String = dirs[index]
|
|
if dir_name.is_valid_int() and not (dir_name.begins_with("+") or dir_name.begins_with("-")):
|
|
index += 1
|
|
else:
|
|
dirs.remove_at(index)
|
|
|
|
return type_convert(dirs, TYPE_PACKED_INT32_ARRAY)
|
|
|
|
|
|
static func get_unique_save_slot_index() -> int:
|
|
var index: int = 0
|
|
var taken_slots: PackedInt32Array = get_save_slots()
|
|
|
|
while taken_slots.has(index):
|
|
index += 1
|
|
|
|
return index
|
|
|
|
|
|
static func get_save_path(slot_index: int) -> String:
|
|
return SAVE_DATA_PATH % slot_index
|
|
|
|
|
|
func _ready() -> void:
|
|
continue_button.pressed.connect(_on_continue_pressed)
|
|
load_button.pressed.connect(_on_load_pressed)
|
|
new_game_button.pressed.connect(_on_new_game_pressed)
|
|
options_button.pressed.connect(_on_options_pressed)
|
|
quit_button.pressed.connect(_on_quit_pressed)
|
|
|
|
settings_menu.close_request.connect(_on_settings_close_request)
|
|
|
|
continue_button.visible = has_save()
|
|
|
|
|
|
func has_save() -> bool:
|
|
var config: ConfigFile = Utils.load_config(USER_SETTINGS_PATH)
|
|
return config.has_section_key("save", "last_slot")
|
|
|
|
|
|
func populate_save_entries() -> void:
|
|
for child: Node in saves_container.get_children():
|
|
child.queue_free()
|
|
|
|
for save_slot: int in get_save_slots():
|
|
var save_path: String = get_save_path(save_slot)
|
|
var button := SaveEntryButton.construct_save_entry_button(saves_container, save_path, save_slot)
|
|
button.pressed.connect(_on_save_entry_pressed.bind(save_slot))
|
|
|
|
|
|
func _on_continue_pressed() -> void:
|
|
var config: ConfigFile = Utils.load_config(USER_SETTINGS_PATH)
|
|
var slot: int = config.get_value("save", "last_slot", 0)
|
|
var path: String = get_save_path(slot)
|
|
|
|
if not FileAccess.file_exists(path):
|
|
slot = 0 # Try the first save slot.
|
|
path = get_save_path(slot)
|
|
if not FileAccess.file_exists(path):
|
|
_on_new_game_pressed()
|
|
return
|
|
|
|
config.set_value("save", "last_slot", slot)
|
|
config.save(USER_SETTINGS_PATH)
|
|
|
|
var save_data: SaveData = load(path)
|
|
load_game_request.emit(save_data, slot)
|
|
|
|
|
|
func _on_load_pressed() -> void:
|
|
saves_scroll_container.show()
|
|
populate_save_entries()
|
|
|
|
|
|
func _on_new_game_pressed() -> void:
|
|
var save_data: SaveData = Game.INITIAL_SAVE_DATA.duplicate()
|
|
var slot_index: int = get_unique_save_slot_index()
|
|
load_game_request.emit(save_data, slot_index)
|
|
|
|
var config: ConfigFile = Utils.load_config(USER_SETTINGS_PATH)
|
|
config.set_value("save", "last_slot", slot_index)
|
|
config.save(USER_SETTINGS_PATH)
|
|
|
|
|
|
func _on_options_pressed() -> void:
|
|
settings_menu.show()
|
|
|
|
|
|
func _on_quit_pressed() -> void:
|
|
quit_request.emit()
|
|
|
|
|
|
func _on_save_entry_pressed(save_slot: int) -> void:
|
|
var config: ConfigFile = Utils.load_config(USER_SETTINGS_PATH)
|
|
config.set_value("save", "last_slot", save_slot)
|
|
config.save(USER_SETTINGS_PATH)
|
|
|
|
var save_path: String = get_save_path(save_slot)
|
|
|
|
if not FileAccess.file_exists(save_path):
|
|
_on_new_game_pressed()
|
|
return
|
|
|
|
var save_data: SaveData = load(save_path)
|
|
load_game_request.emit(save_data, save_slot)
|
|
|
|
|
|
func _on_settings_close_request() -> void:
|
|
settings_menu.hide()
|