# 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()) # --- 40250 client (pack/Index + .eix/.epk), docs/PORT-PLAN.md 2R item 6 / 2D --- # 解析顺序:环境变量 MT_40250_CLIENT;开发树 res://../../40250/Server Client TMP4/Client。 static func client_path() -> String: var env := OS.get_environment("MT_40250_CLIENT") if env != "": return env return ProjectSettings.globalize_path("res://../../40250/Server Client TMP4/Client").simplify_path() # 按 40250 PackInitialize("pack") 注册 /pack;只注册一次,之后返回首次结果。 static func pack_ready() -> bool: if not ClassDB.class_exists("Metin2Pack"): return false return bool(ClassDB.class_call_static("Metin2Pack", "initialize", client_path())) # 40250 的 locale 文件(CPythonApplication::Create: "%s/item_proto" % LocalePath,LocalePath = "locale/"), # 走 pack://;该语言没有时回退 en。pack 没就绪返回 ""。 static func locale_file(name: String, lang: String = "en") -> String: if not pack_ready(): return "" for l in [lang, "en"]: var p := "pack://locale/%s/%s" % [l, name] if bool(ClassDB.class_call_static("Metin2Pack", "exists", "locale/%s/%s" % [l, name])): return p return ""