2026-03-10 18:24:01 +01:00
|
|
|
using OpenTheBox.Core;
|
|
|
|
|
|
|
|
|
|
namespace OpenTheBox.Rendering;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Phase 0 renderer. Pure Console.WriteLine and Console.ReadLine.
|
|
|
|
|
/// 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 void ShowMessage(string message)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowError(string message)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"ERROR: {message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowBoxOpening(string boxName, string rarity)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Opening {boxName}...");
|
|
|
|
|
Console.WriteLine("...");
|
|
|
|
|
Console.WriteLine("......");
|
|
|
|
|
Console.WriteLine($"Box opened! (Rarity: {rarity})");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowLootReveal(List<(string name, string rarity, string category)> items)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("You received:");
|
|
|
|
|
for (int i = 0; i < items.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var (name, rarity, category) = items[i];
|
|
|
|
|
Console.WriteLine($" - {name} [{rarity}] ({category})");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ShowSelection(string prompt, List<string> options)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(prompt);
|
|
|
|
|
for (int i = 0; i < options.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($" {i + 1}. {options[i]}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
Console.Write("> ");
|
|
|
|
|
string? input = Console.ReadLine();
|
|
|
|
|
if (int.TryParse(input, out int choice) && choice >= 1 && choice <= options.Count)
|
|
|
|
|
{
|
|
|
|
|
return choice - 1;
|
|
|
|
|
}
|
|
|
|
|
Console.WriteLine($"Please enter a number between 1 and {options.Count}.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ShowTextInput(string prompt)
|
|
|
|
|
{
|
|
|
|
|
Console.Write($"{prompt}: ");
|
|
|
|
|
return Console.ReadLine() ?? string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowGameState(GameState state, RenderContext context)
|
|
|
|
|
{
|
|
|
|
|
// Phase 0: no panels unlocked yet, so nothing to show.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowAdventureDialogue(string? character, string text)
|
|
|
|
|
{
|
|
|
|
|
if (character is not null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"[{character}]");
|
|
|
|
|
}
|
|
|
|
|
Console.WriteLine(text);
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ShowAdventureChoice(List<string> options)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("What do you do?");
|
|
|
|
|
for (int i = 0; i < options.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($" {i + 1}. {options[i]}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
Console.Write("> ");
|
|
|
|
|
string? input = Console.ReadLine();
|
|
|
|
|
if (int.TryParse(input, out int choice) && choice >= 1 && choice <= options.Count)
|
|
|
|
|
{
|
|
|
|
|
return choice - 1;
|
|
|
|
|
}
|
|
|
|
|
Console.WriteLine($"Please enter a number between 1 and {options.Count}.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowUIFeatureUnlocked(string featureName)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("========================================");
|
|
|
|
|
Console.WriteLine($" NEW FEATURE UNLOCKED: {featureName}");
|
|
|
|
|
Console.WriteLine("========================================");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowInteraction(string description)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"* {description} *");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void WaitForKeyPress(string? message = null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(message ?? "Press any key to continue...");
|
|
|
|
|
Console.ReadKey(intercept: true);
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
Add complete content: recipes, French translations, music/cookie events
- Add 34 crafting recipes (materials, consumables, cosmetics, adventures, boxes)
- Add French translations for all 8 remaining adventures
- Add missing item definitions (resource_max_*, music_melody, cookie_fortune)
- Add MusicPlayedEvent and CookieFortuneEvent for special box types
- Make box_story, box_cookie, box_music reachable from box_of_boxes
- Fix content file copying in csproj (None -> Content)
- Add global.json pinning .NET 10 SDK
- Add graceful Console.Clear() error handling
- Add recipe localization keys (EN/FR)
- Add adventure localization keys (EN/FR)
2026-03-10 18:45:54 +01:00
|
|
|
try { Console.Clear(); }
|
|
|
|
|
catch (IOException) { }
|
2026-03-10 18:24:01 +01:00
|
|
|
}
|
|
|
|
|
}
|