Implement save/load system

This commit is contained in:
SchimmelSpreu83 2026-03-08 00:26:24 +01:00
parent 266f6f7257
commit 9c2fb7ab9c
26 changed files with 176 additions and 55 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# Godot 4+ specific ignores # Godot 4+ specific ignores
.godot/ .godot/
*.unwrap_cache
/android/ /android/
# FMod ignores # FMod ignores

View File

@ -24,7 +24,7 @@ nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true meshes/ensure_tangents=true
meshes/generate_lods=true meshes/generate_lods=true
meshes/create_shadow_meshes=true meshes/create_shadow_meshes=true
meshes/light_baking=1 meshes/light_baking=2
meshes/lightmap_texel_size=0.2 meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false meshes/force_disable_compression=false
skins/use_named_skins=true skins/use_named_skins=true

View File

@ -24,7 +24,7 @@ nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true meshes/ensure_tangents=true
meshes/generate_lods=true meshes/generate_lods=true
meshes/create_shadow_meshes=true meshes/create_shadow_meshes=true
meshes/light_baking=1 meshes/light_baking=2
meshes/lightmap_texel_size=0.2 meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false meshes/force_disable_compression=false
skins/use_named_skins=true skins/use_named_skins=true

View File

@ -24,7 +24,7 @@ nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true meshes/ensure_tangents=true
meshes/generate_lods=true meshes/generate_lods=true
meshes/create_shadow_meshes=true meshes/create_shadow_meshes=true
meshes/light_baking=1 meshes/light_baking=2
meshes/lightmap_texel_size=0.2 meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false meshes/force_disable_compression=false
skins/use_named_skins=true skins/use_named_skins=true

View File

@ -24,7 +24,7 @@ nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true meshes/ensure_tangents=true
meshes/generate_lods=true meshes/generate_lods=true
meshes/create_shadow_meshes=true meshes/create_shadow_meshes=true
meshes/light_baking=1 meshes/light_baking=2
meshes/lightmap_texel_size=0.2 meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false meshes/force_disable_compression=false
skins/use_named_skins=true skins/use_named_skins=true

View File

@ -50,6 +50,13 @@ folder_colors={
"res://tools/": "gray" "res://tools/": "gray"
} }
[importer_defaults]
scene={
&"materials/extract": 1,
&"meshes/light_baking": 2
}
[input] [input]
ui_accept={ ui_accept={

View File

@ -0,0 +1,37 @@
class_name WorldProxy
extends Node
signal world_changed
static var world_proxies: Array[WorldProxy] = []
var world: World: set = set_world, get = get_world
func _enter_tree() -> void:
if not world_proxies.has(self):
world_proxies.append(self)
func _exit_tree() -> void:
world_proxies.erase(self)
func set_world(new_world: World) -> void:
world = new_world
world_changed.emit(world)
func get_world() -> World:
return world
func has_world() -> bool:
return is_instance_valid(world)
func wait_for_world() -> World:
if not is_instance_valid(world):
await world_changed
return get_world()

View File

@ -0,0 +1 @@
uid://qifiwdgyx6e

View File

@ -2,8 +2,8 @@ class_name World
extends Node extends Node
signal loaded signal loaded
signal change_world_request(new_world_path: String, save_previous: bool, load_from_save: bool) signal change_world_requested(new_world_path: String, save_previous: bool, load_from_save: bool)
signal world_unload_request(do_save: bool) signal world_unload_requested(do_save: bool)
@export var level_streamers: Array[LevelStreamer] @export var level_streamers: Array[LevelStreamer]
## Reference to the player. ## Reference to the player.
@ -33,9 +33,23 @@ func _ready() -> void:
else: else:
await initialize_default_world_state() await initialize_default_world_state()
initialize_level_streamers()
initialize_world_proxies()
loaded.emit() loaded.emit()
func initialize_level_streamers() -> void:
for level_streamer: LevelStreamer in level_streamers:
level_streamer.loading_finished.connect(initialize_world_proxies)
func initialize_world_proxies() -> void:
for world_object: WorldProxy in WorldProxy.world_proxies:
if is_ancestor_of(world_object):
world_object.set_world(self)
func initialize_default_world_state() -> void: func initialize_default_world_state() -> void:
world_state = WorldState.new() world_state = WorldState.new()
@ -109,11 +123,11 @@ func get_loaded_level_ids() -> Array[StringName]:
func request_world_change(new_world_path: String, save_current: bool = true, load_from_save: bool = true) -> void: func request_world_change(new_world_path: String, save_current: bool = true, load_from_save: bool = true) -> void:
change_world_request.emit(new_world_path, save_current, load_from_save) change_world_requested.emit(new_world_path, save_current, load_from_save)
func request_world_unload(do_save: bool = true) -> void: func request_world_unload(do_save: bool = true) -> void:
world_unload_request.emit(do_save) world_unload_requested.emit(do_save)
func store_instance_state(key: String, value: Variant) -> void: func store_instance_state(key: String, value: Variant) -> void:

View File

@ -83,8 +83,8 @@ func load_world(world_path: String, save_previous: bool = true, load_from_save:
if load_from_save: if load_from_save:
world.world_state = load_world_state(world_path) world.world_state = load_world_state(world_path)
world.change_world_request.connect(load_world) world.change_world_requested.connect(load_world)
world.world_unload_request.connect(_on_unload_world_request) world.world_unload_requested.connect(_on_unload_world_request)
world_container.add_child.call_deferred(world) world_container.add_child.call_deferred(world)
await world.loaded await world.loaded

View File

@ -2,14 +2,18 @@ class_name FlashlightBattery
extends Node3D extends Node3D
@export var world: World
@export var manager: FlashlightManager @export var manager: FlashlightManager
@export var refill_amount: float = 0.15 @export var refill_amount: float = 0.15
var world: World
@onready var world_proxy: WorldProxy = $WorldProxy
@onready var pickup_interaction: PickupInteraction = $PickupInteraction @onready var pickup_interaction: PickupInteraction = $PickupInteraction
func _ready() -> void: func _ready() -> void:
world = await world_proxy.wait_for_world()
if InstancePersister.new(self, world).get_property(&"is_collected", false): if InstancePersister.new(self, world).get_property(&"is_collected", false):
queue_free() queue_free()
return return

View File

@ -2,6 +2,7 @@
[ext_resource type="Script" uid="uid://nsxr1qkvivsf" path="res://src/gameplay/systems/flashlight/flashlight_battery.gd" id="1_p5331"] [ext_resource type="Script" uid="uid://nsxr1qkvivsf" path="res://src/gameplay/systems/flashlight/flashlight_battery.gd" id="1_p5331"]
[ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_0r1sb"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_0r1sb"]
[ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_3nps0"]
[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_3nps0"] [ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_3nps0"]
[ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="3_ouj7b"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="3_ouj7b"]
@ -25,6 +26,10 @@ radius = 0.1
script = ExtResource("1_p5331") script = ExtResource("1_p5331")
metadata/_custom_type_script = "uid://nsxr1qkvivsf" metadata/_custom_type_script = "uid://nsxr1qkvivsf"
[node name="WorldProxy" type="Node" parent="." unique_id=930661856]
script = ExtResource("2_3nps0")
metadata/_custom_type_script = "uid://qifiwdgyx6e"
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1939916981] [node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1939916981]
mesh = SubResource("CylinderMesh_0r1sb") mesh = SubResource("CylinderMesh_0r1sb")

View File

@ -10,7 +10,6 @@ enum DrainModes {
TIMED, ## Flashlight looses power over time. TIMED, ## Flashlight looses power over time.
} }
@export var world: World
@export var enabled: bool = true @export var enabled: bool = true
@export var initial_power: float = 1.0 @export var initial_power: float = 1.0
@export var full_percentage: float = 0.9 ## At which point we say that the flashlight is full. @export var full_percentage: float = 0.9 ## At which point we say that the flashlight is full.
@ -20,13 +19,23 @@ enum DrainModes {
## How much power is lost each second. ## How much power is lost each second.
@export var timed_drain_amount: float = 0.015: set = set_timed_drain_amount @export var timed_drain_amount: float = 0.015: set = set_timed_drain_amount
var world: World
var power: float = 0.0 var power: float = 0.0
var is_flashlight_active: bool = false: set = set_flashlight_is_active var is_flashlight_active: bool = false: set = set_flashlight_is_active
var _world_proxy: WorldProxy
@onready var _instance_persister := InstancePersister.new(self, world) @onready var _instance_persister: InstancePersister
func _enter_tree() -> void:
_world_proxy = WorldProxy.new()
add_child(_world_proxy)
func _ready() -> void: func _ready() -> void:
world = await _world_proxy.wait_for_world()
_instance_persister= InstancePersister.new(self, world)
power = _instance_persister.get_property(&"power", initial_power) power = _instance_persister.get_property(&"power", initial_power)
is_flashlight_active = _instance_persister.get_property(&"is_flashlight_active", is_flashlight_active) is_flashlight_active = _instance_persister.get_property(&"is_flashlight_active", is_flashlight_active)
drain_mode = _instance_persister.get_property(&"drain_mode", drain_mode) drain_mode = _instance_persister.get_property(&"drain_mode", drain_mode)

View File

@ -6,18 +6,27 @@ enum DrainModes {
AMOUNT, ## Reduce the power by [member drain_value] amount. AMOUNT, ## Reduce the power by [member drain_value] amount.
} }
@export var world: World
@export var manager: FlashlightManager @export var manager: FlashlightManager
@export var allowed_bodies: Array[Node3D] @export var allowed_bodies: Array[Node3D]
@export var trigger_once: bool = true @export var trigger_once: bool = true
var world: World
var _world_proxy: WorldProxy
@export var drain_mode := DrainModes.SET @export var drain_mode := DrainModes.SET
@export var drain_value: float = 0.3 @export var drain_value: float = 0.3
@export var change_manager_drain_mode: bool = false @export var change_manager_drain_mode: bool = false
@export var manager_drain_mode := FlashlightManager.DrainModes.MANUAL @export var manager_drain_mode := FlashlightManager.DrainModes.MANUAL
func _enter_tree() -> void:
_world_proxy = WorldProxy.new()
add_child(_world_proxy)
func _ready() -> void: func _ready() -> void:
world = await _world_proxy.wait_for_world()
if trigger_once and InstancePersister.new(self, world).get_property(&"is_triggered", false): if trigger_once and InstancePersister.new(self, world).get_property(&"is_triggered", false):
queue_free() queue_free()
return return

View File

@ -3,12 +3,16 @@ extends Node3D
@export var power_box: PowerBox @export var power_box: PowerBox
@export var world: World
var world: World
@onready var pickup_interaction: PickupInteraction = $PickupInteraction @onready var pickup_interaction: PickupInteraction = $PickupInteraction
@onready var world_proxy: WorldProxy = $WorldProxy
func _ready() -> void: func _ready() -> void:
world = await world_proxy.wait_for_world()
if InstancePersister.new(self, world).get_property(&"is_collected", false): if InstancePersister.new(self, world).get_property(&"is_collected", false):
queue_free() queue_free()
return return

View File

@ -2,6 +2,7 @@
[ext_resource type="Script" uid="uid://dkao86mwhq1tm" path="res://src/gameplay/systems/power_box/fuse_pickup.gd" id="1_b733i"] [ext_resource type="Script" uid="uid://dkao86mwhq1tm" path="res://src/gameplay/systems/power_box/fuse_pickup.gd" id="1_b733i"]
[ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_of2nm"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_of2nm"]
[ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_p036h"]
[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_hqmg0"] [ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_hqmg0"]
[ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_3b6jw"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_3b6jw"]
@ -28,6 +29,10 @@ radius = 0.1
script = ExtResource("1_b733i") script = ExtResource("1_b733i")
metadata/_custom_type_script = "uid://dkao86mwhq1tm" metadata/_custom_type_script = "uid://dkao86mwhq1tm"
[node name="WorldProxy" type="Node" parent="." unique_id=586279846]
script = ExtResource("2_p036h")
metadata/_custom_type_script = "uid://qifiwdgyx6e"
[node name="PickupInteraction" type="Node" parent="." unique_id=285803844] [node name="PickupInteraction" type="Node" parent="." unique_id=285803844]
script = ExtResource("2_of2nm") script = ExtResource("2_of2nm")
hover_hint = "Press {prompt} to pickup" hover_hint = "Press {prompt} to pickup"

View File

@ -4,21 +4,25 @@ extends Node3D
signal power_restored signal power_restored
signal power_revoked signal power_revoked
@export var world: World
@export var can_interact: bool = true: set = set_can_interact @export var can_interact: bool = true: set = set_can_interact
@export var start_activated: bool = false @export var start_activated: bool = false
@export var minigame: Node3D @export var minigame: Node3D
@export var requires_fuse: bool = true @export var requires_fuse: bool = true
@export var interaction: PickupInteraction @export var interaction: PickupInteraction
var world: World
var is_restored: bool = false var is_restored: bool = false
var is_active: bool = false var is_active: bool = false
var has_completed_minigame: bool = false var has_completed_minigame: bool = false
@onready var _instance_persister := InstancePersister.new(self, world) @onready var world_proxy: WorldProxy = $WorldProxy
@onready var _instance_persister: InstancePersister
func _ready() -> void: func _ready() -> void:
world = await world_proxy.wait_for_world()
_instance_persister = InstancePersister.new(self, world)
is_restored = _instance_persister.get_property(&"is_restored", is_restored) is_restored = _instance_persister.get_property(&"is_restored", is_restored)
is_active = _instance_persister.get_property(&"is_active", start_activated) is_active = _instance_persister.get_property(&"is_active", start_activated)
has_completed_minigame = _instance_persister.get_property(&"has_completed_minigame", has_completed_minigame) has_completed_minigame = _instance_persister.get_property(&"has_completed_minigame", has_completed_minigame)

View File

@ -2,6 +2,7 @@
[ext_resource type="Script" uid="uid://bpvawt7ate0ug" path="res://src/gameplay/systems/power_box/power_box.gd" id="1_m14vv"] [ext_resource type="Script" uid="uid://bpvawt7ate0ug" path="res://src/gameplay/systems/power_box/power_box.gd" id="1_m14vv"]
[ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_35cpc"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_35cpc"]
[ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_v6qxf"]
[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_35cpc"] [ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_35cpc"]
[ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_v6qxf"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_v6qxf"]
@ -23,6 +24,10 @@ script = ExtResource("1_m14vv")
interaction = NodePath("PickupInteraction") interaction = NodePath("PickupInteraction")
metadata/_custom_type_script = "uid://bpvawt7ate0ug" metadata/_custom_type_script = "uid://bpvawt7ate0ug"
[node name="WorldProxy" type="Node" parent="." unique_id=1910031977]
script = ExtResource("2_v6qxf")
metadata/_custom_type_script = "uid://qifiwdgyx6e"
[node name="PickupInteraction" type="Node" parent="." unique_id=1698155134] [node name="PickupInteraction" type="Node" parent="." unique_id=1698155134]
script = ExtResource("2_35cpc") script = ExtResource("2_35cpc")
button_prompt = SubResource("Texture2D_35cpc") button_prompt = SubResource("Texture2D_35cpc")

View File

@ -5,21 +5,22 @@ signal load_game_request(save_data: SaveData, slot_index: int)
signal quit_request signal quit_request
@onready var continue_button: Button = %ContinueButton @onready var continue_button: Button = %ContinueButton
@onready var load_button: Button = %LoadButton
@onready var new_game_button: Button = %NewGameButton @onready var new_game_button: Button = %NewGameButton
@onready var quit_button: Button = %QuitButton @onready var quit_button: Button = %QuitButton
@onready var saves_scroll_container: ScrollContainer = $SavesScrollContainer
@onready var saves_container: VBoxContainer = %SavesContainer @onready var saves_container: VBoxContainer = %SavesContainer
func _ready() -> void: func _ready() -> void:
continue_button.pressed.connect(_on_continue_pressed) continue_button.pressed.connect(_on_continue_pressed)
load_button.pressed.connect(_on_load_pressed)
new_game_button.pressed.connect(_on_new_game_pressed) new_game_button.pressed.connect(_on_new_game_pressed)
quit_button.pressed.connect(_on_quit_pressed) quit_button.pressed.connect(_on_quit_pressed)
continue_button.visible = has_save() continue_button.visible = has_save()
populate_save_entries()
func has_save() -> bool: func has_save() -> bool:
var config := ConfigFile.new() var config := ConfigFile.new()
@ -33,7 +34,8 @@ func populate_save_entries() -> void:
for save_slot: int in get_save_slots(): for save_slot: int in get_save_slots():
var save_path: String = "user://%s/save_data.tres" % save_slot var save_path: String = "user://%s/save_data.tres" % save_slot
SaveEntryButton.construct_save_entry_button(saves_container, save_path) var button := SaveEntryButton.construct_save_entry_button(saves_container, save_path, save_slot)
button.pressed.connect(_on_save_entry_pressed.bind(save_slot))
func get_save_slots() -> PackedInt32Array: func get_save_slots() -> PackedInt32Array:
@ -78,6 +80,11 @@ func _on_continue_pressed() -> void:
load_game_request.emit(save_data, slot) 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: func _on_new_game_pressed() -> void:
var save_data: SaveData = Game.INITIAL_SAVE_DATA.duplicate() var save_data: SaveData = Game.INITIAL_SAVE_DATA.duplicate()
var slot_index: int = get_unique_save_slot_index() var slot_index: int = get_unique_save_slot_index()
@ -92,3 +99,19 @@ func _on_new_game_pressed() -> void:
func _on_quit_pressed() -> void: func _on_quit_pressed() -> void:
quit_request.emit() quit_request.emit()
func _on_save_entry_pressed(save_slot: int) -> void:
var config := ConfigFile.new()
config.load("user://settings.ini")
config.set_value("game", "last_slot", save_slot)
config.save("user://settings.ini")
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)

View File

@ -41,6 +41,11 @@ unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
text = "CONTINUE" text = "CONTINUE"
[node name="LoadButton" type="Button" parent="MainButtons" unique_id=972924585]
unique_name_in_owner = true
layout_mode = 2
text = "LOAD"
[node name="NewGameButton" type="Button" parent="MainButtons" unique_id=91755502] [node name="NewGameButton" type="Button" parent="MainButtons" unique_id=91755502]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
@ -51,7 +56,7 @@ unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
text = "QUIT" text = "QUIT"
[node name="Saves" type="ScrollContainer" parent="." unique_id=1084479536] [node name="SavesScrollContainer" type="ScrollContainer" parent="." unique_id=1084479536]
visible = false visible = false
layout_mode = 1 layout_mode = 1
anchors_preset = -1 anchors_preset = -1
@ -68,23 +73,23 @@ grow_vertical = 2
follow_focus = true follow_focus = true
metadata/_edit_use_anchors_ = true metadata/_edit_use_anchors_ = true
[node name="SavesContainer" type="VBoxContainer" parent="Saves" unique_id=665774472] [node name="SavesContainer" type="VBoxContainer" parent="SavesScrollContainer" unique_id=665774472]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="Button" type="Button" parent="Saves/SavesContainer" unique_id=784511958] [node name="Button" type="Button" parent="SavesScrollContainer/SavesContainer" unique_id=784511958]
layout_mode = 2 layout_mode = 2
text = "Save 1" text = "Save 1"
[node name="Button2" type="Button" parent="Saves/SavesContainer" unique_id=1926271686] [node name="Button2" type="Button" parent="SavesScrollContainer/SavesContainer" unique_id=1926271686]
layout_mode = 2 layout_mode = 2
text = "Save 1" text = "Save 1"
[node name="Button3" type="Button" parent="Saves/SavesContainer" unique_id=929881066] [node name="Button3" type="Button" parent="SavesScrollContainer/SavesContainer" unique_id=929881066]
layout_mode = 2 layout_mode = 2
text = "Save 1" text = "Save 1"
[node name="Button4" type="Button" parent="Saves/SavesContainer" unique_id=366833041] [node name="Button4" type="Button" parent="SavesScrollContainer/SavesContainer" unique_id=366833041]
layout_mode = 2 layout_mode = 2
text = "Save 1" text = "Save 1"

View File

@ -9,10 +9,10 @@ signal pressed
@onready var timestamp: Label = %Timestamp @onready var timestamp: Label = %Timestamp
static func construct_save_entry_button(node: Node, save_path: String) -> SaveEntryButton: static func construct_save_entry_button(node: Node, save_path: String, slot_index: int) -> SaveEntryButton:
var entry: SaveEntryButton = load("uid://b3rf5k5u0nh5j").instantiate() var entry: SaveEntryButton = load("uid://b3rf5k5u0nh5j").instantiate()
node.add_child(entry) node.add_child(entry)
entry.apply_save_data(save_path) entry.apply_save_data(save_path, slot_index)
return entry return entry
@ -20,8 +20,7 @@ func _ready() -> void:
button.pressed.connect(pressed.emit) button.pressed.connect(pressed.emit)
func apply_save_data(save_path: String) -> void: func apply_save_data(save_path: String, slot_index: int) -> void:
var modified_time: int = FileAccess.get_modified_time(save_path) var modified_time: int = FileAccess.get_modified_time(save_path)
timestamp.text = str("Timestamp:\n", Time.get_time_dict_from_unix_time(modified_time)) timestamp.text = str("Timestamp:\n", Time.get_time_dict_from_unix_time(modified_time))
var slot_index: int = save_path.split("/")[3].to_int()
save_slot.text = str("Slot: ", slot_index) save_slot.text = str("Slot: ", slot_index)

View File

@ -308,9 +308,8 @@ shadow_enabled = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0000005, 17) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0000005, 17)
flashlight_manager = NodePath("FlashlightManager") flashlight_manager = NodePath("FlashlightManager")
[node name="FlashlightManager" type="Node" parent="PlayerCharacter" index="6" unique_id=583526169 node_paths=PackedStringArray("world")] [node name="FlashlightManager" type="Node" parent="PlayerCharacter" index="6" unique_id=583526169]
script = ExtResource("2_whdyi") script = ExtResource("2_whdyi")
world = NodePath("../..")
metadata/_custom_type_script = "uid://s1vhbwkyewdg" metadata/_custom_type_script = "uid://s1vhbwkyewdg"
[node name="EntranceHall" type="Node3D" parent="." index="5" unique_id=1518685491] [node name="EntranceHall" type="Node3D" parent="." index="5" unique_id=1518685491]
@ -599,46 +598,40 @@ material = ExtResource("4_8xmty")
[node name="godot_plush V2" parent="." index="7" unique_id=1756431274 instance=ExtResource("8_qm8ha")] [node name="godot_plush V2" parent="." index="7" unique_id=1756431274 instance=ExtResource("8_qm8ha")]
transform = Transform3D(-50, 0, 4.371139e-06, 0, 50, 0, -4.371139e-06, 0, -50, 0, 5.628097, 0) transform = Transform3D(-50, 0, 4.371139e-06, 0, 50, 0, -4.371139e-06, 0, -50, 0, 5.628097, 0)
[node name="godot_plush_01" parent="godot_plush V2" index="0" unique_id=1748171278] [node name="godot_plush_01" parent="godot_plush V2" index="0" unique_id=983026135]
visible = false visible = false
[node name="godot_plush_sitted" parent="godot_plush V2" index="1" unique_id=438565683] [node name="godot_plush_sitted" parent="godot_plush V2" index="1" unique_id=1406071640]
visible = false visible = false
[node name="godot_plush_02" parent="godot_plush V2" index="2" unique_id=1913873414] [node name="godot_plush_02" parent="godot_plush V2" index="2" unique_id=815057431]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0025618896, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0025618896, 0)
[node name="Objects" type="Node3D" parent="." index="8" unique_id=249052389] [node name="Objects" type="Node3D" parent="." index="8" unique_id=249052389]
[node name="FlashlightBattery" parent="Objects" index="0" unique_id=1021450063 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery" parent="Objects" index="0" unique_id=1021450063 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.39999998, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.39999998, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
[node name="FlashlightBattery2" parent="Objects" index="1" unique_id=1280919267 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery2" parent="Objects" index="1" unique_id=1280919267 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.19999997, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.19999997, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
[node name="FlashlightBattery3" parent="Objects" index="2" unique_id=180006569 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery3" parent="Objects" index="2" unique_id=180006569 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.9802322e-08, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.9802322e-08, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
[node name="FlashlightBattery4" parent="Objects" index="3" unique_id=2057837844 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery4" parent="Objects" index="3" unique_id=2057837844 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.10000003, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.10000003, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
[node name="FlashlightBattery5" parent="Objects" index="4" unique_id=1599096313 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery5" parent="Objects" index="4" unique_id=1599096313 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.30000004, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.30000004, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
refill_amount = 1.0 refill_amount = 1.0
[node name="FlashlightBattery6" parent="Objects" index="5" unique_id=1386160339 node_paths=PackedStringArray("world", "manager") instance=ExtResource("9_n68sy")] [node name="FlashlightBattery6" parent="Objects" index="5" unique_id=1386160339 node_paths=PackedStringArray("manager") instance=ExtResource("9_n68sy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.50000006, 2.0499978, 5.8) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.50000006, 2.0499978, 5.8)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
refill_amount = 0.5 refill_amount = 0.5
@ -670,19 +663,16 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -5)
top_level = true top_level = true
fov = 65.0 fov = 65.0
[node name="PowerBoxFuse" parent="Objects/LogicCluster" index="1" unique_id=1951712625 node_paths=PackedStringArray("world") instance=ExtResource("10_xp6ux")] [node name="PowerBoxFuse" parent="Objects/LogicCluster" index="1" unique_id=1951712625 instance=ExtResource("10_xp6ux")]
transform = Transform3D(0.96592575, 0, 0.25881898, 0, 1, 0, -0.25881898, 0, 0.96592575, -1.2618543, 2.5, -5.657638) transform = Transform3D(0.96592575, 0, 0.25881898, 0, 1, 0, -0.25881898, 0, 0.96592575, -1.2618543, 2.5, -5.657638)
world = NodePath("../../..")
[node name="FusePickup" parent="Objects/LogicCluster" index="2" unique_id=38269817 node_paths=PackedStringArray("power_box", "world") instance=ExtResource("11_qm8ha")] [node name="FusePickup" parent="Objects/LogicCluster" index="2" unique_id=38269817 node_paths=PackedStringArray("power_box") instance=ExtResource("11_qm8ha")]
transform = Transform3D(0.9999998, 0, 0, 0, 1, 0, 0, 0, 0.9999998, -4.2999997, 2.0499978, -3.9999995) transform = Transform3D(0.9999998, 0, 0, 0, 1, 0, 0, 0, 0.9999998, -4.2999997, 2.0499978, -3.9999995)
power_box = NodePath("../PowerBoxFuse") power_box = NodePath("../PowerBoxFuse")
world = NodePath("../../..")
[node name="Triggers" type="Node3D" parent="." index="9" unique_id=1343544739] [node name="Triggers" type="Node3D" parent="." index="9" unique_id=1343544739]
[node name="FlashlightTrigger" parent="Triggers" index="0" unique_id=1379952044 node_paths=PackedStringArray("world", "manager", "allowed_bodies") instance=ExtResource("10_dy1qy")] [node name="FlashlightTrigger" parent="Triggers" index="0" unique_id=1379952044 node_paths=PackedStringArray("manager", "allowed_bodies") instance=ExtResource("10_dy1qy")]
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
allowed_bodies = [NodePath("../../PlayerCharacter")] allowed_bodies = [NodePath("../../PlayerCharacter")]
change_manager_drain_mode = true change_manager_drain_mode = true
@ -692,9 +682,8 @@ manager_drain_mode = 1
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.200001, 2.4, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.200001, 2.4, 0)
shape = SubResource("BoxShape3D_dy1qy") shape = SubResource("BoxShape3D_dy1qy")
[node name="FlashlightTrigger2" parent="Triggers" index="1" unique_id=275007123 node_paths=PackedStringArray("world", "manager", "allowed_bodies") instance=ExtResource("10_dy1qy")] [node name="FlashlightTrigger2" parent="Triggers" index="1" unique_id=275007123 node_paths=PackedStringArray("manager", "allowed_bodies") instance=ExtResource("10_dy1qy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14, 0, -23) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14, 0, -23)
world = NodePath("../..")
manager = NodePath("../../PlayerCharacter/FlashlightManager") manager = NodePath("../../PlayerCharacter/FlashlightManager")
allowed_bodies = [NodePath("../../PlayerCharacter")] allowed_bodies = [NodePath("../../PlayerCharacter")]
trigger_once = false trigger_once = false