TH1/Tools/multilingual_check/translate_8new.py
2026-05-15 19:36:39 +08:00

253 lines
13 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# -*- coding: utf-8 -*-
"""
为 Multilingual.xlsx 中 8 条新条目填 TW/EN/JP/KR 翻译。
目标 ID: 19855, 19857, 19862, 19869, 19872, 19874, 19875, 19876
跳过: 19871(只填了EN), 19873(已 4 语齐全)
规则:
- 严格保留所有 **<...>** 标签的数量与位置(标签内文本可翻译)
- 术语沿用项目内已有译文(参考 19871 V1.4.0 公告 + 19873 + Dashboard/techs.json
- 韩文权威: 플랑드르(不是 플란드르) / 레밀리아 / 优曇華院 - 鈴仙=레이센 우동게인 이나바
- 印度地名 "乌甲因" 是误音译, 正确是 Ujjain(乌贾因), 直接翻为正确地名
"""
import re
import shutil
import sys
import io
from openpyxl import load_workbook
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
XLSX = r'C:\TH1\TH1\Tools\Multilingual.xlsx'
# ---------------- 翻译数据 ----------------
# 每条: {ID: (TW, EN, JP, KR)}
TRANSLATIONS = {
'19855': (
'蕾米莉亞斯卡雷特',
'Remilia Scarlet',
'レミリア・スカーレット',
'레밀리아 스칼렛',
),
'19857': (
'芙蘭朵露斯卡雷特',
'Flandre Scarlet',
'フランドール・スカーレット',
'플랑드르 스칼렛',
),
# 乌甲因 = 印度地名 Ujjain 误音译, 直接翻为正确地名
'19862': (
'烏賈因',
'Ujjain',
'ウッジャイン',
'우자인',
),
# 19869 = 铃仙称号. 沿用 19871 V1.4.0 公告同名术语 "The Empire's Eye of Madness"
# 而非用户提示里的 "Imperial Eye of Madness", 以保持与 19876 英雄技能描述一致
# (两者指代同一英雄, 不能英文出现两种称号)
'19869': (
'帝國的狂氣之瞳 鈴仙・優曇華院・因幡',
"The Empire's Eye of Madness: Reisen Udongein Inaba",
'帝国の狂気の瞳 鈴仙・優曇華院・イナバ',
'제국의 광기의 눈동자: 레이센 우동게인 이나바',
),
# 19872: 含 3 个标签 **<军港>**, **<通用行动点>**, **<军港>**
# 军港=Naval Port/軍港/軍港/군항
# 通用行动点=通用行動點/General Action Points/汎用行動ポイント/범용 행동 포인트
'19872': (
'為處於**<軍港>**的單位恢復1點**<通用行動點>**,每回合上限一次。提供額外防禦。每座城市僅能建造一座**<軍港>**,且僅能建造在港口附近。',
'Restore 1 **<General Action Point>** to units stationed in a **<Naval Port>**, up to once per turn. Provides additional defense. Each city can construct only one **<Naval Port>**, and it must be built near a harbor.',
'**<軍港>**にいるユニットに**<汎用行動ポイント>**を1点回復する毎ターン1回まで。追加の防御を提供する。各都市につき**<軍港>**は1つしか建設できず、港の近くにのみ建設できる。',
'**<군항>**에 있는 유닛에게 **<범용 행동 포인트>**를 1점 회복시킨다(매 턴 1회까지). 추가 방어를 제공한다. 각 도시는 **<군항>**을 하나만 건설할 수 있으며, 항구 근처에만 건설할 수 있다.',
),
# 19874: 北纬27的日晷之王 - 丰聪耳神子相关称号
# "北纬27" 实际为 "北纬27度" 的简写形式; 翻译时英日韩都补"度"显得自然
'19874': (
'北緯27度的日晷之王',
'Sundial King of the 27th Parallel North',
'北緯27度の日時計の王',
'북위 27도의 해시계 왕',
),
# 19875: 含 1 个标签 **<军港>** (注意中文末尾无句号)
# 沿用 Multilingual_P2 修复后版本: "可以建造**<军港>**。所有单位获得海洋防御"
'19875': (
'可以建造**<軍港>**。所有單位獲得海洋防禦。',
'Can construct **<Naval Port>**. All units gain Naval Defense.',
'**<軍港>**を建造可能。全ユニットが海洋防御を獲得する。',
'**<군항>** 건설 가능. 모든 유닛이 해양 방어를 획득한다.',
),
# 19876: 铃仙英雄技能描述. 严格沿用 19871 V1.4.0 公告中铃仙部分的术语
# 注意中文里 Lv.3 段写的是 **<幻想视差>** 而非 **<幻象视差>** (19871 是幻象视差,
# 这里"幻想"应是错字, 但既然内部文本可翻译, 我们翻译为 Phantom Parallax 与 19871 一致)
# 另外最后 **<月兔幻想>** 也是错字应为 **<月兔幻象>** -> Moon Rabbit Phantom
# 19876 中文标签清单(19个):
# **<帝国的狂气之瞳:铃仙·优昙华院·因幡>**
# **<-------- Lv.1 -------->**
# **<[基础属性]>**
# **<[能力:战地协同]>**
# **<协同标的>** x2
# **<-------- Lv.2 -------->**
# **<[基础属性]>**
# **<[能力:幻视调率]>**
# **<月兔幻象>**
# **<战地协同>**
# **<-------- Lv.3 -------->**
# **<[基础属性]>**
# **<[能力:幻想视差]>**
# **<月兔幻象>**
# **<-------- Lv.4 -------->**
# **<[基础属性]>**
# **<[能力:狂视调率]>**
# **<月兔幻象>** x2
'19876': (
# TW
'**<帝國的狂氣之瞳:鈴仙・優曇華院・因幡>**<br> '
'**<-------- Lv.1 -------->**<br> '
'**<[基礎屬性]>**10HP/2攻/1防/2移動力/2射程<br> '
'**<[能力:戰地協同]>**攻擊單位時將施加一層**<協同標的>**持續1回合。攻擊帶有**<協同標的>**的目標時每層使得本次攻擊力提升0.5。<br> '
'**<-------- Lv.2 -------->**<br> '
'**<[基礎屬性]>**15HP/2攻/2防/2移動力/2射程<br> '
'**<[能力:幻視調率]>**擊殺敵方單位時在其位置生成1個看似與鈴仙完全相同的**<月兔幻象>**。幻象繼承鈴仙的**<戰地協同>**能力,但無法造成傷害,並且受到任意攻擊後立刻陣亡。<br> '
'**<-------- Lv.3 -------->**<br> '
'**<[基礎屬性]>**20HP/3攻/2防/2移動力/2射程<br> '
'**<[能力:幻象視差]>**鈴仙攻擊目標前,附近所有**<月兔幻象>**會對該目標進行一輪齊射。<br> '
'**<-------- Lv.4 -------->**<br> '
'**<[基礎屬性]>**30HP/4攻/3防/2移動力/2射程<br> '
'**<[能力:狂視調率]>**所有**<月兔幻象>**具有本體50%的攻擊力。幻象消滅單位時,也可以創造新的**<月兔幻象>**。<br>',
# EN (术语严格沿用 19871)
"**<The Empire's Eye of Madness: Reisen Udongein Inaba>**<br> "
"**<-------- Lv.1 -------->**<br> "
"**<[Base Stats]>**10HP / 2 ATK / 1 DEF / 2 MOV / 2 RNG<br> "
"**<[Ability: Battlefield Synergy]>**When attacking a unit, applies one stack of **<Synergy Mark>** for 1 turn. When attacking a target that bears **<Synergy Mark>**, each stack increases this attack's damage by 0.5.<br> "
"**<-------- Lv.2 -------->**<br> "
"**<[Base Stats]>**15HP / 2 ATK / 2 DEF / 2 MOV / 2 RNG<br> "
"**<[Ability: Illusion Tuning]>**When killing an enemy unit, generates 1 **<Moon Rabbit Phantom>** identical in appearance to Reisen at its position. The phantom inherits Reisen's **<Battlefield Synergy>** ability but cannot deal damage, and dies instantly upon receiving any attack.<br> "
"**<-------- Lv.3 -------->**<br> "
"**<[Base Stats]>**20HP / 3 ATK / 2 DEF / 2 MOV / 2 RNG<br> "
"**<[Ability: Phantom Parallax]>**Before Reisen attacks a target, all nearby **<Moon Rabbit Phantom>**s fire a salvo at that target.<br> "
"**<-------- Lv.4 -------->**<br> "
"**<[Base Stats]>**30HP / 4 ATK / 3 DEF / 2 MOV / 2 RNG<br> "
"**<[Ability: Mad Tuning]>**All **<Moon Rabbit Phantom>**s have 50% of the main body's attack power. When a phantom destroys a unit, it can also create a new **<Moon Rabbit Phantom>**.<br>",
# JP
'**<帝国の狂気の瞳:鈴仙・優曇華院・イナバ>**<br> '
'**<-------- Lv.1 -------->**<br> '
'**<[基本ステータス]>**10HP/攻撃2/防御1/移動2/射程2<br> '
'**<[能力:戦地連携]>**ユニットを攻撃する際、**<連携対象>**を1層付与し、1ターン持続する。**<連携対象>**を持つ目標を攻撃する時、1層ごとに本攻撃の攻撃力が0.5上昇する。<br> '
'**<-------- Lv.2 -------->**<br> '
'**<[基本ステータス]>**15HP/攻撃2/防御2/移動2/射程2<br> '
'**<[能力:幻視調律]>**敵ユニットを撃破した時、その位置に鈴仙とまったく同じ姿の**<月兎幻影>**を1体生成する。幻影は鈴仙の**<戦地連携>**能力を継承するが、ダメージを与えることはできず、いかなる攻撃を受けても即座に消滅する。<br> '
'**<-------- Lv.3 -------->**<br> '
'**<[基本ステータス]>**20HP/攻撃3/防御2/移動2/射程2<br> '
'**<[能力:幻影視差]>**鈴仙が目標を攻撃する前に、近くの全ての**<月兎幻影>**がその目標へ一斉射撃を行う。<br> '
'**<-------- Lv.4 -------->**<br> '
'**<[基本ステータス]>**30HP/攻撃4/防御3/移動2/射程2<br> '
'**<[能力:狂視調律]>**全ての**<月兎幻影>**は本体の50%の攻撃力を持つ。幻影がユニットを撃破した時、新たな**<月兎幻影>**を生成することもできる。<br>',
# KR
'**<제국의 광기의 눈동자: 레이센 우동게인 이나바>**<br> '
'**<-------- Lv.1 -------->**<br> '
'**<[기본 스탯]>**10HP/공격2/방어1/이동2/사거리2<br> '
'**<[능력: 전장 협동]>**유닛을 공격할 때 **<협동 표적>**을 1중첩 부여하며 1턴간 지속된다. **<협동 표적>**이 부여된 대상을 공격할 때, 중첩 1당 이번 공격력이 0.5 상승한다.<br> '
'**<-------- Lv.2 -------->**<br> '
'**<[기본 스탯]>**15HP/공격2/방어2/이동2/사거리2<br> '
'**<[능력: 환시 조율]>**적 유닛을 처치할 때, 그 위치에 레이센과 완전히 똑같이 보이는 **<달토끼 환영>**을 1개 생성한다. 환영은 레이센의 **<전장 협동>** 능력을 계승하지만, 피해를 줄 수 없으며 어떤 공격이라도 받으면 즉시 사망한다.<br> '
'**<-------- Lv.3 -------->**<br> '
'**<[기본 스탯]>**20HP/공격3/방어2/이동2/사거리2<br> '
'**<[능력: 환영 시차]>**레이센이 목표를 공격하기 전에, 근처의 모든 **<달토끼 환영>**이 그 목표를 향해 일제 사격한다.<br> '
'**<-------- Lv.4 -------->**<br> '
'**<[기본 스탯]>**30HP/공격4/방어3/이동2/사거리2<br> '
'**<[능력: 광시 조율]>**모든 **<달토끼 환영>**은 본체의 50% 공격력을 지닌다. 환영이 유닛을 처치할 때, 새로운 **<달토끼 환영>**을 생성할 수도 있다.<br>',
),
}
# ---------------- 校验 + 写入 ----------------
TAG_PATTERN = re.compile(r'\*\*<[^>]*>\*\*')
def count_tags(s):
if s is None:
return 0
return len(TAG_PATTERN.findall(str(s)))
def main():
wb = load_workbook(XLSX, read_only=False, data_only=False)
ws = wb.active
# 建立 ID -> row 映射 (注意第一行表头 ID 可能带 BOM)
id_to_row = {}
for r in range(2, ws.max_row + 1):
raw = ws.cell(row=r, column=1).value
if raw is None:
continue
s = str(raw).lstrip('').strip()
id_to_row[s] = r
# 列: 4=TW, 5=EN, 6=JP, 7=KR
LANG_COLS = [('TW', 4), ('EN', 5), ('JP', 6), ('KR', 7)]
print('=' * 70)
print('校验阶段:')
print('=' * 70)
issues = []
for tid in TRANSLATIONS:
if tid not in id_to_row:
issues.append(f' ID={tid}: row 不存在')
continue
r = id_to_row[tid]
zh = ws.cell(row=r, column=3).value
zh_tags = count_tags(zh)
tw, en, jp, kr = TRANSLATIONS[tid]
tag_counts = {
'CN': zh_tags,
'TW': count_tags(tw),
'EN': count_tags(en),
'JP': count_tags(jp),
'KR': count_tags(kr),
}
ok = all(v == zh_tags for v in tag_counts.values())
marker = 'OK' if ok else '!!FAIL!!'
print(f' ID={tid} row={r} CN={zh_tags} '
f'TW={tag_counts["TW"]} EN={tag_counts["EN"]} '
f'JP={tag_counts["JP"]} KR={tag_counts["KR"]} {marker}')
if not ok:
issues.append(f' ID={tid} 标签数量不一致: {tag_counts}')
if issues:
print('\n校验失败,中止写入:')
for x in issues:
print(x)
sys.exit(1)
print('\n' + '=' * 70)
print('写入阶段:')
print('=' * 70)
for tid, (tw, en, jp, kr) in TRANSLATIONS.items():
r = id_to_row[tid]
ws.cell(row=r, column=4).value = tw
ws.cell(row=r, column=5).value = en
ws.cell(row=r, column=6).value = jp
ws.cell(row=r, column=7).value = kr
print(f' ID={tid} row={r}: 4 语言已填')
wb.save(XLSX)
print(f'\n保存到: {XLSX}')
if __name__ == '__main__':
main()