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

275 lines
7.0 KiB
Markdown
Raw Permalink 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.
# Effect 系统多语言使用指南
本文档说明 Effect 系统的多语言支持实现。
## 已完成的改动
### 1. `src/classes/effect/desc.py` 重构
将硬编码的中文映射字典改为使用翻译函数:
#### **Effect 名称翻译**
**修改前**
```python
EFFECT_DESC_MAP = {
"extra_max_hp": "最大生命值",
"extra_battle_strength_points": "战力点数",
# ... 30+ 项
}
```
**修改后**
```python
def get_effect_desc(effect_key: str) -> str:
"""获取 effect 的描述名称(支持国际化)"""
from src.i18n import t
msgid_map = {
"extra_max_hp": "effect_extra_max_hp",
"extra_battle_strength_points": "effect_extra_battle_strength_points",
# ...
}
msgid = msgid_map.get(effect_key, effect_key)
return t(msgid)
```
#### **Action 名称翻译**
**修改前**
```python
ACTION_DESC_MAP = {
"DualCultivation": "双修",
"DevourMortals": "吞噬凡人",
}
```
**修改后**
```python
def get_action_short_name(action_name: str) -> str:
"""获取 action 的简短名称(复用 Action 系统翻译)"""
from src.i18n import t
msgid = f"action_{action_name.lower()}_short_name"
return t(msgid)
```
#### **条件表达式翻译(简化方案)**
采用简化方案,保持代码形式,仅翻译前缀:
```python
def translate_condition(condition: str) -> str:
"""将代码形式的条件表达式转换为易读描述"""
from src.i18n import t
if not condition:
return t("Conditional effect")
# 特殊模式检测
if "avatar.personas" in condition and "any" in condition:
m = re.search(r'p\.name\s*==\s*["\'](.*?)["\']', condition)
if m:
return t("Has [{trait}] trait", trait=m.group(1))
# 保持代码形式
return t("When {condition}", condition=condition)
```
#### **Effect 文本格式化**
```python
def format_effects_to_text(effects: dict[str, Any] | list[dict[str, Any]]) -> str:
"""将 effects 字典转换为易读的文本描述"""
from src.i18n import t
# ... 处理逻辑 ...
# 使用翻译的分隔符
sep = t("effect_separator") # "" / "; "
text = sep.join(desc_list)
if effects.get("when"):
cond = translate_condition(str(effects["when"]))
return t("[{condition}] {effects}", condition=cond, effects=text)
return text
```
### 2. `src/classes/effect/mixin.py` 重构
修改 `get_effect_breakdown()` 方法,使用翻译函数:
**修改前**
```python
if self.sect:
_collect(f"宗门【{self.sect.name}", source_obj=self.sect)
if self.technique:
_collect(f"功法【{self.technique.name}", source_obj=self.technique)
_collect("灵根", source_obj=self.root)
# ...
```
**修改后**
```python
from src.i18n import t
if self.sect:
label = t("Sect [{name}]", name=self.sect.name)
_collect(label, source_obj=self.sect)
if self.technique:
label = t("Technique [{name}]", name=self.technique.name)
_collect(label, source_obj=self.technique)
_collect(t("Spirit Root"), source_obj=self.root)
# ...
```
## PO 文件新增条目
共新增约 **60+ 条翻译**
### Effect 名称28 项)
- `effect_extra_max_hp` - 最大生命值 / Max HP
- `effect_extra_battle_strength_points` - 战力点数 / Battle Strength
- `effect_extra_cultivate_exp` - 修炼经验 / Cultivation Experience
- ... 等 25 项
### Action 简短名称2 项)
- `action_dualcultivation_short_name` - 双修 / Dual Cultivation
- `action_devourmortals_short_name` - 吞噬凡人 / Devour Mortals
### 格式化相关4 项)
- `action_list_separator` - 、 / ,
- `effect_separator` - / ;
- `Special effect (dynamic)` - 特殊效果(动态)
- 条件翻译相关
### Effect 来源标签9 项)
- `Sect [{name}]` - 宗门【{name}】
- `Technique [{name}]` - 功法【{name}】
- `Spirit Root` - 灵根
- `Trait [{name}]` - 特质【{name}】
- `Weapon [{name}]` - 兵器【{name}】
- `Auxiliary [{name}]` - 辅助【{name}】
- `Spirit Animal [{name}]` - 灵兽【{name}】
- `Heaven and Earth Phenomenon` - 天地灵机
- `Elixir [{name}]` - 丹药【{name}】
## 使用示例
### 获取 Effect 描述
```python
from src.classes.effect.desc import get_effect_desc
# 自动根据当前语言返回翻译
desc = get_effect_desc("extra_max_hp")
# 中文: "最大生命值"
# 英文: "Max HP"
```
### 格式化 Effect 文本
```python
from src.classes.effect.desc import format_effects_to_text
effects = {
"extra_max_hp": 100,
"extra_battle_strength_points": 3
}
text = format_effects_to_text(effects)
# 中文: "最大生命值 +100战力点数 +3"
# 英文: "Max HP +100; Battle Strength +3"
```
### 带条件的 Effect
```python
effects = {
"extra_battle_strength_points": 3,
"when": "avatar.weapon.type == WeaponType.SWORD"
}
text = format_effects_to_text(effects)
# 中文: "[当avatar.weapon.type == WeaponType.SWORD] 战力点数 +3"
# 英文: "[When avatar.weapon.type == WeaponType.SWORD] Battle Strength +3"
```
### 获取 Effect 来源明细
```python
# 在 Avatar 类中自动使用翻译
breakdown = avatar.get_effect_breakdown()
# 返回: [
# ("宗门【天剑宗】", {"extra_battle_strength_points": 2}),
# ("功法【太玄真经】", {"extra_cultivate_exp": 50}),
# ("灵根", {"extra_max_hp": 30}),
# ...
# ]
```
## 设计决策
### ✅ 采用的简化方案
1. **条件表达式保持代码形式**
- 原因:条件表达式翻译复杂且容易出错
- 方案:仅翻译前缀"当" / "When",保持表达式本身为代码
- 优势:简单可靠,对开发者友好
2. **百分比和数值符号不翻译**
- 原因:`+`, `%`, `-` 等符号国际通用
- 方案:保持原样,节省翻译工作量
3. **Action 名称复用现有翻译**
- 原因Action 系统已完成国际化
- 方案:使用统一命名规则 `action_{name}_short_name`
- 优势:避免重复维护
### 🎯 核心改动点
- ✅ 2 个文件修改(`desc.py`, `mixin.py`
- ✅ 约 60+ 条新 msgid
- ✅ 难度较低,与 Action 系统模式一致
## 测试
```python
# 切换语言
from src.classes.language import language_manager
# 测试中文
language_manager.set_language("zh-CN")
from src.classes.effect.desc import get_effect_desc
print(get_effect_desc("extra_max_hp")) # 输出:最大生命值
# 测试英文
language_manager.set_language("en-US")
print(get_effect_desc("extra_max_hp")) # 输出Max HP
```
## 最佳实践
1. **新增 Effect 时同步添加翻译**
-`consts.py` 定义新 effect
-`desc.py``get_effect_desc()` 添加 msgid 映射
-`static/locales/{lang}/modules/effect.po` 添加中英文翻译
2. **保持命名规范**
- Effect msgid: `effect_{effect_key}`
- Action msgid: `action_{action_name}_short_name`
3. **测试多语言切换**
- 添加新翻译后测试切换语言是否正常显示
## 已完成
- ✅ 28 个 Effect 名称国际化
- ✅ 9 个 Effect 来源标签国际化
- ✅ 条件表达式简化翻译方案
- ✅ Action 名称复用现有系统
- ✅ 格式化函数国际化