Files
mtgodot-poc/project/locale.gd
T

119 lines
3.7 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.
# Locale —— EterLocale 字符串表(`locale/locale/<lang>/*.txt`KEY\tVALUEUTF-8)。
# Godot 原生处理 UTF-8 + 拉丁/西里尔/希腊/阿拉伯;CJK 需外挂字体(apply_font)。
# 用 preload("res://locale.gd").new()setup() 后 t("KEY", [args]).
extends RefCounted
var _lang := "zh"
var _tab := {} # KEY -> value
var _item_names := {} # int vnum -> String name
var _mob_names := {} # int vnum -> String name
var _base := ""
static func get_default_lang() -> String:
var env_lang := OS.get_environment("MT_LOCALE").strip_edges().to_lower()
if not env_lang.is_empty():
return env_lang
return "zh"
func setup(assets_root: String, lang := "") -> void:
_base = assets_root.path_join("locale/locale")
if lang.is_empty():
lang = get_default_lang()
set_lang(lang)
func set_lang(lang: String) -> void:
_lang = lang
_tab.clear()
_item_names.clear()
_mob_names.clear()
var dir := _base.path_join(lang)
if not DirAccess.dir_exists_absolute(dir):
push_warning("[locale] no such lang: " + dir)
return
for f in ["locale_interface.txt", "locale_game.txt", "itemdesc.txt", "skilldesc.txt"]:
_load_table(dir.path_join(f))
_load_name_table(dir.path_join("item_names.txt"), _item_names)
_load_name_table(dir.path_join("mob_names.txt"), _mob_names)
func _load_name_table(path: String, target_dict: Dictionary) -> void:
if not FileAccess.file_exists(path):
return
var fa := FileAccess.open(path, FileAccess.READ)
if fa == null:
return
while not fa.eof_reached():
var line := fa.get_line().strip_edges()
if line.is_empty() or line.begins_with("#") or line.begins_with("VNUM"):
continue
var tab := line.find("\t")
if tab < 0:
tab = line.find(" ")
if tab < 0:
continue
var k_str := line.substr(0, tab).strip_edges()
var val := line.substr(tab + 1).strip_edges()
if k_str.is_valid_int():
var vnum := int(k_str)
target_dict[vnum] = val
_tab["ITEM_%d" % vnum] = val
func item_name(vnum: int, fallback: String = "") -> String:
if _item_names.has(vnum):
return String(_item_names[vnum])
return fallback if not fallback.is_empty() else ("物品 #%d" % vnum)
func mob_name(vnum: int, fallback: String = "") -> String:
if _mob_names.has(vnum):
return String(_mob_names[vnum])
return fallback if not fallback.is_empty() else ("怪物 #%d" % vnum)
func has_item_name(vnum: int) -> bool:
return _item_names.has(vnum)
func has_mob_name(vnum: int) -> bool:
return _mob_names.has(vnum)
func _load_table(path: String) -> void:
if not FileAccess.file_exists(path):
return
var fa := FileAccess.open(path, FileAccess.READ)
if fa == null:
return
while not fa.eof_reached():
var line := fa.get_line()
if line.is_empty() or line.begins_with("#"):
continue
var tab := line.find("\t")
if tab < 0:
continue
var key := line.substr(0, tab).strip_edges()
var val := line.substr(tab + 1).strip_edges()
if not key.is_empty():
_tab[key] = val
func lang() -> String:
return _lang
func has(key: String) -> bool:
return _tab.has(key)
# t("SELECT_LEVEL") -> "Level"t("AFF_LOVE_POINT", [42]) -> "Love points: 42%"
# 缺失时返回 "<KEY>"(开发期一眼可见)。
func t(key: String, args: Array = []) -> String:
if not _tab.has(key):
return "<" + key + ">"
var s: String = _tab[key]
if args.is_empty():
return s
return s % args if args.size() > 1 else (s % args[0])
# 给一个 Control / Window 挂 CJK(或其它)字体。ttf_path 为空则不动。
func apply_font(node: Control, ttf_path: String, size := 0) -> void:
if ttf_path.is_empty() or not FileAccess.file_exists(ttf_path):
return
var f := FontFile.new()
f.load_dynamic_font(ttf_path)
node.add_theme_font_override("font", f)
if size > 0:
node.add_theme_font_size_override("font_size", size)