多语言布局:自动缩字、按语言放宽钱包表与手册列表、缩短过长标签
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f5de68aea9
commit
fa8f416545
11 files changed
+70
-23
No files matched your search
@@ -5,6 +5,7 @@
|
||||
### 第九阶段:剧情与收尾
|
||||
|
||||
- 多语言:新增 de fr es pl ru ja 六种语言表(连同 zh en 共 8 种,对应游戏主菜单的语言)。英文表是源文,其他语言由 Gemini 分块译出(术语表 `docs/i18n-glossary.md` 在运营仓库,游戏已有的词用官方译名),未经人工校对,文件头有说明。键集合、占位符、`§ ¶ \\n` 标记由单元测试逐语言核对,非中日语言里不得出现汉字或假名。
|
||||
- 多语言布局:表格单元、按钮文字放不下时自动缩小字号(最小 68%)再省略,商品名限定两行内缩放;de fr es pl ru 的钱包表、手册章节列表、硬件钱包粘贴键按语言放宽;ru de 等少数过长标签改短(永续“加保证金”键、收益池列头)。
|
||||
- 中文“匿名币”改称“隐私币”(英文 privacy coin),手册、黑市标签同步。
|
||||
- 英文手册里写死的“六天”“7 天”改为占位符 `{BmBulkDays}`、`{AmlWindowDays}`,和中文一致。
|
||||
- 手册里剩下的写死数字也进了 `Tuning`:出金审查污点系数 `AmlTaintMult` 与超额权重 `AmlExcessWeight`、出售速度界线 `BmSellFastMult` / `BmSellDay1Mult`;剧情联动的期限和涨幅改用已有的 `Story*` / `Tumbler*` 常量占位。占位符新增 `{Name:+%}`(倍数显示成涨幅)。
|
||||
|
||||
@@ -14,6 +14,12 @@ namespace Decentralized
|
||||
public static class L
|
||||
{
|
||||
public static string T(string key, params object[] args) => ModHelper.GetLocalized(ModInfo.Id, key, args);
|
||||
|
||||
/// <summary>当前游戏语言代码(en zh de fr es pl ru ja)。</summary>
|
||||
public static string Code => LocHelper.GetCurrentLocaleCode() ?? "en";
|
||||
|
||||
/// <summary>译文普遍比中英文长的语言:表格列宽、操作键区按此放宽。</summary>
|
||||
public static bool Wide { get { var c = Code; return c == "de" || c == "fr" || c == "es" || c == "pl" || c == "ru"; } }
|
||||
}
|
||||
|
||||
public static class Log
|
||||
|
||||
@@ -11,7 +11,9 @@ namespace Decentralized
|
||||
{
|
||||
public const string Id = "pd_handbook";
|
||||
private const float WinW = 828f, WinH = 680f, ScreenW = 768f, ScreenH = 578f, Bezel = 6f;
|
||||
private const float ListW = 190f, TextW = 540f;
|
||||
private static float ListW => L.Wide ? 276f : 190f;
|
||||
private static float RowW => L.Wide ? ListW - 52f : ListW - 12f;
|
||||
private static float TextW => L.Wide ? 456f : 540f;
|
||||
|
||||
private static int _chapter;
|
||||
private static readonly List<GameObject> _picked = new List<GameObject>();
|
||||
@@ -61,7 +63,7 @@ namespace Decentralized
|
||||
for (int i = 0; i < chapters.Length; i++)
|
||||
{
|
||||
int k = i;
|
||||
PledgerSkin.TableRow(b, ListW - 12f, 30f, new[] { ListW - 12f }, new[] { TextAnchor.MiddleLeft },
|
||||
PledgerSkin.TableRow(b, RowW, 30f, new[] { RowW }, new[] { TextAnchor.MiddleLeft },
|
||||
new[] { Title(chapters[i]) }, i == _chapter, () => { _chapter = k; Open(); }, _rows, _clear);
|
||||
}
|
||||
b.End();
|
||||
|
||||
@@ -498,7 +498,7 @@ perp.open,Eröffnen
|
||||
perp.margin,Margin (CRC)
|
||||
perp.preview,Nominal {0} Ausführung {1}
|
||||
perp.do.open,Eröffnen
|
||||
perp.do.add,Margin hinzufügen
|
||||
perp.do.add,+ Margin
|
||||
perp.do.close,Schließen
|
||||
perp.opened,"{0} {1} eröffnet: Margin {2} CRC, {3}×."
|
||||
perp.added,{0} CRC Margin hinzugefügt.
|
||||
@@ -683,11 +683,11 @@ air.err.wallet,Mit der freigebenden Wallet signieren.
|
||||
pool.h,Drittanbieter-Renditepools (CRC)
|
||||
pool.none,Derzeit keine vorhanden.
|
||||
pool.col.name,Pool
|
||||
pool.col.rate,Tageszins
|
||||
pool.col.rate,Zins
|
||||
pool.col.reserve,Reserve
|
||||
pool.col.lock,Timelock
|
||||
pool.col.lock,Sperre
|
||||
pool.col.audit,Audit
|
||||
pool.col.mine,Eigene
|
||||
pool.col.mine,Mein
|
||||
pool.yes,ja
|
||||
pool.no,nein
|
||||
pool.pending,in Auszahlung
|
||||
|
||||
|
@@ -498,7 +498,7 @@ perp.open,Abrir
|
||||
perp.margin,Margen (CRC)
|
||||
perp.preview,Nocional {0} ejecución {1}
|
||||
perp.do.open,Abrir
|
||||
perp.do.add,Agregar margen
|
||||
perp.do.add,+ Margen
|
||||
perp.do.close,Cerrar
|
||||
perp.opened,"Se abrió {0} {1}: margen {2} CRC, {3}×."
|
||||
perp.added,Se agregaron {0} CRC de margen.
|
||||
@@ -683,11 +683,11 @@ air.err.wallet,Firmar con la billetera que aprobó.
|
||||
pool.h,Fondos de rendimiento de terceros (CRC)
|
||||
pool.none,Ninguno por ahora.
|
||||
pool.col.name,Fondo
|
||||
pool.col.rate,Tasa diaria
|
||||
pool.col.rate,Tasa/día
|
||||
pool.col.reserve,Reserva
|
||||
pool.col.lock,Bloqueo
|
||||
pool.col.audit,Auditoría
|
||||
pool.col.mine,Mi depósito
|
||||
pool.col.mine,Mío
|
||||
pool.yes,sí
|
||||
pool.no,no
|
||||
pool.pending,retirando
|
||||
|
||||
|
@@ -498,7 +498,7 @@ perp.open,Ouvrir
|
||||
perp.margin,Marge (CRC)
|
||||
perp.preview,Notionnel {0} exécution {1}
|
||||
perp.do.open,Ouvrir
|
||||
perp.do.add,Ajouter de la marge
|
||||
perp.do.add,+ Marge
|
||||
perp.do.close,Fermer
|
||||
perp.opened,"Position {0} {1} ouverte : marge {2} CRC, {3}×."
|
||||
perp.added,{0} CRC de marge ajoutés.
|
||||
@@ -687,7 +687,7 @@ pool.col.rate,Taux/j
|
||||
pool.col.reserve,Réserve
|
||||
pool.col.lock,Blocage
|
||||
pool.col.audit,Audit
|
||||
pool.col.mine,Dépôt
|
||||
pool.col.mine,Mon dépôt
|
||||
pool.yes,oui
|
||||
pool.no,non
|
||||
pool.pending,retrait en cours
|
||||
|
||||
|
@@ -406,7 +406,7 @@ poin.out.done,Wypłacono {0} {1} na {2}.
|
||||
wallets.count,Portfele {0}/{1}
|
||||
wallets.col.name,Nazwa
|
||||
wallets.col.addr,Adres
|
||||
wallets.col.taint,Skażenie
|
||||
wallets.col.taint,Skażone
|
||||
wallets.open,Otwórz
|
||||
wallets.use,Połącz
|
||||
wallets.current,Połączono
|
||||
@@ -498,7 +498,7 @@ perp.open,Otwórz
|
||||
perp.margin,Depozyt zabezpieczający (CRC)
|
||||
perp.preview,Nominał {0} realizacja {1}
|
||||
perp.do.open,Otwórz
|
||||
perp.do.add,Dodaj depozyt
|
||||
perp.do.add,+ Depozyt
|
||||
perp.do.close,Zamknij
|
||||
perp.opened,"Otwarto {0} {1}: depozyt {2} CRC, {3}×."
|
||||
perp.added,Dodano {0} CRC depozytu.
|
||||
|
||||
|
@@ -154,7 +154,7 @@ avg.short,ср. покупка {0}
|
||||
avg.none,—
|
||||
col.asset,Актив
|
||||
col.amount,Сумма
|
||||
col.value,Стоимость
|
||||
col.value,Оценка
|
||||
col.avg,Ср. покупка
|
||||
bank.cash.k,Кредиты
|
||||
bank.rent.k,Аренда
|
||||
@@ -406,7 +406,7 @@ poin.out.done,{0} {1} выведено на {2}.
|
||||
wallets.count,Кошельки {0}/{1}
|
||||
wallets.col.name,Название
|
||||
wallets.col.addr,Адрес
|
||||
wallets.col.taint,Загрязнение
|
||||
wallets.col.taint,Грязные
|
||||
wallets.open,Открыть
|
||||
wallets.use,Подключить
|
||||
wallets.current,Подключено
|
||||
@@ -425,7 +425,7 @@ wallets.destroy.sure,Подтвердить
|
||||
wallets.destroy.notempty,В {0} ещё есть монеты. Сначала выведите их.
|
||||
wallets.destroyed,Уничтожен {0}: {1}
|
||||
hw.balance.value,≈ {0}
|
||||
wallets.rename,Переименовать
|
||||
wallets.rename,Назвать
|
||||
wallets.rename.h,Новое имя для {0}
|
||||
wallets.rename.ok,ОК
|
||||
hw.fee.slow,Медленно
|
||||
@@ -498,7 +498,7 @@ perp.open,Открыть
|
||||
perp.margin,Маржа (CRC)
|
||||
perp.preview,Номинал {0} цена исполнения {1}
|
||||
perp.do.open,Открыть
|
||||
perp.do.add,Добавить маржу
|
||||
perp.do.add,+ Маржа
|
||||
perp.do.close,Закрыть
|
||||
perp.opened,"Открыто {0} {1}: маржа {2} CRC, {3}×."
|
||||
perp.added,Добавлено {0} CRC маржи.
|
||||
@@ -685,7 +685,7 @@ pool.none,Сейчас пулов нет.
|
||||
pool.col.name,Пул
|
||||
pool.col.rate,Ставка
|
||||
pool.col.reserve,Резерв
|
||||
pool.col.lock,Таймлок
|
||||
pool.col.lock,Лок
|
||||
pool.col.audit,Аудит
|
||||
pool.col.mine,Вклад
|
||||
pool.yes,да
|
||||
|
||||
|
@@ -123,6 +123,7 @@ namespace Decentralized
|
||||
b.BeginPanel(w, height - 6f, align, 0f, 0f);
|
||||
if (clear != null) clear.Add(b.Last.image);
|
||||
b.AddLabel(i < texts.Length ? texts[i] : "");
|
||||
FitCurrent(b);
|
||||
b.End();
|
||||
}
|
||||
b.End();
|
||||
@@ -142,12 +143,46 @@ namespace Decentralized
|
||||
b.BeginPanel(w, height - 6f, align, 0f, 0f);
|
||||
if (clear != null) clear.Add(b.Last.image);
|
||||
b.AddLabel(i < headers.Length ? "<b>" + headers[i] + "</b>" : "");
|
||||
FitCurrent(b);
|
||||
b.End();
|
||||
}
|
||||
b.End();
|
||||
b.End();
|
||||
}
|
||||
|
||||
/// <summary>单行固定宽度的文字放不下时先缩小字号(最小 68%),再省略:各语言译文长度不同,不靠逐语言调列宽。</summary>
|
||||
public static void Fit(TMP_Text t)
|
||||
{
|
||||
if (t == null) return;
|
||||
t.enableWordWrapping = false;
|
||||
t.enableAutoSizing = true;
|
||||
t.fontSizeMax = t.fontSize;
|
||||
t.fontSizeMin = Mathf.Round(t.fontSize * 0.68f);
|
||||
t.overflowMode = TextOverflowModes.Ellipsis;
|
||||
}
|
||||
|
||||
/// <summary>刚加的标签限定在固定高度内(可折行),放不下时缩小字号:商品名等多语言下长度差很大的标题用。</summary>
|
||||
public static void FitBox(CustomUIBuilder b, float height)
|
||||
{
|
||||
var c = b.CurrentContainer;
|
||||
if (c == null || c.childCount == 0) return;
|
||||
var t = c.GetChild(c.childCount - 1).GetComponentInChildren<TextMeshProUGUI>(true);
|
||||
if (t == null) return;
|
||||
var le = t.gameObject.GetComponent<LayoutElement>() ?? t.gameObject.AddComponent<LayoutElement>();
|
||||
le.minHeight = height; le.preferredHeight = height; le.flexibleHeight = 0f;
|
||||
t.enableAutoSizing = true;
|
||||
t.fontSizeMax = t.fontSize;
|
||||
t.fontSizeMin = Mathf.Round(t.fontSize * 0.7f);
|
||||
t.overflowMode = TextOverflowModes.Ellipsis;
|
||||
}
|
||||
|
||||
/// <summary>对当前容器(刚加完标签的单元面板)里的文字做 Fit。</summary>
|
||||
public static void FitCurrent(CustomUIBuilder b)
|
||||
{
|
||||
if (b.CurrentContainer == null) return;
|
||||
foreach (var t in b.CurrentContainer.GetComponentsInChildren<TextMeshProUGUI>(true)) Fit(t);
|
||||
}
|
||||
|
||||
/// <summary>应用整套 PLEDGER 皮肤:机身、边框、墨水屏、刻字、文字颜色、触控键、滚动条与数据表行。</summary>
|
||||
public static void Apply(CustomUIWindow win, RectTransform screen, Image bezel, Image paper, ICollection<GameObject> picked, ICollection<Image> clear, IEnumerable<RowDef> rows = null)
|
||||
{
|
||||
@@ -230,6 +265,7 @@ namespace Decentralized
|
||||
}
|
||||
foreach (var t in btn.GetComponentsInChildren<TextMeshProUGUI>(true))
|
||||
{
|
||||
Fit(t);
|
||||
t.color = on ? Ink : KeyText;
|
||||
if (on) t.fontStyle |= FontStyles.Bold;
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ namespace Decentralized
|
||||
b.BeginPanel(w, 26f, align, 0f, 0f);
|
||||
_clear.Add(b.Last.image);
|
||||
b.AddLabel(header ? "<b>" + text + "</b>" : text);
|
||||
PledgerSkin.FitCurrent(b);
|
||||
b.End();
|
||||
}
|
||||
|
||||
@@ -984,7 +985,7 @@ namespace Decentralized
|
||||
{
|
||||
var d = Session.Data;
|
||||
b.AddLabel(L.T("wallets.count", d.Wallets.Count, Tuning.WalletMax), "wallets_count_dim");
|
||||
var cols = new[] { 100f, 110f, 85f, 70f, 375f };
|
||||
var cols = L.Wide ? new[] { 100f, 92f, 62f, 62f, 372f } : new[] { 100f, 110f, 85f, 70f, 375f };
|
||||
var aligns = new[] { TextAnchor.MiddleLeft, TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleLeft };
|
||||
TableHeader(b, 740f, cols, aligns, L.T("wallets.col.name"), L.T("wallets.col.addr"), L.T("col.value"), L.T("wallets.col.taint"), "");
|
||||
for (int i = 0; i < d.Wallets.Count; i++)
|
||||
@@ -1009,7 +1010,7 @@ namespace Decentralized
|
||||
Cell(b, cols[3], Fmt.Credits(w.Taint), false, TextAnchor.MiddleRight);
|
||||
b.End();
|
||||
b.End();
|
||||
b.BeginPanel(cols[4] - 150f, 32f, TextAnchor.MiddleLeft, 0f, 0f);
|
||||
b.BeginPanel(cols[4] - (L.Wide ? 112f : 150f), 32f, TextAnchor.MiddleLeft, 0f, 0f);
|
||||
_clear.Add(b.Last.image);
|
||||
b.BeginRow(4f, TextAnchor.MiddleLeft);
|
||||
RowKey(b, L.T("wallets.open"), () => WalletWindow.Open(w));
|
||||
@@ -1018,11 +1019,11 @@ namespace Decentralized
|
||||
if (idx > 0) RowKey(b, _destroyPick == w.Address ? L.T("wallets.destroy.sure") : L.T("wallets.destroy"), () => DestroyWallet(w));
|
||||
b.End();
|
||||
b.End();
|
||||
b.BeginPanel(84f, 32f, TextAnchor.MiddleRight, 0f, 0f);
|
||||
b.BeginPanel(L.Wide ? 92f : 84f, 32f, TextAnchor.MiddleRight, 0f, 0f);
|
||||
_clear.Add(b.Last.image);
|
||||
b.BeginRow(0f, TextAnchor.MiddleRight);
|
||||
if (idx != d.Current) RowKey(b, L.T("wallets.use"), () => { d.Current = idx; Session.Save(); Open(); });
|
||||
else b.AddLabel(L.T("wallets.current"), "wallets_cur_dim");
|
||||
else { b.AddLabel(L.T("wallets.current"), "wallets_cur_dim"); PledgerSkin.FitCurrent(b); }
|
||||
b.End();
|
||||
b.End();
|
||||
b.End();
|
||||
@@ -1754,6 +1755,7 @@ namespace Decentralized
|
||||
var sprite = Icon(g.Item);
|
||||
if (sprite != null) c.AddImage(sprite, 64f, 64f); else c.AddSpace(64f);
|
||||
c.AddLabel("<b>" + ItemName(g.Item) + "</b>");
|
||||
PledgerSkin.FitBox(c, 52f);
|
||||
bool asic = g.Kind == GoodKind.Gpu && g.Model != null && Hardware.Specs.TryGetValue(g.Model, out var gs) && gs.Asic;
|
||||
c.AddLabel(asic ? (g.Health >= 100 ? L.T("black.kind.asicnew") : L.T("black.kind.asic", (int)Math.Round(g.Health))) : g.Kind == GoodKind.Gpu ? (g.Health >= 100 ? L.T("black.kind.gpunew") : L.T("black.kind.gpu", (int)Math.Round(g.Health))) : L.T("black.kind." + g.Kind + (g.Kind == GoodKind.Contraband ? "." + g.Level : "")), "good_kind_dim");
|
||||
if (!string.IsNullOrEmpty(line2)) c.AddLabel(line2, "good_line2_dim");
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Decentralized
|
||||
b.AddHeader(L.T("hw.send"));
|
||||
b.AddLabel(L.T("hw.to"));
|
||||
b.BeginRow(6f, TextAnchor.MiddleLeft);
|
||||
b.BeginPanel(RowW - 70f, -1f, TextAnchor.MiddleLeft, 0f, 0f);
|
||||
b.BeginPanel(RowW - (L.Wide ? 100f : 70f), -1f, TextAnchor.MiddleLeft, 0f, 0f);
|
||||
_clear.Add(b.Last.image);
|
||||
b.AddInput("0x", dev.To, s => dev.To = s, "to", s => dev.To = s);
|
||||
b.End();
|
||||
|
||||
Reference in new issue
Block a user