new battle gui
This commit is contained in:
1 parent
86e3de904e
commit
ba2c08b1dc
22 files changed
+1613
-120
No files matched your search
@@ -0,0 +1,130 @@
|
||||
using Cthangover.Core.UI;
|
||||
using Cthangover.Core.UI.Theming;
|
||||
using Godot;
|
||||
|
||||
namespace Cthangover.FFBattle.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Battle journal docked to the upper right: a window with a header carrying
|
||||
/// the round counter and a scrollable list of colour-coded rows. The panel is
|
||||
/// a proposal on top of the bare battle screen — it gives damage, shield
|
||||
/// absorption, status and death events a readable history that the original
|
||||
/// FF-style UI lacked. Node structure lives in
|
||||
/// <c>scenes/ff_battle_log_panel.tscn</c>; rows are created at runtime because
|
||||
/// they are data, not layout, and are capped to <see cref="MaxRows"/> so a long
|
||||
/// battle cannot grow unbounded.
|
||||
/// </summary>
|
||||
public partial class FFBattleLogPanel : ModWidget
|
||||
{
|
||||
private const int MaxRows = 80;
|
||||
|
||||
private Label _title;
|
||||
private Label _roundLabel;
|
||||
private ScrollContainer _scroll;
|
||||
private VBoxContainer _rows;
|
||||
|
||||
protected override void Construct()
|
||||
{
|
||||
CthangoverTheme.Apply(this);
|
||||
|
||||
_title = GetNode<Label>("Window/Column/Header/HeaderRow/TitleLabel");
|
||||
_roundLabel = GetNode<Label>("Window/Column/Header/HeaderRow/RoundLabel");
|
||||
_scroll = GetNode<ScrollContainer>("Window/Column/Scroll");
|
||||
_rows = GetNode<VBoxContainer>("Window/Column/Scroll/Rows");
|
||||
|
||||
var windowStyle = UiKit.Frame(UiTokens.RadiusLg, UiTokens.Alpha(UiTokens.Surface0, 0.84f), UiTokens.Line);
|
||||
windowStyle.ContentMarginLeft = 0;
|
||||
windowStyle.ContentMarginRight = 0;
|
||||
windowStyle.ContentMarginTop = 0;
|
||||
windowStyle.ContentMarginBottom = 0;
|
||||
windowStyle.ShadowColor = new Color(0f, 0f, 0f, 0.6f);
|
||||
windowStyle.ShadowSize = 18;
|
||||
windowStyle.ShadowOffset = new Vector2(0f, 8f);
|
||||
GetNode<PanelContainer>("Window").AddThemeStyleboxOverride("panel", windowStyle);
|
||||
|
||||
_title.AddThemeColorOverride("font_color", UiTokens.Muted);
|
||||
_roundLabel.AddThemeColorOverride("font_color", UiTokens.Faint);
|
||||
}
|
||||
|
||||
/// <summary>Updates the round caption in the header.</summary>
|
||||
public void SetRound(int round)
|
||||
=> _roundLabel.Text = string.Format(Translate("ff_battle/log_round"), round);
|
||||
|
||||
/// <summary>Drops every row; used when the battle is cleared or restarted.</summary>
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var child in _rows.GetChildren())
|
||||
{
|
||||
_rows.RemoveChild(child);
|
||||
child.QueueFree();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends one coloured row and trims the oldest entries past the cap.
|
||||
/// The scroll is pushed to the bottom so the newest event is always visible.
|
||||
/// </summary>
|
||||
public void AddEntry(string text, FFBattleLogKind kind)
|
||||
{
|
||||
var style = UiKit.Frame(0, BackgroundOf(kind), new Color(0f, 0f, 0f, 0f));
|
||||
style.BorderWidthLeft = 2;
|
||||
style.BorderColor = BorderOf(kind);
|
||||
style.ContentMarginLeft = 16;
|
||||
style.ContentMarginRight = 12;
|
||||
style.ContentMarginTop = 7;
|
||||
style.ContentMarginBottom = 7;
|
||||
|
||||
var row = new PanelContainer { MouseFilter = MouseFilterEnum.Ignore };
|
||||
row.AddThemeStyleboxOverride("panel", style);
|
||||
|
||||
var label = UiKit.Label(text, UiTokens.FontBodySmall, TextOf(kind));
|
||||
label.AutowrapMode = TextServer.AutowrapMode.WordSmart;
|
||||
row.AddChild(label);
|
||||
|
||||
_rows.AddChild(row);
|
||||
|
||||
while (_rows.GetChildCount() > MaxRows)
|
||||
{
|
||||
var first = _rows.GetChild(0);
|
||||
_rows.RemoveChild(first);
|
||||
first.QueueFree();
|
||||
}
|
||||
|
||||
_scroll.ScrollVertical = (int)_scroll.GetVScrollBar().MaxValue;
|
||||
}
|
||||
|
||||
private static Color BackgroundOf(FFBattleLogKind kind)
|
||||
=> kind == FFBattleLogKind.Turn ? UiTokens.AccentSoft : new Color(0f, 0f, 0f, 0f);
|
||||
|
||||
private static Color BorderOf(FFBattleLogKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case FFBattleLogKind.Turn: return UiTokens.Accent;
|
||||
case FFBattleLogKind.Damage: return UiTokens.Danger;
|
||||
case FFBattleLogKind.Shield: return UiTokens.TypeResource;
|
||||
case FFBattleLogKind.Buff: return UiTokens.TypePassive;
|
||||
case FFBattleLogKind.Status: return UiTokens.Cooldown;
|
||||
case FFBattleLogKind.Dead: return UiTokens.LineFaint;
|
||||
default: return UiTokens.Line;
|
||||
}
|
||||
}
|
||||
|
||||
private static Color TextOf(FFBattleLogKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case FFBattleLogKind.Turn: return UiTokens.AccentBright;
|
||||
case FFBattleLogKind.Damage: return UiTokens.DangerText;
|
||||
case FFBattleLogKind.Shield: return UiTokens.Info;
|
||||
case FFBattleLogKind.Buff: return UiTokens.SuccessText;
|
||||
case FFBattleLogKind.Status: return UiTokens.Cooldown;
|
||||
case FFBattleLogKind.Dead: return UiTokens.Faint;
|
||||
default: return UiTokens.Muted;
|
||||
}
|
||||
}
|
||||
|
||||
private static string Translate(string key)
|
||||
=> TranslationServer.Translate(key).ToString();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user