Files
mtgodot-poc/project/asset_root.gd
T
shenleiandClaude Opus 5 232d0461be port 2D step 2: 40250 item_proto/mob_proto through CLZO and pack://locale/<lang>/
proto.cpp reads the 40250 MIPX/MMPT tables with the ported CLZO/TEA (156-byte
TItemTable, 255-byte SMobTable), replacing the m2dev XChaCha20 236/335 reader.
Names follow CItemData::GetName / GetMonsterName (szLocaleName, cp1252).
GDScript callers load AssetRoot.locale_file() = pack://locale/en/<name>, which
makes the EterPack chain runtime-reachable; port-map entries for the functions
a coverage run hit move to PORTED/ADAPTED.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 01:34:08 +09:00

73 lines
3.1 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.
# 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.zipAssetPack)把资源放到 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") 注册 <client>/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" % LocalePathLocalePath = "locale/<lang>"),
# 走 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 ""