finish implementing saving and loading
This commit is contained in:
parent
bdf78a55c0
commit
022053a078
|
|
@ -2,10 +2,6 @@ extends RoomTemplate
|
|||
|
||||
signal ini_room
|
||||
|
||||
@onready var mask_memento: CollectableUi = %MaskMemento.ui
|
||||
@onready var clothes_memento: CollectableUi = %ClothesMemento.ui
|
||||
@onready var comic_memento: CollectableUi = %ComicMemento.ui
|
||||
@onready var ceiling_memento: CollectableUi = %CeilingMemento.ui
|
||||
@onready var board_trigger: InteractiveSprite = %MindBoard
|
||||
@onready var door_trigger: InteractiveSprite = %DoorTrigger
|
||||
@onready var card_board: CardBoard = %Board
|
||||
|
|
@ -13,17 +9,18 @@ signal ini_room
|
|||
|
||||
func start_room():
|
||||
save_game = State.active_save_game
|
||||
##TODO: make sure this is done automagically!
|
||||
# Setting Memento user interface elemnts as collected based on the savegame.
|
||||
#mask_memento.collected = save_game.mementos_complete && 1 >> Scenes.id.YOUTH_CHILDHOOD > 0
|
||||
#clothes_memento.collected = save_game.mementos_complete && 1 >> Scenes.id.YOUTH_JUI_JUTSU > 0
|
||||
#comic_memento.collected = save_game.mementos_complete && 1 >> Scenes.id.YOUTH_VOICE_TRAINING > 0
|
||||
#ceiling_memento.collected = save_game.mementos_complete && 1 >> Scenes.id.YOUTH_DRAEVEN > 0
|
||||
|
||||
save_game.current_room = State.rooms.YOUTH
|
||||
Scenes.completed_sequences = save_game.mementos_complete
|
||||
Scenes.started_sequences = save_game.mementos_complete
|
||||
card_board.initialise_from_save(save_game)
|
||||
$logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
|
||||
ini_room.emit()
|
||||
if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN):
|
||||
Scenes.start_sequence(Scenes.id.YOUTH_DRAEVEN)
|
||||
State.queue_for_stage(%PlayerController)
|
||||
else:
|
||||
State.pass_stage_to(%PlayerController)
|
||||
%LightAnimation.lights_on()
|
||||
|
||||
|
||||
func get_ready():
|
||||
|
|
@ -43,11 +40,11 @@ func _ready():
|
|||
|
||||
func pull_save_state(save: SaveGame) -> void:
|
||||
save.board_state = card_board.get_save_dict()
|
||||
save.current_room = State.rooms.YOUTH
|
||||
save.mementos_complete = Scenes.completed_sequences
|
||||
|
||||
func _on_scene_finished(id: int, _repeat:bool):
|
||||
# need to properly implement saving and loading
|
||||
return
|
||||
save_game.mementos_complete &= 1 << id
|
||||
await get_tree().create_timer(3).timeout
|
||||
save_room()
|
||||
|
||||
#FIXME forgot to comment what this means, just marking it for removal
|
||||
|
|
|
|||
|
|
@ -1201,10 +1201,10 @@ func _ready() -> void:
|
|||
Scenes.scene_finished.connect(lights_on)
|
||||
Scenes.scene_starting.connect(lights_off)
|
||||
|
||||
func lights_off(_id: int, _repeat: bool):
|
||||
func lights_off(_id: int = -1, _repeat: bool = false):
|
||||
queue(\"lights_out\")
|
||||
|
||||
func lights_on(_id: int, _repeat: bool):
|
||||
func lights_on(_id: int = -1, _repeat: bool = false):
|
||||
queue(\"light_up\")
|
||||
"
|
||||
|
||||
|
|
@ -1420,6 +1420,7 @@ script = ExtResource("1_aitp0")
|
|||
|
||||
[node name="PlayerController" parent="logic" groups=["camera_owner"] instance=ExtResource("3_foj4y")]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 4
|
||||
transform = Transform3D(0.686123, 0, 0.727485, 0, 1, 0, -0.727485, 0, 0.686123, 0.63, 0, 0.925)
|
||||
|
||||
[node name="colission" type="Node3D" parent="logic"]
|
||||
|
|
@ -2088,7 +2089,8 @@ shadow_enabled = true
|
|||
omni_range = 2.17653
|
||||
omni_attenuation = 1.41421
|
||||
|
||||
[node name="light_animation" type="AnimationPlayer" parent="visuals/lights" groups=["scene_actors"]]
|
||||
[node name="LightAnimation" type="AnimationPlayer" parent="visuals/lights" groups=["scene_actors"]]
|
||||
unique_name_in_owner = true
|
||||
libraries = {
|
||||
&"": SubResource("AnimationLibrary_k8op5")
|
||||
}
|
||||
|
|
@ -2246,7 +2248,7 @@ light_array = Array[Vector3]([Vector3(-0.545, 0.915, 1.035), Vector3(-0.47, 0.85
|
|||
|
||||
[connection signal="ini_room" from="." to="logic/PlayerController" method="_on_ini_room"]
|
||||
[connection signal="ini_room" from="." to="logic/ScenePlayer" method="_on_ini_room"]
|
||||
[connection signal="ini_room" from="." to="visuals/lights/light_animation" method="_on_ini_room"]
|
||||
[connection signal="ini_room" from="." to="visuals/lights/LightAnimation" method="_on_ini_room"]
|
||||
[connection signal="ui_entered" from="logic/PlayerController" to="SceneUI" method="show"]
|
||||
[connection signal="ui_exited" from="logic/PlayerController" to="SceneUI" method="hide"]
|
||||
[connection signal="body_entered" from="logic/Bed and Ladders/ladder_trigger" to="logic/PlayerController" method="_on_bed_enter"]
|
||||
|
|
|
|||
|
|
@ -19,4 +19,4 @@ func pull_save_state(save: SaveGame) -> void:
|
|||
|
||||
func save_room():
|
||||
pull_save_state(save_game)
|
||||
save_game.save_to_file.call_deferred(get_tree().root.get_texture())
|
||||
save_game.save_to_file(get_tree().root.get_texture())
|
||||
|
|
|
|||
|
|
@ -1,58 +1,111 @@
|
|||
@tool
|
||||
class_name SaveGame extends Resource
|
||||
|
||||
@export var filepath: String
|
||||
@export var unique_save_name: String = "frame_of_mind_%s_%s" % [Time.get_date_string_from_system(), Time.get_time_string_from_system()]
|
||||
@export var current_room: State.rooms = State.rooms.YOUTH
|
||||
@export var mementos_complete: int = 0
|
||||
@export var board_state: Dictionary = {}
|
||||
@export var thumbnail: Texture = preload("res://import/interface-elements/empty_save_slot.png")
|
||||
@export var last_saved: int = int(Time.get_unix_time_from_system())
|
||||
var _is_initialised: bool = false
|
||||
|
||||
@export var is_save_file_valid: bool = false
|
||||
@export var filepath: String:
|
||||
set(value):
|
||||
filepath = value
|
||||
if _is_initialised:
|
||||
read_save_file()
|
||||
changed.emit()
|
||||
@export var unique_save_name: String = "frame_of_mind_%s_%s" % [Time.get_date_string_from_system(), Time.get_time_string_from_system().replace(":", "-")]:
|
||||
set(value):
|
||||
unique_save_name = value
|
||||
if _is_initialised: changed.emit()
|
||||
@export var current_room: State.rooms = State.rooms.NULL:
|
||||
set(value):
|
||||
current_room = value
|
||||
if _is_initialised: changed.emit()
|
||||
@export_flags("Intro", "Childhood", "Voice Training", "Jui Jutsu") var mementos_complete: int = 0:
|
||||
set(value):
|
||||
mementos_complete = value
|
||||
if _is_initialised: changed.emit()
|
||||
@export var board_state: Dictionary = {"cards": {}, "stickies": {}}:
|
||||
set(value):
|
||||
board_state = value
|
||||
if _is_initialised: changed.emit()
|
||||
@export var thumbnail: Texture = preload("res://import/interface-elements/empty_save_slot.png"):
|
||||
set(value):
|
||||
thumbnail = value
|
||||
if _is_initialised: changed.emit()
|
||||
@export var last_saved: int = int(Time.get_unix_time_from_system()):
|
||||
set(value):
|
||||
last_saved = value
|
||||
if _is_initialised: changed.emit()
|
||||
|
||||
@export var is_valid: bool = false
|
||||
@export var is_empty: bool = true:
|
||||
get():
|
||||
return not FileAccess.file_exists("%s.json:" % filepath)
|
||||
@export var save_manually: bool = false:
|
||||
set(val):
|
||||
if val: save_to_file(thumbnail)
|
||||
|
||||
func _validate_property(property: Dictionary):
|
||||
if property.name == filepath:
|
||||
property.usage |= PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED
|
||||
if property.name == "thumbnail":
|
||||
property.usage = not PROPERTY_USAGE_STORAGE
|
||||
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "is_valid":
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "is_empty":
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
|
||||
func _init(initial_filepath = "") -> void:
|
||||
|
||||
if initial_filepath == "":
|
||||
filepath = "%s/%s" % [State.user_saves_path, unique_save_name]
|
||||
else:
|
||||
filepath = initial_filepath
|
||||
unique_save_name = initial_filepath.get_file()
|
||||
read_save_file()
|
||||
_is_initialised = true
|
||||
|
||||
func read_save_file():
|
||||
print("Opening Savegame: %s.json" % filepath)
|
||||
|
||||
if FileAccess.file_exists("%s.json:" % filepath):
|
||||
|
||||
|
||||
var file = FileAccess.open("%s.json:" % filepath, FileAccess.READ)
|
||||
var raw_json = FileAccess.get_file_as_string("%s.json:" % filepath)
|
||||
if FileAccess.file_exists("%s.json" % filepath):
|
||||
var file = FileAccess.open("%s.json" % filepath, FileAccess.READ)
|
||||
var raw_json = FileAccess.get_file_as_string("%s.json" % filepath)
|
||||
file.close()
|
||||
var parsed: Dictionary = JSON.parse_string(raw_json)
|
||||
|
||||
var tmp_img: Image
|
||||
if FileAccess.file_exists("%s/thumbnails/%s.png" % [State.user_saves_path, filepath]):
|
||||
tmp_img = Image.load_from_file("%s/thumbnails/%s.png" % [State.user_saves_path, filepath])
|
||||
|
||||
is_save_file_valid = (
|
||||
if FileAccess.file_exists("%s/thumbnails/%s.png" % [filepath.get_base_dir(), unique_save_name]):
|
||||
tmp_img = Image.load_from_file("%s/thumbnails/%s.png" % [filepath.get_base_dir(), unique_save_name])
|
||||
|
||||
var are_types_valid = (
|
||||
parsed["unique_save_name"] is String and
|
||||
parsed["current_room"] is int and
|
||||
parsed["mementos_complete"] is int and
|
||||
parsed["coard_state"] is Dictionary and
|
||||
parsed["last_saved"] is float and last_saved != 0 and
|
||||
parsed["tmp_img"] is Image
|
||||
parsed["current_room"] is float and
|
||||
parsed["mementos_complete"] is float and
|
||||
parsed["board_state"] is Dictionary and
|
||||
parsed["last_saved"] is float and last_saved != 0
|
||||
)
|
||||
|
||||
if is_save_file_valid:
|
||||
if are_types_valid:
|
||||
for key in parsed.keys():
|
||||
set(key, parsed[key])
|
||||
|
||||
for dict:Dictionary in board_state.values():
|
||||
for key in dict.keys():
|
||||
if dict[key] is String:
|
||||
if dict[key].begins_with("("):
|
||||
dict[key] = parse_vec_from_string(dict[key])
|
||||
|
||||
is_valid = are_types_valid \
|
||||
and current_room >= 0 \
|
||||
and current_room < State.rooms.keys().size() \
|
||||
and validate_board_state()
|
||||
|
||||
if not is_valid:
|
||||
push_error("Parsing of Save failed.")
|
||||
|
||||
if tmp_img != null:
|
||||
thumbnail = ImageTexture.create_from_image(tmp_img)
|
||||
is_empty = false
|
||||
else:
|
||||
is_valid = true
|
||||
|
||||
func _get_save_dict() -> Dictionary:
|
||||
return {
|
||||
|
|
@ -64,13 +117,54 @@ func _get_save_dict() -> Dictionary:
|
|||
}
|
||||
|
||||
func save_to_file(current_screen: Texture):
|
||||
return
|
||||
last_saved = Time.get_unix_time_from_system()
|
||||
|
||||
var thumbnail_image: Image = current_screen.get_image()
|
||||
thumbnail_image.resize(384, 261, Image.INTERPOLATE_LANCZOS) # nonexistent call in ViewportTexturew
|
||||
|
||||
thumbnail_image.save_png("%s/thumbnails/%s.png" % [State.user_saves_path, filepath])
|
||||
var thumbnail_path: String = "%s/thumbnails/%s.png" % [filepath.get_base_dir(), unique_save_name]
|
||||
var save_dir = DirAccess.open(filepath.get_base_dir())
|
||||
if not save_dir.dir_exists("thumbnails"):
|
||||
save_dir.make_dir("thumbnails")
|
||||
|
||||
var file = FileAccess.open("%s.json:" % filepath, FileAccess.WRITE)
|
||||
thumbnail_image.save_png("%s/thumbnails/%s.png" % [filepath.get_base_dir(), unique_save_name])
|
||||
#thumbnail_image.save_png("%s/test.png" % State.user_saves_path)
|
||||
print(filepath.get_base_dir())
|
||||
var file = FileAccess.open("%s.json" % filepath, FileAccess.WRITE)
|
||||
file.store_string(JSON.stringify(_get_save_dict()))
|
||||
file.close()
|
||||
|
||||
|
||||
func calculate_completed_sequences() -> int:
|
||||
var i: int = mementos_complete - ((mementos_complete >> 1) & 0x55555555);
|
||||
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
|
||||
i = (i + (i >> 4)) & 0x0F0F0F0F;
|
||||
i *= 0x01010101;
|
||||
return i >> 24;
|
||||
|
||||
func calculate_total_connections() -> int:
|
||||
var connections:= 0
|
||||
|
||||
for sticky_position in board_state.stickies.values():
|
||||
connections += int(sticky_position is String)
|
||||
|
||||
return connections
|
||||
|
||||
func validate_board_state() -> bool:
|
||||
if board_state.keys().has("cards") and board_state.keys().has("stickies"):
|
||||
for card in board_state.cards.values():
|
||||
if not card is Vector2:
|
||||
push_error("Save %s could not be parsed: Corrupted Cards." % unique_save_name)
|
||||
return false
|
||||
for sticky in board_state.stickies.values():
|
||||
if not (sticky == -1 or sticky is Vector2 or board_state.cards.keys.has(sticky)):
|
||||
push_error("Save %s could not be parsed: Corrupted Sticky Notes.")
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func parse_vec_from_string(string: String) -> Vector2:
|
||||
var string_array = string.replace("(", "").replace(")", "").split(", ")
|
||||
return Vector2(float(string_array[0]), float(string_array[1]))
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ func _ready():
|
|||
|
||||
get_viewport().gui_focus_changed.connect(reclaim_lost_focus)
|
||||
|
||||
print(get_save_dict())
|
||||
|
||||
|
||||
func reclaim_lost_focus():
|
||||
if has_stage:
|
||||
|
|
@ -396,19 +398,25 @@ func get_save_dict() -> Dictionary:
|
|||
|
||||
for child in dropzone.get_children():
|
||||
if child is Card:
|
||||
if child.has_sticky_note_attached():
|
||||
stickies[child.get_attached_sticky_note().name] = child.name
|
||||
# Save position of Card.
|
||||
cards[child.name] = child.transform.origin
|
||||
|
||||
if child.has_sticky_note_attached():
|
||||
# Saves Card Name as position of it's children.
|
||||
stickies[child.get_attached_sticky_note().name] = child.name
|
||||
|
||||
elif child is StickyNote:
|
||||
# Save position of StickyNote.
|
||||
cards[child.name] = child.transform.origin
|
||||
|
||||
for child in sticky_note_container.get_children():
|
||||
if child is StickyNotePanel:
|
||||
# Saves all collected Stickies that are not on board.
|
||||
stickies[child.attached_sticky_note.name] = -1
|
||||
return {
|
||||
"cards": cards,
|
||||
"stickies": stickies
|
||||
} if cards != {} and stickies != {} else {}
|
||||
}
|
||||
|
||||
func initialise_from_save(savegame: SaveGame):
|
||||
if savegame.board_state == {}: return
|
||||
|
|
@ -419,12 +427,13 @@ func initialise_from_save(savegame: SaveGame):
|
|||
|
||||
for card:Card in card_pile["cards"]:
|
||||
add_card(card)
|
||||
card.transform.origin = cards[card.name]
|
||||
card.transform.origin = cards[card.name] # Replacing position reference with card reference! Needed in next loop.
|
||||
cards[card.name] = card
|
||||
|
||||
for sticky:StickyNote in card_pile["sticky_notes"]:
|
||||
if stickies[sticky.name] == -1:
|
||||
if stickies[sticky.name] == -1.0:
|
||||
add_sticky_note(sticky)
|
||||
if stickies[sticky.name] is String:
|
||||
elif stickies[sticky.name] is String:
|
||||
cards[stickies[sticky.name]].attach_sticky_note(sticky)
|
||||
else:
|
||||
insert_area(dropzone, sticky)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ var has_stage: bool = false:
|
|||
if is_node_ready():
|
||||
if has_stage: new_game_button.grab_focus()
|
||||
new_game_button.disabled = not has_stage
|
||||
continue_button.disabled = not has_stage
|
||||
load_game_button.disabled = not has_stage
|
||||
continue_button.disabled = not has_stage or save_game_handle.get_most_recent_save().current_room == 0
|
||||
load_game_button.disabled = not has_stage or not save_game_handle.has_existing_saves()
|
||||
settings_button.disabled = not has_stage
|
||||
credits_button.disabled = not has_stage
|
||||
quit_button.disabled = not has_stage
|
||||
|
|
@ -31,14 +31,14 @@ signal roll_credits
|
|||
|
||||
var await_new_game: bool = false
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
save_game_handle.picked.connect(_on_save_picked)
|
||||
continue_button.visible = save_game_handle.get_most_recent_save().current_room != 0
|
||||
continue_button.disabled = save_game_handle.get_most_recent_save().current_room == 0
|
||||
continue_button.pressed.connect(func(): start_game.emit(save_game_handle.get_most_recent_save()))
|
||||
new_game_button.pressed.connect(func(): save_game_handle.pick_save_slot(true))
|
||||
load_game_button.pressed.connect(func(): save_game_handle.pick_save_slot(false))
|
||||
load_game_button.disabled = not save_game_handle.has_existing_saves()
|
||||
settings_button.get_popup().index_pressed.connect(settings_popup.show_settings)
|
||||
quit_button.pressed.connect(get_tree().quit)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,49 @@
|
|||
@tool
|
||||
class_name SaveGameDisplay extends Button
|
||||
|
||||
func _init(save: SaveGame, id: int) -> void:
|
||||
var base_container:= HBoxContainer.new()
|
||||
var _is_built: bool = false
|
||||
|
||||
@export var save: SaveGame:
|
||||
set(new_save):
|
||||
save = new_save
|
||||
if _is_built: rebuild()
|
||||
@export var id: int:
|
||||
set(new_id):
|
||||
id = new_id
|
||||
if _is_built: rebuild()
|
||||
|
||||
func _init(new_save: SaveGame = SaveGame.new(), new_id: int = 0) -> void:
|
||||
self.save = new_save
|
||||
self.id = new_id
|
||||
|
||||
func _ready() -> void:
|
||||
save.changed.connect(rebuild)
|
||||
rebuild()
|
||||
_is_built = true
|
||||
|
||||
func rebuild():
|
||||
for child in get_children(true):
|
||||
remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
if not save.is_valid:
|
||||
disabled = true
|
||||
text = "Slot %d corrupted." % id
|
||||
else:
|
||||
disabled = false
|
||||
text = ""
|
||||
|
||||
var base_container := HBoxContainer.new()
|
||||
base_container.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
add_child(base_container)
|
||||
|
||||
var texture:= TextureRect.new()
|
||||
var texture := TextureRect.new()
|
||||
texture.texture = save.thumbnail
|
||||
texture.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
|
||||
base_container.add_child(texture)
|
||||
var heading_split:= HSplitContainer.new()
|
||||
var heading:= Label.new()
|
||||
var heading_split := HSplitContainer.new()
|
||||
var heading := Label.new()
|
||||
|
||||
heading.text = "Slot %d" % id
|
||||
heading.theme_type_variation = "HeaderLarge"
|
||||
|
|
@ -40,43 +72,48 @@ func _init(save: SaveGame, id: int) -> void:
|
|||
date_time["minute"],
|
||||
"AM" if date_time["hour"] < 12 else "PM"]
|
||||
|
||||
var time:= Label.new()
|
||||
time.text = localised_date_time if not save.current_room == 0 else "Start new game."
|
||||
var time_label := Label.new()
|
||||
time_label.text = localised_date_time if not save.current_room == State.rooms.NULL else "Start new game"
|
||||
|
||||
var info:= VBoxContainer.new()
|
||||
base_container.add_child(info)
|
||||
|
||||
info.add_child(heading_split)
|
||||
heading_split.add_child(heading)
|
||||
heading_split.add_child(time)
|
||||
heading_split.add_child(time_label)
|
||||
|
||||
var room:= Label.new()
|
||||
room.theme_type_variation = "HeaderMedium"
|
||||
match save.current_room:
|
||||
State.rooms.MENU:
|
||||
State.rooms.NULL:
|
||||
room.text = "Empty Slot"
|
||||
State.rooms.DRAVEN:
|
||||
room.text = "Intro Sequence"
|
||||
State.rooms.YOUTH:
|
||||
room.text = "Inside youth room."
|
||||
if save.mementos_complete == 0:
|
||||
room.text = "Youth Room"
|
||||
else:
|
||||
room.text = "Intro Sequence"
|
||||
State.rooms.TRANSITION:
|
||||
room.text = "Transitioning to Adulthood."
|
||||
room.text = "Transitioning to Adulthood"
|
||||
State.rooms.ADULTHOOD:
|
||||
room.text = "Exploring Adulthood."
|
||||
room.text = "Exploring Adulthood"
|
||||
State.rooms.ENDING:
|
||||
room.text = "Ending"
|
||||
|
||||
var state: = Label.new()
|
||||
state.text = ("""
|
||||
Mementos collected: 1/4
|
||||
Connections found: 1/8
|
||||
Secrets found: 1/4
|
||||
""").strip_edges()
|
||||
state.text = TranslationServer.translate(("""
|
||||
Mementos collected: %d/4
|
||||
Connections found: %d/8
|
||||
""").strip_edges()) % [save.calculate_completed_sequences(), save.calculate_total_connections()]
|
||||
#Secrets found: 1/4
|
||||
|
||||
info.add_child(room)
|
||||
info.add_child(state)
|
||||
info.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
|
||||
custom_minimum_size = base_container.get_combined_minimum_size() + Vector2(64, 32)
|
||||
|
||||
theme_type_variation = "SaveButton"
|
||||
|
||||
call_deferred("resize")
|
||||
|
||||
func resize():
|
||||
custom_minimum_size = get_child(0, true).get_combined_minimum_size() + Vector2(64, 32)
|
||||
get_child(0, true).position = Vector2(32, 16)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,12 @@ var scroll_container: ScrollContainer
|
|||
|
||||
var override_save_slot: bool = false
|
||||
|
||||
func _validate_property(property: Dictionary) -> void:
|
||||
if property.name == "saves":
|
||||
property.usage = PROPERTY_USAGE_READ_ONLY + PROPERTY_USAGE_SCRIPT_VARIABLE + PROPERTY_USAGE_EDITOR
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
#FIXME: stop this from creating countless save games!
|
||||
return
|
||||
var dir = DirAccess.open(State.user_saves_path)
|
||||
print(DirAccess.get_open_error())
|
||||
# Invalid Error being raised when Directory does not exist.
|
||||
|
|
@ -28,31 +31,39 @@ func _ready() -> void:
|
|||
dir = DirAccess.open("user://")
|
||||
dir.make_dir_recursive(State.user_saves_path)
|
||||
load_games()
|
||||
for i in range(save_buttons.size()):
|
||||
save_buttons[i].pressed.connect(func(): picked.emit(saves[i]))
|
||||
print("connect ", i)
|
||||
|
||||
func load_games():
|
||||
saves = []
|
||||
var save_game_dir := DirAccess.open(State.user_saves_path)
|
||||
var filepaths: PackedStringArray = save_game_dir.get_files()
|
||||
|
||||
for path in filepaths:
|
||||
if path.ends_with(".json"):
|
||||
saves.append(SaveGame.new(path))
|
||||
saves.append(SaveGame.new("%s/%s" % [State.user_saves_path, path.get_basename()]))
|
||||
|
||||
saves.append(SaveGame.new())
|
||||
|
||||
#purging the current state
|
||||
save_buttons = []
|
||||
if scroll_container != null:
|
||||
scroll_container.free()
|
||||
scroll_container.queue_free()
|
||||
|
||||
scroll_container = ScrollContainer.new()
|
||||
|
||||
scroll_container.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
scroll_container.custom_minimum_size = Vector2(0, ProjectSettings.get_setting("display/window/size/viewport_height") - 256)
|
||||
add_child(scroll_container)
|
||||
|
||||
var save_box := VBoxContainer.new()
|
||||
save_box.add_theme_constant_override("separation", 16)
|
||||
scroll_container.add_child(save_box)
|
||||
|
||||
for i in range(saves.size()):
|
||||
var new_button := SaveGameDisplay.new(saves[i], i+1)
|
||||
scroll_container.add_child(new_button)
|
||||
save_box.add_child(new_button)
|
||||
save_buttons.append(new_button)
|
||||
new_button.pressed.connect(func(): _on_game_picked(i))
|
||||
|
||||
|
|
@ -68,6 +79,9 @@ func _on_game_picked(id: int):
|
|||
|
||||
# This function is called when the user us supposed to choose a slot to load or create a new game.
|
||||
func pick_save_slot(create_new_game: bool):
|
||||
if saves.size() == 1:
|
||||
picked.emit(saves[0])
|
||||
else:
|
||||
State.take_stage(self)
|
||||
self.override_save_slot = create_new_game
|
||||
|
||||
|
|
@ -80,3 +94,10 @@ func get_most_recent_save() -> SaveGame:
|
|||
most_recent_time = saves[i].last_saved
|
||||
|
||||
return saves[most_recent_index] if most_recent_time > 0 else SaveGame.new()
|
||||
|
||||
func has_existing_saves() -> bool:
|
||||
return saves.size() > 1
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
State.leave_stage(self)
|
||||
|
|
|
|||
17
src/main.gd
17
src/main.gd
|
|
@ -38,8 +38,8 @@ var currently_loading_room: String = "":
|
|||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
currently_loading_room = youth_room_path
|
||||
|
||||
currently_loading_room = get_room_path_from_id(main_menu.save_game_handle.get_most_recent_save().current_room)
|
||||
main_menu.start_game.connect(load_save)
|
||||
get_tree().tree_process_mode_changed.connect(pause_mode_changed)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
|
|
@ -52,10 +52,6 @@ func _process(_delta: float) -> void:
|
|||
currently_loading_room = ""
|
||||
room_loaded.emit()
|
||||
|
||||
if Input.is_action_just_pressed("reset_demo") and (OS.has_feature("demo") or true):
|
||||
State.stage_list = [self]
|
||||
_return_to_menu()
|
||||
$"Messe-Menue".show()
|
||||
if Input.is_action_just_pressed("ui_menu") and in_game:
|
||||
toggle_pause_menu()
|
||||
|
||||
|
|
@ -94,10 +90,10 @@ func _return_to_menu():
|
|||
|
||||
func load_save(save: SaveGame):
|
||||
|
||||
#if currently_loading_room != "":
|
||||
# await(room_loaded)
|
||||
if currently_loading_room != "":
|
||||
await(room_loaded)
|
||||
|
||||
if save.current_room != current_room_id:
|
||||
if get_room_path_from_id(save.current_room) != get_room_path_from_id(current_room_id):
|
||||
# TODO Prevent race condition from appearing when save is loaded while room is still loading.
|
||||
currently_loading_room = get_room_path_from_id(save.current_room)
|
||||
await(room_loaded)
|
||||
|
|
@ -106,6 +102,7 @@ func load_save(save: SaveGame):
|
|||
|
||||
State.active_save_game = save
|
||||
in_game = true
|
||||
current_room.start_room()
|
||||
|
||||
func _on_ready_to_unload():
|
||||
if get_child(0) is Node3D:
|
||||
|
|
@ -113,7 +110,7 @@ func _on_ready_to_unload():
|
|||
|
||||
func get_room_path_from_id(id: State.rooms) -> String:
|
||||
match id:
|
||||
State.rooms.YOUTH, State.rooms.MENU, State.rooms.DRAVEN:
|
||||
State.rooms.YOUTH, State.rooms.NULL:
|
||||
return youth_room_path
|
||||
State.rooms.TRANSITION:
|
||||
return transition_room_path
|
||||
|
|
|
|||
|
|
@ -294,8 +294,7 @@ func queue_for_stage(target: Object, index: int = 1):
|
|||
#region play state
|
||||
|
||||
enum rooms {
|
||||
MENU,
|
||||
DRAVEN,
|
||||
NULL,
|
||||
YOUTH,
|
||||
TRANSITION,
|
||||
ADULTHOOD,
|
||||
|
|
@ -317,4 +316,4 @@ enum sequences {
|
|||
BURNOUT
|
||||
}
|
||||
|
||||
var current_room = rooms.MENU
|
||||
var current_room = rooms.NULL
|
||||
|
|
|
|||
Loading…
Reference in New Issue