D5/Autoload/InitialDataManager.gd

124 lines
4.6 KiB
GDScript

# InitialDataManager.gd
# Autoload Singleton
# 负责加载和管理游戏的基础静态配置数据 (来自 res://Data/)。
# 提供对这些数据的只读访问接口。
extends Node
# --- 内部数据缓存 ---
var _settings_data: Dictionary = {}
var _task_development_data: Dictionary = {}
var _npc_data: Dictionary = {} # MODIFIED: 新增NPC数据缓存
var _is_data_loaded: bool = false
const DATA_DIR = "res://Data/"
# --- 对外接口 (Public API / Data Access Functions) ---
# 确保所有初始数据已加载。通常由 InitializationManager 调用。
# 返回加载是否成功。
func ensure_data_loaded() -> bool:
if _is_data_loaded:
return true # 避免重复加载
print("InitialDataManager: Loading initial data...")
# 依次加载所有 JSON 文件
var success = true
success = success and _load_json_data("Init_Base.json", "_settings_data", false)
success = success and _load_json_data("task_development.json", "_task_development_data", false)
success = success and _load_json_data("npc.json", "_npc_data", false) # MODIFIED: 新增加载npc.json
if success:
_is_data_loaded = true
print("InitialDataManager: All initial data loaded successfully.")
return true
else:
printerr("InitialDataManager: Failed to load one or more initial data files.")
# 清理可能部分加载的数据,确保状态一致性
_clear_loaded_data()
return false
# 获取 settings.json 中的初始游戏设定 (如初始资金、年份等)。
# 返回的数据应视为只读。
func get_starting_settings() -> Dictionary:
if not _is_data_loaded:
printerr("InitialDataManager: Attempted to get settings before data was loaded!")
return {} # 返回空字典避免崩溃,但这是一个错误状态
return _settings_data.duplicate(true)
# 获取 task_development.json 中的所有数据 (平台、玩法、主题等)。
# 返回的数据应视为只读。
func get_task_development_data() -> Dictionary:
if not _is_data_loaded:
printerr("InitialDataManager: Attempted to get task development data before data was loaded!")
return {}
# 返回副本以强调只读性
return _task_development_data.duplicate(true)
# NEW: 获取 npc.json 中的所有数据。
# 返回的数据应视为只读,用于构建初始状态。
func get_npc_initial_data() -> Dictionary:
if not _is_data_loaded:
printerr("InitialDataManager: Attempted to get NPC data before data was loaded!")
return {}
return _npc_data.duplicate(true)
# --- 内部辅助函数 ---
# 从指定文件加载 JSON 数据并存储到目标变量
# target_var_name 是存储数据的成员变量名 (字符串)
# expect_array 指定期望的数据是数组 (true) 还是字典 (false)
func _load_json_data(filename: String, target_var_name: String, expect_array: bool = true) -> bool:
var file_path = DATA_DIR.path_join(filename)
if not FileAccess.file_exists(file_path):
printerr("InitialDataManager: File not found: " + file_path)
return false
var file = FileAccess.open(file_path, FileAccess.READ)
if file == null:
printerr("InitialDataManager: Failed to open file: " + file_path + " Error code: " + str(FileAccess.get_open_error()))
return false
var json_string = file.get_as_text()
file.close()
var parse_result = JSON.parse_string(json_string)
if parse_result == null:
printerr("InitialDataManager: Failed to parse JSON from file: " + file_path + ". Check JSON syntax.")
return false
# 类型检查
if expect_array and not typeof(parse_result) == TYPE_ARRAY:
printerr("InitialDataManager: Invalid data format in " + file_path + ". Expected Array, got " + str(typeof(parse_result)))
return false
if not expect_array and not typeof(parse_result) == TYPE_DICTIONARY:
printerr("InitialDataManager: Invalid data format in " + file_path + ". Expected Dictionary, got " + str(typeof(parse_result))) # 确保npc.json顶层是字典
return false
# 使用 set() 通过变量名字符串来设置成员变量的值
set(target_var_name, parse_result)
print("InitialDataManager: Successfully loaded and parsed " + filename)
return true
# 通用函数:在字典数组中通过 id 查找项 (线性查找)
func _find_item_by_id(data_array: Array, id: String): # Removed -> Dictionary
if id == null or id.is_empty():
return null
for item in data_array:
# 确保 item 是字典并且有 'id' 键
if typeof(item) == TYPE_DICTIONARY and item.has("id") and item["id"] == id:
return item # 找到匹配项
return null # 未找到
# 清理所有加载的数据(用于加载失败时)
func _clear_loaded_data() -> void:
_settings_data = {}
_task_development_data = {}
_npc_data = {} # MODIFIED: 清理NPC数据
_is_data_loaded = false