champions-of-luneraria/Assets/Luneraria/UI/Theme/LuneUiTheme.cs
Martin Stickelbroeck 4dee9b18d2 U3A HUD-Grundlagen: UI Toolkit, Sichtmodell, menschlicher Sitz
Beginn des Ports des G3-HUD (Referenz luneraria/g3, 1b540f2).

- Entscheidung UI Toolkit statt uGUI nach kurzer Bewertung und einer Probe:
  Panel rendert im Batchmodus in eine 1920x1080-Textur (Skalierung wie Godot
  canvas_items/expand, 1600x960), gefaste Verlaufsplatten, alle 50 Symbole,
  Schriften aus den variablen Fonts der Referenz.
- Sichtmodell portiert (LuneHudModel, LuneLaneThreat, LuneStats) mit den
  Privatsphäre-Regeln der Referenz: Gold, Entwurf, Rückgängig und neue
  Buchungen nur für den eigenen Sitz; Lanes, Gebäude, Boss und Wellen aus
  öffentlichem Zustand.
- Menschlicher Sitz in LuneMatchRunner/LuneMatchDriver: Bots planen die
  übrigen fünf Sitze, die Planung wartet auf Bereit; Tempo 1x/2x/4x und Pause
  nur im Kampf. Bot-Partien unverändert.
- Theme-Grundlagen: Farben und Zahlenformate, Platten (forged_style.gd),
  Vektorsymbole (lune_glyphs.gd) mit Painter2D, statische SDF-Atlanten aus
  den benannten Instanzen von Cantarell und Cinzel (OFL).
- Tests: EditMode 23/23 (12 neue: gleiches öffentliches Bild für alle Sitze,
  fremde Entwürfe privat, private Boss-Lane-Wahl, Lane-Bedrohung, Bosszustände,
  nächste Welle, Bereit-Sperre, Formate, menschlicher Sitz); PlayMode 3/3,
  Fingerabdrücke der Bot-Partien unverändert (DCE95C96556F3A1A, 7B8E43AEFC0D60C5).
- Dokumentation: U3-UI (Bewertung, U3A), U5-VISUAL (Vorgaben des
  Projektinhabers: stilisierter Realismus für die ganze Welt, erst in U5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:57:45 +02:00

107 lines
5 KiB
C#
Raw 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.

using System;
using System.Globalization;
using UnityEngine;
namespace Luneraria.UI
{
/// <summary>
/// Colours and number formats of the Champions of Luneraria HUD (port of
/// scripts/luneraria/ui/theme/lune_ui_theme.gd and the colours of the Saumwacht menu theme it
/// extends): dark blue-anthracite plates, bronze and gold only on what the player can act on,
/// quiet team accents. Colours are sRGB, as in Godot.
/// </summary>
public static class LuneUiTheme
{
public static readonly Color SlateTop = new Color(.075f, .1f, .135f, .9f);
public static readonly Color SlateBottom = new Color(.05f, .068f, .094f, .93f);
public static readonly Color Edge = Hex("2b3848");
public static readonly Color EdgeLight = Hex("455870");
public static readonly Color Text = Hex("ebe5d8");
public static readonly Color Bright = Hex("f6eedc");
public static readonly Color Muted = Hex("9aa4b0");
public static readonly Color Faint = Hex("6a7480");
public static readonly Color Gold = Hex("f2c96b");
// Saumwacht menu theme (saumwacht_theme.gd).
public static readonly Color Bronze = Hex("b7874a");
public static readonly Color BronzeLight = Hex("e4bd7c");
public static readonly Color BronzeDeep = Hex("6b4f2e");
public static readonly Color Ink = Hex("1a120a");
public static readonly Color Focus = Hex("f6e2b0");
public static readonly Color Parchment = Hex("efe6d2");
/// <summary>Team accents: Blau (cool, crescent moon), Rot (warm, sun disc), neutral grotto (violet).</summary>
public static readonly Color[] Team = { Hex("6cb4ff"), Hex("ff7b5e"), Hex("b78cff") };
public static readonly Color[] TeamDark = { Hex("1c3f6a"), Hex("722a1f"), Hex("45305f") };
public static readonly string[] TeamNames = { "Blau", "Rot", "Grotte" };
public static readonly string[] TeamEmblems = { "Mondsichel", "Sonnenscheibe", "Grotte" };
/// <summary>Threat levels RUHIG, UMKÄMPFT, UNTER DRUCK, KRITISCH.</summary>
public static readonly Color[] Threat = { Hex("7cc9a6"), Hex("e5c35e"), Hex("ff9448"), Hex("ff584a") };
public static readonly Color Champion = Hex("e2a15e");
public static readonly Color Hero = Hex("f2c96b");
public static readonly Color Good = Hex("8fdcb4");
public static readonly Color Warn = Hex("f0c060");
public static readonly Color Danger = Hex("ff6a55");
public static readonly Color Info = Hex("a9c6e8");
/// <summary>Lower bound for any HUD text: 14 logical px stay above 10 px at 1280×720.</summary>
public const int MinFont = 14;
public static Color Hex(string hex)
{
if (!ColorUtility.TryParseHtmlString("#" + hex, out Color color))
throw new ArgumentException("Bad colour " + hex);
return color;
}
/// <summary>Godot Color.darkened: rgb times (1 - amount), alpha kept.</summary>
public static Color Darkened(Color color, float amount)
{
return new Color(color.r * (1f - amount), color.g * (1f - amount), color.b * (1f - amount), color.a);
}
/// <summary>Godot Color.lightened: rgb towards white by amount, alpha kept.</summary>
public static Color Lightened(Color color, float amount)
{
return new Color(color.r + (1f - color.r) * amount, color.g + (1f - color.g) * amount, color.b + (1f - color.b) * amount, color.a);
}
public static Color WithAlpha(Color color, float alpha)
{
return new Color(color.r, color.g, color.b, alpha);
}
public static Color TeamColor(int team)
{
return Team[Mathf.Clamp(team, 0, 2)];
}
public static string TeamName(int team)
{
return TeamNames[Mathf.Clamp(team, 0, 2)];
}
/// <summary>Whole numbers with German thousands separators (12.000), rounded like Godot (half away from zero).</summary>
public static string Number(double value)
{
long whole = (long)Math.Round(value, MidpointRounding.AwayFromZero);
string digits = Math.Abs(whole).ToString(CultureInfo.InvariantCulture);
string result = "";
while (digits.Length > 3)
{
result = "." + digits.Substring(digits.Length - 3) + result;
digits = digits.Substring(0, digits.Length - 3);
}
return (whole < 0 ? "-" : "") + digits + result;
}
/// <summary>Fixed decimals with a decimal comma (Godot: "%.1f" % value with "." replaced).</summary>
public static string Decimal(double value, int places = 1)
{
return value.ToString("F" + places, CultureInfo.InvariantCulture).Replace(".", ",");
}
/// <summary>Godot round(): half away from zero.</summary>
public static int Round(double value)
{
return (int)Math.Round(value, MidpointRounding.AwayFromZero);
}
}
}