# AssetRoot —— Metin2 资源根目录的唯一解析点。 # # 资源(`.gr2` / `.dds` / `locale` / `OutdoorA1` / `uiscript` …)不进版本库。 # 解析顺序: # 1. 环境变量 MT_ASSETS(绝对路径) # 2. res://../assets —— 开发树(仓库根的 assets/) # 3. <可执行文件>/../Resources/assets —— 打包进 .app 内 # 4. <.app 同级>/assets —— .app 旁边放一份 # 都没有就返回 res://../assets(调用方自行 warn)。 # # var root := AssetRoot.path() # var il := AssetRoot.sub("locale/locale/common/item_list.txt") # if AssetRoot.available(): ... class_name AssetRoot extends RefCounted static func _candidates() -> Array: var out: Array = [] var env := OS.get_environment("MT_ASSETS") if env != "": out.append(env) # 挂载的 assets.zip(AssetPack)把资源放到 res://assets —— 移动端主路径。 # 用 asset_index.txt 作为「pack 已挂载」信号(空的 project/assets/ 占位目录不算)。 if FileAccess.file_exists("res://assets/asset_index.txt"): out.append("res://assets") out.append(ProjectSettings.globalize_path("res://../assets")) var exe := OS.get_executable_path() if exe != "": var exe_dir := exe.get_base_dir() # .../mtgodot-poc.app/Contents/MacOS out.append(exe_dir.path_join("../Resources/assets").simplify_path()) out.append(exe_dir.path_join("../../../assets").simplify_path()) # 与 .app 同级 out.append(exe_dir.path_join("assets")) # 与裸可执行文件同级 return out static func path() -> String: for c in _candidates(): if DirAccess.dir_exists_absolute(c): return c return ProjectSettings.globalize_path("res://../assets") # 资源根下的子路径(用 path_join,跨平台)。 static func sub(rel: String) -> String: return path().path_join(rel) # 资源目录是否真的存在(缺资源的测试据此跳过)。 static func available() -> bool: return DirAccess.dir_exists_absolute(path())