105 lines
3.4 KiB
GDScript
105 lines
3.4 KiB
GDScript
## 存档面板(挂载于 SavePanel.tscn)。
|
|
## 两级浏览:左侧存档组列表 → 右侧该组槽位列表。
|
|
## 存档模式(游戏内):点"新建存档"每次创建新槽位;读档模式(主菜单):点槽位读档。
|
|
extends Panel
|
|
|
|
## 面板模式。
|
|
enum Mode { SAVE, LOAD }
|
|
|
|
## 请求关闭面板(返回上级界面)。
|
|
signal save_panel_esc_pressed
|
|
## 请求读档(LOAD 模式点槽位时发出)。
|
|
signal load_requested(profile_id: int, slot_name: String)
|
|
|
|
## 槽位条目场景。
|
|
const SAVE_SLOT_SCENE := preload("res://src/UI/Panels/SaveSlot.tscn")
|
|
## 组条目场景。
|
|
const SAVE_GROUP_SCENE := preload("res://src/UI/Panels/SaveGroup.tscn")
|
|
|
|
@onready var group_container: VBoxContainer = %GroupContainer
|
|
@onready var slot_list: VBoxContainer = %SlotItems
|
|
@onready var new_slot_button: Button = %Button_NewSlot
|
|
|
|
## 当前模式。
|
|
var mode: Mode = Mode.LOAD
|
|
## 当前浏览的存档组 ID(0 = 未选中)。
|
|
var _current_profile: int = 0
|
|
|
|
func open_load() -> void:
|
|
mode = Mode.LOAD
|
|
new_slot_button.visible = false
|
|
refresh_groups()
|
|
visible = true
|
|
|
|
func open_save() -> void:
|
|
mode = Mode.SAVE
|
|
new_slot_button.visible = true
|
|
refresh_groups()
|
|
visible = true
|
|
|
|
## 刷新左侧存档组列表(调用 SaveSystem.get_profiles() 动态创建条目)。
|
|
func refresh_groups() -> void:
|
|
_clear_children(group_container)
|
|
for group in SaveSystem.get_profiles():
|
|
var item := SAVE_GROUP_SCENE.instantiate()
|
|
item.set_data(group)
|
|
item.group_selected.connect(_on_group_selected)
|
|
item.delete_requested.connect(_on_group_delete_requested)
|
|
group_container.add_child(item)
|
|
# 校验当前选中组:已被删除则复位并清空右列
|
|
if _current_profile == 0 or _current_profile not in _get_profile_ids():
|
|
_current_profile = 0
|
|
refresh_slots(_current_profile)
|
|
|
|
## 当前所有组的 id 列表。
|
|
func _get_profile_ids() -> Array[int]:
|
|
var ids: Array[int] = []
|
|
for group in SaveSystem.get_profiles():
|
|
ids.append(int(group["id"]))
|
|
return ids
|
|
|
|
## 刷新右侧槽位列表(profile_id 为 0 时清空)。
|
|
func refresh_slots(profile_id: int) -> void:
|
|
_clear_children(slot_list)
|
|
if profile_id == 0:
|
|
return
|
|
for slot in SaveSystem.list_slots(profile_id):
|
|
var item := SAVE_SLOT_SCENE.instantiate()
|
|
item.set_data(profile_id, slot["name"], slot["date"])
|
|
item.load_requested.connect(_on_slot_load_requested)
|
|
item.delete_requested.connect(_on_slot_delete_requested)
|
|
slot_list.add_child(item)
|
|
|
|
|
|
func _on_group_selected(profile_id: int) -> void:
|
|
_current_profile = profile_id
|
|
refresh_slots(profile_id)
|
|
|
|
func _on_group_delete_requested(profile_id: int) -> void:
|
|
# 条目已自行删数据并销毁,这里只校正选中状态
|
|
if _current_profile == profile_id:
|
|
_current_profile = 0
|
|
refresh_slots(_current_profile)
|
|
|
|
func _on_slot_load_requested(profile_id: int, slot_name: String) -> void:
|
|
load_requested.emit(profile_id, slot_name)
|
|
|
|
func _on_slot_delete_requested(profile_id: int, slot_name: String) -> void:
|
|
SaveSystem.delete_slot(profile_id, slot_name)
|
|
refresh_slots(profile_id)
|
|
|
|
## 清空容器的所有子节点。
|
|
func _clear_children(container: Node) -> void:
|
|
for child in container.get_children():
|
|
container.remove_child(child)
|
|
child.queue_free()
|
|
|
|
func _on_SavePanel_Esc_ButtonUp() -> void:
|
|
save_panel_esc_pressed.emit()
|
|
|
|
func _on_SavePanel_NewSlot_ButtonUp() -> void:
|
|
if _current_profile == 0:
|
|
return
|
|
SaveSystem.save(_current_profile)
|
|
refresh_slots(_current_profile)
|