Files
cultivation-world-simulator/docs/i18n-avatar-usage.md
2026-02-06 00:43:08 +08:00

12 KiB
Raw Blame History

Avatar 系统多语言使用指南

本文档说明 Avatar 系统的多语言支持实现。

已完成的改动

1. src/classes/avatar/core.py 重构

修改了两个方法,将硬编码的 "散修" 改为使用翻译函数:

get_sect_str() 方法

修改前

def get_sect_str(self) -> str:
    if self.sect is None:
        return "散修"
    # ...

修改后

def get_sect_str(self) -> str:
    from src.i18n import t
    if self.sect is None:
        return t("Rogue Cultivator")
    # ...

get_sect_rank_name() 方法

修改前

def get_sect_rank_name(self) -> str:
    if self.sect is None or self.sect_rank is None:
        return "散修"
    # ...

修改后

def get_sect_rank_name(self) -> str:
    from src.i18n import t
    if self.sect is None or self.sect_rank is None:
        return t("Rogue Cultivator")
    # ...

2. src/classes/avatar/action_mixin.py 重构

修改了 get_planned_actions_str() 方法:

修改前

def get_planned_actions_str(self: "Avatar") -> str:
    if not self.planned_actions:
        return "无"
    # ...

修改后

def get_planned_actions_str(self: "Avatar") -> str:
    from src.i18n import t
    if not self.planned_actions:
        return t("None")
    # ...

3. src/classes/avatar/info_presenter.py 重构(核心文件)

这是本次重构的核心文件,包含大量用户可见文本的国际化。

3.1 默认值统一翻译

将所有硬编码的默认值改为翻译函数调用:

# "无" -> t("None")
weapon_info = avatar.weapon.get_info() if avatar.weapon else t("None")

# "未知" -> t("Unknown")
alignment_info = avatar.alignment.get_info() if avatar.alignment else t("Unknown")

# "散修" -> t("Rogue Cultivator")
sect = to_avatar.sect.name if to_avatar.sect else t("Rogue Cultivator")

# "弟子" -> t("Disciple")
sect_info["rank"] = t("Disciple")

3.2 分隔符国际化

# 关系分隔符:中文 "" / 英文 "; "
relations_info = t("relation_separator").join(relation_lines) if relation_lines else t("None")

# 元素分隔符:中文 "、" / 英文 ", "
elements = t("element_separator").join(str(e) for e in avatar.root.elements)

# 材料分隔符:中文 "" / 英文 ", "
materials_info = t("material_separator").join([...]) if avatar.materials else t("None")

3.3 info_dict 键名翻译

get_avatar_info() 函数返回的字典,所有键名都改为翻译:

修改前

info_dict = {
    "名字": avatar.name,
    "性别": str(avatar.gender),
    "年龄": str(avatar.age),
    "hp": str(avatar.hp),
    # ... 20+ 项
}

修改后

info_dict = {
    t("Name"): avatar.name,
    t("Gender"): str(avatar.gender),
    t("Age"): str(avatar.age),
    t("HP"): str(avatar.hp),
    t("Spirit Stones"): magic_stone_info,
    t("Relations"): relations_info,
    t("Sect"): sect_info,
    t("Alignment"): alignment_info,
    t("Region"): region_info,
    t("Spirit Root"): root_info,
    t("Technique"): technique_info,
    t("Realm"): cultivation_info,
    t("Traits"): personas_info,
    t("Materials"): materials_info,
    t("Appearance"): appearance_info,
    t("Weapon"): weapon_info,
    t("Auxiliary"): auxiliary_info,
    t("Emotion"): avatar.emotion.value,
    t("Long-term Goal"): avatar.long_term_objective.content if avatar.long_term_objective else t("None"),
    t("Short-term Goal"): avatar.short_term_objective if avatar.short_term_objective else t("None"),
}

if detailed:
    info_dict[t("Current Effects")] = _get_effects_text(avatar)

if avatar.nickname is not None:
    info_dict[t("Nickname")] = avatar.nickname.value

if avatar.spirit_animal is not None:
    info_dict[t("Spirit Animal")] = spirit_animal_info

3.4 格式化字符串翻译

所有复杂的格式化字符串都使用占位符模式:

# 武器信息(带熟练度)
weapon_info = t("{weapon_name}, Proficiency: {proficiency}%", 
               weapon_name=avatar.weapon.get_detailed_info(), 
               proficiency=f"{avatar.weapon_proficiency:.1f}") if avatar.weapon else t("None")

# 观察到的角色
observed.append(t("{name}, Realm: {realm}", 
                 name=other.name, 
                 realm=other.cultivation_progress.get_info()))

# 动作状态
"action_state": t("Performing {action}", action=avatar.current_action_name)

# 灵根元素描述
"desc": t("Contains elements: {elements}", 
         elements=t("element_separator").join(str(e) for e in avatar.root.elements))

# 角色基础描述
lines = [t("【{name}{gender} {age} years old", 
          name=avatar.name, gender=avatar.gender, age=avatar.age)]
lines.append(t("Realm: {realm}", realm=avatar.cultivation_progress.get_info()))
lines.append(t("Identity: {identity}", identity=avatar.get_sect_str()))

3.5 其他字段键名翻译

get_avatar_expanded_info() 中:

info[t("Nearby Avatars")] = observed
info[t("Major Events")] = major_list
info[t("Recent Events")] = minor_list

3.6 复杂信息串翻译

get_other_avatar_info() 函数的整个返回字符串改为使用翻译:

修改前

return (
    f"{to_avatar.name},绰号:{nickname},境界:{to_avatar.cultivation_progress.get_info()}"
    f"关系:{relation},宗门:{sect},阵营:{alignment}"
    f"外貌:{to_avatar.appearance.get_info()},功法:{tech},兵器:{weapon},辅助:{aux}HP{to_avatar.hp}"
)

修改后

return t(
    "{name}, Nickname: {nickname}, Realm: {realm}, Relation: {relation}, Sect: {sect}, Alignment: {alignment}, Appearance: {appearance}, Technique: {technique}, Weapon: {weapon}, Auxiliary: {aux}, HP: {hp}",
    name=to_avatar.name,
    nickname=nickname,
    realm=to_avatar.cultivation_progress.get_info(),
    relation=relation,
    sect=sect,
    alignment=alignment,
    appearance=to_avatar.appearance.get_info(),
    technique=tech,
    weapon=weapon,
    aux=aux,
    hp=to_avatar.hp
)

PO 文件新增条目

共新增约 40+ 条翻译

字段标签23 项)

  • Name - 名字 / Name
  • Gender - 性别 / Gender
  • Age - 年龄 / Age
  • HP - hp / HP
  • Spirit Stones - 灵石 / Spirit Stones
  • Relations - 关系 / Relations
  • Sect - 宗门 / Sect
  • Alignment - 阵营 / Alignment
  • Region - 地区 / Region
  • Spirit Root - 灵根 / Spirit Root
  • Technique - 功法 / Technique
  • Realm - 境界 / Realm
  • Traits - 特质 / Traits
  • Materials - 材料 / Materials
  • Appearance - 外貌 / Appearance
  • Weapon - 兵器 / Weapon
  • Auxiliary - 辅助装备 / Auxiliary
  • Emotion - 情绪 / Emotion
  • Long-term Goal - 长期目标 / Long-term Goal
  • Short-term Goal - 短期目标 / Short-term Goal
  • Current Effects - 当前效果 / Current Effects
  • Nickname - 绰号 / Nickname
  • Spirit Animal - 灵兽 / Spirit Animal

扩展信息标签3 项)

  • Nearby Avatars - 周围角色 / Nearby Avatars
  • Major Events - 重大事件 / Major Events
  • Recent Events - 短期事件 / Recent Events

默认值4 项)

  • None - 无 / None
  • Unknown - 未知 / Unknown
  • Rogue Cultivator - 散修 / Rogue Cultivator
  • Disciple - 弟子 / Disciple

分隔符3 项)

  • relation_separator - / ;
  • element_separator - 、/ ,
  • material_separator - / ,

格式化字符串8 项)

  • {weapon_name}, Proficiency: {proficiency}% - 武器和熟练度
  • {name}, Realm: {realm} - 名字和境界
  • Performing {action} - 正在执行动作
  • Contains elements: {elements} - 包含元素
  • 【{name}】 {gender} {age} years old - 角色基础描述
  • Realm: {realm} - 境界标签
  • Identity: {identity} - 身份标签
  • \n--- Current Effects Detail --- - 效果明细标题
  • No additional effects - 无额外效果
  • 复杂的 get_other_avatar_info 格式化字符串

使用示例

获取角色信息

from src.classes.avatar import Avatar

# 获取基础信息(字典键名自动翻译)
info = avatar.get_avatar_info(detailed=False)
# 中文环境:{"名字": "李云", "性别": "男", ...}
# 英文环境:{"Name": "Li Yun", "Gender": "Male", ...}

# 获取详细信息
detailed_info = avatar.get_avatar_info(detailed=True)

获取角色描述文本

# 获取简要描述
desc = avatar.get_avatar_desc(detailed=False)
# 中文:【李云】 男 23岁\n境界: 筑基初期\n身份: 天剑宗内门弟子
# 英文【Li Yun】 Male 23 years old\nRealm: Foundation Early\nIdentity: ...

# 获取详细描述(包含效果分析)
detailed_desc = avatar.get_avatar_desc(detailed=True)

获取宗门信息

# 获取宗门显示名(含职位)
sect_str = avatar.get_sect_str()
# 中文:天剑宗内门弟子 / 散修
# 英文Heaven Sword Sect Inner Disciple / Rogue Cultivator

# 仅获取职位
rank_str = avatar.get_sect_rank_name()
# 中文:内门弟子 / 散修
# 英文Inner Disciple / Rogue Cultivator

获取计划动作

# 获取计划动作列表字符串
plans_str = avatar.get_planned_actions_str()
# 中文:无 / 1. 修炼 (参数: ...) \n 2. 突破 (参数: ...)
# 英文None / 1. Cultivate (params: ...) \n 2. Breakthrough (params: ...)

设计决策

采用的方案

  1. info_dict 键名直接翻译

    • 原因:返回的字典直接用于显示,翻译键名最直接
    • 方案:使用 t("Key") 作为字典键
    • 优势:一次性解决,无需后续处理
  2. 统一默认值文本

    • "无" → t("None")
    • "未知" → t("Unknown")
    • "散修" → t("Rogue Cultivator")
    • "弟子" → t("Disciple")
    • 优势:保持一致性,易于维护
  3. 格式化字符串使用占位符

    • 复杂字符串拆分为带占位符的模板
    • 使用 t("{key}: {value}", key=k, value=v) 格式
    • 优势:翻译灵活,支持不同语言的语序
  4. 分隔符可配置

    • 中文:顿号(、)、分号(;)、逗号(,)
    • 英文:逗号(, )、分号(;
    • 优势:符合各语言的标点使用习惯

测试

# 切换语言
from src.classes.language import language_manager

# 测试中文
language_manager.set_language("zh-CN")
info = avatar.get_avatar_info()
print(info[t("Name")])  # 输出键名为中文的字典

# 测试英文
language_manager.set_language("en-US")
info = avatar.get_avatar_info()
print(info[t("Name")])  # 输出键名为英文的字典

最佳实践

  1. 新增字段时同步添加翻译

    • info_presenter.py 添加新字段时
    • 使用 t("New Field Label") 作为键名
    • static/locales/{lang}/modules/avatar.po (或 ui.po) 添加对应翻译
  2. 保持命名规范

    • 字段名使用英文,首字母大写(如 "Spirit Root"
    • 默认值使用简短英文(如 "None", "Unknown"
    • 分隔符使用下划线命名(如 "relation_separator"
  3. 格式化字符串命名

    • 使用描述性占位符名称(如 {weapon_name}, {proficiency}
    • 保持占位符在中英文翻译中一致
  4. 测试多语言切换

    • 添加新翻译后测试切换语言是否正常显示
    • 检查分隔符和格式是否符合语言习惯

已完成

  • 3 个文件修改(core.py, action_mixin.py, info_presenter.py
  • 约 40+ 条新翻译(字段标签、默认值、分隔符、格式化字符串)
  • info_dict 完全国际化
  • 所有用户可见文本国际化
  • 统一默认值和分隔符处理

影响范围

Avatar 系统的本地化影响以下功能:

  1. 角色信息展示 - get_avatar_info(), get_avatar_structured_info()
  2. 角色描述生成 - get_avatar_desc(), get_other_avatar_info()
  3. 扩展信息查询 - get_avatar_expanded_info()
  4. 宗门信息显示 - get_sect_str(), get_sect_rank_name()
  5. 计划动作显示 - get_planned_actions_str()

所有这些功能现在都完全支持多语言切换!🎉