Localize all hardcoded English strings in renderers
Renderers now use LocalizationManager for all UI text: box opening, loot reveal, feature unlock, prompts, and error messages. Added missing localization keys to both en.json and fr.json.
This commit is contained in:
parent
2825621d0a
commit
c580e1cf2e
6 changed files with 68 additions and 38 deletions
|
|
@ -27,11 +27,22 @@
|
|||
"prompt.press_key": "Press any key to continue...",
|
||||
|
||||
"box.opening": "Opening {0}...",
|
||||
"box.opened": "{0} opened! (Rarity: {1})",
|
||||
"box.opened_short": "{0} opened!",
|
||||
"box.shimmer": "Something shimmers...",
|
||||
"box.found": "You found: {0}!",
|
||||
"box.found_box": "Inside was... another box! {0}!",
|
||||
"box.empty": "The box is empty! How philosophical.",
|
||||
"box.no_boxes": "You have no boxes. How did you manage that?",
|
||||
"box.auto_open": "{0} opens automatically!",
|
||||
"loot.received": "You received:",
|
||||
"loot.title": "Loot!",
|
||||
"loot.name": "Name",
|
||||
"loot.rarity": "Rarity",
|
||||
"loot.category": "Category",
|
||||
"ui.feature_unlocked": "NEW FEATURE UNLOCKED: {0}",
|
||||
"prompt.what_do": "What do you do?",
|
||||
"prompt.invalid_choice": "Please enter a number between 1 and {0}.",
|
||||
|
||||
"box.starter": "Starter Box",
|
||||
"box.starter.desc": "Your first box. The beginning of everything. Or nothing. Probably something though.",
|
||||
|
|
|
|||
|
|
@ -27,11 +27,22 @@
|
|||
"prompt.press_key": "Appuie sur une touche pour continuer...",
|
||||
|
||||
"box.opening": "Ouverture de {0}...",
|
||||
"box.opened": "{0} ouverte ! (Rarete : {1})",
|
||||
"box.opened_short": "{0} ouverte !",
|
||||
"box.shimmer": "Quelque chose scintille...",
|
||||
"box.found": "Tu as trouve : {0} !",
|
||||
"box.found_box": "A l'interieur il y avait... une autre boite ! {0} !",
|
||||
"box.empty": "La boite est vide ! Philosophique.",
|
||||
"box.no_boxes": "Tu n'as aucune boite. Comment t'as fait ?",
|
||||
"box.auto_open": "{0} s'ouvre automatiquement !",
|
||||
"loot.received": "Tu as recu :",
|
||||
"loot.title": "Butin !",
|
||||
"loot.name": "Nom",
|
||||
"loot.rarity": "Rarete",
|
||||
"loot.category": "Categorie",
|
||||
"ui.feature_unlocked": "NOUVELLE FONCTIONNALITE : {0}",
|
||||
"prompt.what_do": "Que fais-tu ?",
|
||||
"prompt.invalid_choice": "Entre un nombre entre 1 et {0}.",
|
||||
|
||||
"box.starter": "Boite de depart",
|
||||
"box.starter.desc": "Ta premiere boite. Le debut de tout. Ou de rien. Probablement de quelque chose quand meme.",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public static class Program
|
|||
_saveManager = new SaveManager();
|
||||
_loc = new LocalizationManager(Locale.EN);
|
||||
_renderContext = new RenderContext();
|
||||
_renderer = RendererFactory.Create(_renderContext);
|
||||
_renderer = RendererFactory.Create(_renderContext, _loc);
|
||||
|
||||
await MainMenuLoop();
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ public static class Program
|
|||
);
|
||||
_simulation = new GameSimulation(_registry);
|
||||
_renderContext = RenderContext.FromGameState(_state);
|
||||
_renderer = RendererFactory.Create(_renderContext);
|
||||
_renderer = RendererFactory.Create(_renderContext, _loc);
|
||||
}
|
||||
|
||||
private static void ChangeLanguage()
|
||||
|
|
@ -141,7 +141,7 @@ public static class Program
|
|||
if (_state != null)
|
||||
_state.CurrentLocale = newLocale;
|
||||
|
||||
_renderer = RendererFactory.Create(_renderContext);
|
||||
_renderer = RendererFactory.Create(_renderContext, _loc);
|
||||
}
|
||||
|
||||
private static async Task GameLoop()
|
||||
|
|
@ -264,7 +264,7 @@ public static class Program
|
|||
|
||||
case UIFeatureUnlockedEvent uiEvt:
|
||||
_renderContext.Unlock(uiEvt.Feature);
|
||||
_renderer = RendererFactory.Create(_renderContext);
|
||||
_renderer = RendererFactory.Create(_renderContext, _loc);
|
||||
var featureKey = $"meta.{uiEvt.Feature.ToString().ToLower()}";
|
||||
_renderer.ShowUIFeatureUnlocked(
|
||||
_loc.Get("meta.unlocked", _loc.Get(featureKey)));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using OpenTheBox.Core;
|
||||
using OpenTheBox.Localization;
|
||||
|
||||
namespace OpenTheBox.Rendering;
|
||||
|
||||
|
|
@ -7,7 +8,7 @@ namespace OpenTheBox.Rendering;
|
|||
/// No colors, no frames, no fancy stuff. This is the "stone age" of the UI,
|
||||
/// deliberately ugly and minimal.
|
||||
/// </summary>
|
||||
public sealed class BasicRenderer : IRenderer
|
||||
public sealed class BasicRenderer(LocalizationManager loc) : IRenderer
|
||||
{
|
||||
public void ShowMessage(string message)
|
||||
{
|
||||
|
|
@ -21,15 +22,15 @@ public sealed class BasicRenderer : IRenderer
|
|||
|
||||
public void ShowBoxOpening(string boxName, string rarity)
|
||||
{
|
||||
Console.WriteLine($"Opening {boxName}...");
|
||||
Console.WriteLine(loc.Get("box.opening", boxName));
|
||||
Console.WriteLine("...");
|
||||
Console.WriteLine("......");
|
||||
Console.WriteLine($"Box opened! (Rarity: {rarity})");
|
||||
Console.WriteLine(loc.Get("box.opened", boxName, rarity));
|
||||
}
|
||||
|
||||
public void ShowLootReveal(List<(string name, string rarity, string category)> items)
|
||||
{
|
||||
Console.WriteLine("You received:");
|
||||
Console.WriteLine(loc.Get("loot.received"));
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
var (name, rarity, category) = items[i];
|
||||
|
|
@ -53,7 +54,7 @@ public sealed class BasicRenderer : IRenderer
|
|||
{
|
||||
return choice - 1;
|
||||
}
|
||||
Console.WriteLine($"Please enter a number between 1 and {options.Count}.");
|
||||
Console.WriteLine(loc.Get("prompt.invalid_choice", options.Count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +81,7 @@ public sealed class BasicRenderer : IRenderer
|
|||
|
||||
public int ShowAdventureChoice(List<string> options)
|
||||
{
|
||||
Console.WriteLine("What do you do?");
|
||||
Console.WriteLine(loc.Get("prompt.what_do"));
|
||||
for (int i = 0; i < options.Count; i++)
|
||||
{
|
||||
Console.WriteLine($" {i + 1}. {options[i]}");
|
||||
|
|
@ -94,14 +95,14 @@ public sealed class BasicRenderer : IRenderer
|
|||
{
|
||||
return choice - 1;
|
||||
}
|
||||
Console.WriteLine($"Please enter a number between 1 and {options.Count}.");
|
||||
Console.WriteLine(loc.Get("prompt.invalid_choice", options.Count));
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowUIFeatureUnlocked(string featureName)
|
||||
{
|
||||
Console.WriteLine("========================================");
|
||||
Console.WriteLine($" NEW FEATURE UNLOCKED: {featureName}");
|
||||
Console.WriteLine($" {loc.Get("ui.feature_unlocked", featureName)}");
|
||||
Console.WriteLine("========================================");
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +113,7 @@ public sealed class BasicRenderer : IRenderer
|
|||
|
||||
public void WaitForKeyPress(string? message = null)
|
||||
{
|
||||
Console.WriteLine(message ?? "Press any key to continue...");
|
||||
Console.WriteLine(message ?? loc.Get("prompt.press_key"));
|
||||
Console.ReadKey(intercept: true);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using OpenTheBox.Localization;
|
||||
|
||||
namespace OpenTheBox.Rendering;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -11,7 +13,7 @@ public static class RendererFactory
|
|||
/// If the context has any Spectre-capable feature unlocked, a <see cref="SpectreRenderer"/>
|
||||
/// is returned; otherwise the plain <see cref="BasicRenderer"/> is used.
|
||||
/// </summary>
|
||||
public static IRenderer Create(RenderContext context)
|
||||
public static IRenderer Create(RenderContext context, LocalizationManager loc)
|
||||
{
|
||||
bool hasAnySpectreFeature =
|
||||
context.HasColors ||
|
||||
|
|
@ -29,9 +31,9 @@ public static class RendererFactory
|
|||
|
||||
if (hasAnySpectreFeature)
|
||||
{
|
||||
return new SpectreRenderer(context);
|
||||
return new SpectreRenderer(context, loc);
|
||||
}
|
||||
|
||||
return new BasicRenderer();
|
||||
return new BasicRenderer(loc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using OpenTheBox.Core;
|
||||
using OpenTheBox.Core.Characters;
|
||||
using OpenTheBox.Core.Enums;
|
||||
using OpenTheBox.Localization;
|
||||
using OpenTheBox.Rendering.Panels;
|
||||
using Spectre.Console;
|
||||
|
||||
|
|
@ -48,26 +49,26 @@ public sealed class SpectreRenderer : IRenderer
|
|||
AnsiConsole.Status()
|
||||
.Spinner(Spinner.Known.Star)
|
||||
.SpinnerStyle(new Style(RarityColorValue(rarity)))
|
||||
.Start($"Opening [bold {color}]{Markup.Escape(boxName)}[/]...", ctx =>
|
||||
.Start(Markup.Escape(_loc.Get("box.opening", boxName)), ctx =>
|
||||
{
|
||||
Thread.Sleep(1500);
|
||||
ctx.Status($"[bold {color}]Something shimmers...[/]");
|
||||
ctx.Status($"[bold {color}]{Markup.Escape(_loc.Get("box.shimmer"))}[/]");
|
||||
Thread.Sleep(1000);
|
||||
});
|
||||
AnsiConsole.MarkupLine($"[bold {color}]{Markup.Escape(boxName)}[/] opened!");
|
||||
AnsiConsole.MarkupLine($"[bold {color}]{Markup.Escape(_loc.Get("box.opened_short", boxName))}[/]");
|
||||
}
|
||||
else if (_context.HasColors)
|
||||
{
|
||||
string color = RarityColor(rarity);
|
||||
AnsiConsole.MarkupLine($"Opening [bold {color}]{Markup.Escape(boxName)}[/]...");
|
||||
AnsiConsole.MarkupLine($"[bold {color}]{Markup.Escape(_loc.Get("box.opening", boxName))}[/]");
|
||||
Thread.Sleep(800);
|
||||
AnsiConsole.MarkupLine($"[bold {color}]{Markup.Escape(boxName)}[/] opened!");
|
||||
AnsiConsole.MarkupLine($"[bold {color}]{Markup.Escape(_loc.Get("box.opened_short", boxName))}[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Opening {boxName}...");
|
||||
Console.WriteLine(_loc.Get("box.opening", boxName));
|
||||
Thread.Sleep(500);
|
||||
Console.WriteLine($"{boxName} opened! (Rarity: {rarity})");
|
||||
Console.WriteLine(_loc.Get("box.opened", boxName, rarity));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,10 +80,10 @@ public sealed class SpectreRenderer : IRenderer
|
|||
{
|
||||
var table = new Table()
|
||||
.Border(TableBorder.Rounded)
|
||||
.Title("[bold yellow]Loot![/]")
|
||||
.AddColumn(new TableColumn("[bold]Name[/]").Centered())
|
||||
.AddColumn(new TableColumn("[bold]Rarity[/]").Centered())
|
||||
.AddColumn(new TableColumn("[bold]Category[/]").Centered());
|
||||
.Title($"[bold yellow]{Markup.Escape(_loc.Get("loot.title"))}[/]")
|
||||
.AddColumn(new TableColumn($"[bold]{Markup.Escape(_loc.Get("loot.name"))}[/]").Centered())
|
||||
.AddColumn(new TableColumn($"[bold]{Markup.Escape(_loc.Get("loot.rarity"))}[/]").Centered())
|
||||
.AddColumn(new TableColumn($"[bold]{Markup.Escape(_loc.Get("loot.category"))}[/]").Centered());
|
||||
|
||||
foreach (var (name, rarity, category) in items)
|
||||
{
|
||||
|
|
@ -97,7 +98,7 @@ public sealed class SpectreRenderer : IRenderer
|
|||
}
|
||||
else if (_context.HasColors)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[bold yellow]You received:[/]");
|
||||
AnsiConsole.MarkupLine($"[bold yellow]{Markup.Escape(_loc.Get("loot.received"))}[/]");
|
||||
foreach (var (name, rarity, category) in items)
|
||||
{
|
||||
string color = RarityColor(rarity);
|
||||
|
|
@ -106,7 +107,7 @@ public sealed class SpectreRenderer : IRenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("You received:");
|
||||
Console.WriteLine(_loc.Get("loot.received"));
|
||||
foreach (var (name, rarity, category) in items)
|
||||
{
|
||||
Console.WriteLine($" - {name} [{rarity}] ({category})");
|
||||
|
|
@ -155,13 +156,14 @@ public sealed class SpectreRenderer : IRenderer
|
|||
return choice - 1;
|
||||
}
|
||||
|
||||
string errorMsg = _loc.Get("prompt.invalid_choice", options.Count);
|
||||
if (_context.HasColors)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[red]Please enter a number between 1 and {options.Count}.[/]");
|
||||
AnsiConsole.MarkupLine($"[red]{Markup.Escape(errorMsg)}[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Please enter a number between 1 and {options.Count}.");
|
||||
Console.WriteLine(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -222,14 +224,14 @@ public sealed class SpectreRenderer : IRenderer
|
|||
{
|
||||
string selected = AnsiConsole.Prompt(
|
||||
new SelectionPrompt<string>()
|
||||
.Title("[bold yellow]What do you do?[/]")
|
||||
.Title($"[bold yellow]{Markup.Escape(_loc.Get("prompt.what_do"))}[/]")
|
||||
.PageSize(10)
|
||||
.AddChoices(options));
|
||||
|
||||
return options.IndexOf(selected);
|
||||
}
|
||||
|
||||
return ShowSelection("What do you do?", options);
|
||||
return ShowSelection(_loc.Get("prompt.what_do"), options);
|
||||
}
|
||||
|
||||
// ── UI feature unlock announcement ──────────────────────────────────
|
||||
|
|
@ -238,14 +240,14 @@ public sealed class SpectreRenderer : IRenderer
|
|||
{
|
||||
if (_context.HasColors)
|
||||
{
|
||||
AnsiConsole.Write(new Rule($"[bold yellow]NEW FEATURE UNLOCKED[/]").RuleStyle("yellow"));
|
||||
AnsiConsole.Write(new Rule($"[bold yellow]{Markup.Escape(_loc.Get("ui.feature_unlocked", featureName))}[/]").RuleStyle("yellow"));
|
||||
AnsiConsole.Write(new FigletText(featureName).Color(Color.Yellow).Centered());
|
||||
AnsiConsole.Write(new Rule().RuleStyle("yellow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("========================================");
|
||||
Console.WriteLine($" NEW FEATURE UNLOCKED: {featureName}");
|
||||
Console.WriteLine($" {_loc.Get("ui.feature_unlocked", featureName)}");
|
||||
Console.WriteLine("========================================");
|
||||
}
|
||||
}
|
||||
|
|
@ -268,13 +270,14 @@ public sealed class SpectreRenderer : IRenderer
|
|||
|
||||
public void WaitForKeyPress(string? message = null)
|
||||
{
|
||||
string text = message ?? _loc.Get("prompt.press_key");
|
||||
if (_context.HasColors)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[dim]{Markup.Escape(message ?? "Press any key to continue...")}[/]");
|
||||
AnsiConsole.MarkupLine($"[dim]{Markup.Escape(text)}[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(message ?? "Press any key to continue...");
|
||||
Console.WriteLine(text);
|
||||
}
|
||||
|
||||
Console.ReadKey(intercept: true);
|
||||
|
|
@ -290,10 +293,12 @@ public sealed class SpectreRenderer : IRenderer
|
|||
// ── Construction ────────────────────────────────────────────────────
|
||||
|
||||
private RenderContext _context;
|
||||
private readonly LocalizationManager _loc;
|
||||
|
||||
public SpectreRenderer(RenderContext context)
|
||||
public SpectreRenderer(RenderContext context, LocalizationManager loc)
|
||||
{
|
||||
_context = context;
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue