D5/Autoload/GameState.gd
2025-05-09 15:40:47 +08:00

161 lines
7.0 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GameState.gd
# Autoload Singleton
# 负责存储和管理核心游戏状态。
# 使用一个中央字典 (_state_data) 来存储所有状态,提高灵活性和可维护性。
# 状态的键名直接来源于初始化数据 (Init_Base.json) 或后续动态添加。
extends Node
# --- 状态信号 ---
# 当游戏状态通过 initialize_for_new_game 初始化完成时发出
signal state_initialized(initial_state: Dictionary)
# 当游戏状态通过 restore_state 从存档恢复完成时发出
signal state_restored(restored_state: Dictionary)
# 当任何状态值通过 set_value 发生改变时发出
signal state_value_changed(key: String, new_value)
# [兼容性信号] 当 "time" 状态值被设置或更新时发出 (保持与旧代码或特定UI的兼容)
signal date_changed(new_date: Dictionary)
# --- 内部状态变量 ---
# 核心状态字典,存储所有动态游戏数据
var _state_data: Dictionary = {}
# 注意:内部的 game_pause 和 is_on_task 变量已被移除,
# 相关状态现在存储在 _state_data["system_status"] 中。
# --- 状态初始化与恢复 ---
# 为新游戏初始化状态。
# 直接使用传入的 initial_settings 字典填充状态。
# 这个函数无需修改,因为它已经正确处理了包含 "system_status" 的 _state_data。
func initialize_for_new_game(initial_settings: Dictionary) -> void:
print("GameState: Initializing state directly from initial settings...")
# 使用深拷贝 (duplicate(true)),确保 GameState 拥有独立的数据副本
_state_data = initial_settings.duplicate(true)
print("GameState: State initialized. Data:", _state_data)
# 发出通用初始化完成信号,传递状态副本
emit_signal("state_initialized", _state_data.duplicate(true))
# [兼容性] 如果存在 "time" 键,则发出 date_changed 信号
if _state_data.has("time") and typeof(_state_data["time"]) == TYPE_DICTIONARY:
emit_signal("date_changed", _state_data["time"].duplicate(true))
# 从加载的数据恢复状态。
# 直接使用 loaded_data 覆盖当前状态。
# 这个函数无需修改,因为它已经正确处理了包含 "system_status" 的 _state_data。
func restore_state(loaded_data: Dictionary) -> void:
print("GameState: Restoring state from loaded data...")
# 同样建议使用深拷贝,虽然从存档加载的数据理论上已经是独立的
_state_data = loaded_data.duplicate(true)
print("GameState: State restored. Data:", _state_data)
# 发出通用恢复完成信号,传递状态副本
emit_signal("state_restored", _state_data.duplicate(true))
# [兼容性] 如果存在 "time" 键,则发出 date_changed 信号
if _state_data.has("time") and typeof(_state_data["time"]) == TYPE_DICTIONARY:
emit_signal("date_changed", _state_data["time"].duplicate(true))
# 获取需要保存到存档的状态。
# 直接返回核心状态字典的副本。
# 这个函数无需修改,因为它返回的是完整的 _state_data。
func get_savable_state() -> Dictionary:
print("GameState: Gathering savable state...")
# 返回深拷贝,确保存档系统拿到的是快照,不会意外修改当前状态
return _state_data.duplicate(true)
# --- 状态访问 (通用 Getter) ---
# 获取指定键 (key) 的状态值。
# 如果键不存在,返回提供的默认值 (default)。
func get_value(key: String, default = null):
# 使用字典的 get 方法,它能优雅地处理键不存在的情况
return _state_data.get(key, default)
# --- 状态修改 (通用 Setter) ---
# 设置指定键 (key) 的状态值。
# 如果值发生变化,会发出 state_value_changed 信号。
# 如果键是 "time",还会额外发出 date_changed 信号。
func set_value(key: String, value) -> void:
var old_value = _state_data.get(key)
# 只有当值确实发生改变时才执行更新和发信号,提高效率
# 注意:对于字典或数组等引用类型,这个比较是浅比较。
if old_value != value:
_state_data[key] = value
#print("GameState: Value changed - ", key, ": ", value)
# 发出通用值变化信号
emit_signal("state_value_changed", key, value)
# [兼容性] 如果更新的是 "time" 键,且值是字典,则发出 date_changed 信号
if key == "time" and typeof(value) == TYPE_DICTIONARY:
emit_signal("date_changed", value.duplicate(true)) # 发送新日期的副本
# --- 系统状态访问辅助函数 (新添加) ---
# 内部辅助函数:安全地获取 "system_status" 字典
# 返回一个字典的副本,如果原始数据无效或不存在,则返回包含默认值的字典
func _get_system_status_dict() -> Dictionary:
var status = get_value("system_status")
# 验证获取到的值是否为字典,如果不是或为 null则返回默认结构
if typeof(status) != TYPE_DICTIONARY:
printerr("GameState: 'system_status' key missing or not a Dictionary in _state_data. Returning default.")
return {"game_pause": false, "is_on_task": false}
# 返回深拷贝以防止外部意外修改原始字典的引用(虽然 get_value 返回的通常是副本或基础类型)
return status.duplicate(true)
# 设置 "system_status" 中的特定键值 (game_pause 或 is_on_task)
# key: 要设置的键名 ("game_pause" 或 "is_on_task")
# value: 要设置的布尔值 (true 或 false)
func set_system_status_value(key: String, value: bool) -> void:
# 获取当前的 system_status 字典的副本
var current_status = _get_system_status_dict()
# 检查键是否是预期的 "game_pause" 或 "is_on_task"
if key == "game_pause" or key == "is_on_task":
# 只有当值实际改变时才更新,以避免不必要的 set_value 调用和信号发射
if current_status.get(key) != value:
current_status[key] = value
# 使用通用的 set_value 来更新整个 system_status 字典
# 这将触发 state_value_changed("system_status", new_dictionary) 信号
set_value("system_status", current_status)
print("GameState: Updated system_status -> ", key, " set to ", value)
# else: # 值未改变,无需操作
# print("GameState: system_status -> ", key, " already set to ", value)
else:
printerr("GameState: Invalid key '", key, "' provided to set_system_status_value. Expected 'game_pause' or 'is_on_task'.")
# 检查游戏是否暂停
# 返回: bool - true 如果游戏已暂停, false 否则
func is_game_paused() -> bool:
# 直接从 _state_data 中读取,通过辅助函数获取字典并访问键值
# 使用 .get() 并提供默认值 false增加健壮性
return _get_system_status_dict().get("game_pause", false)
# 检查是否处于任务中状态
# 返回: bool - true 如果正在进行任务, false 否则
func is_on_task_status() -> bool:
# 直接从 _state_data 中读取
# 使用 .get() 并提供默认值 false增加健壮性
return _get_system_status_dict().get("is_on_task", false)
# 暂停游戏
func pause_game():
# 调用新的辅助函数来修改 _state_data 中的 "game_pause" 值
set_system_status_value("game_pause", true)
# 恢复游戏
func resume_game():
# 调用新的辅助函数来修改 _state_data 中的 "game_pause" 值
set_system_status_value("game_pause", false)