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>
73 lines
3.1 KiB
GDScript
73 lines
3.1 KiB
GDScript
# 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") 注册 <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" % LocalePath,LocalePath = "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 ""
|