CatStation/Content.Client/TextScreen/TextScreenVisualsComponent.cs
Whatstone 041a7e6504
Scrolling text screens (#43997)
* Scrolling text screens

* remove ScrollingTextScreenComponent, fix comments

* shave a pixel off of the frame, commas cut off

* logMissing to false, state does may not exist

* variable timing, offset array serializer

* namespaces are a state of mind

* Use CustomArraySerializer instead of a one-off

* better alphabetize punctuation text

* Unneeded VV access, 4-space meta.json

* Subscription attributes

* cleanup pass

* shift left

* AJCM's suggestions

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>

* PadRight returns a string.

* kill the loop, use funny division instead

* smoother animations, dark stripe on outer frame

* Update for the new comms console UI

* communications console changes

* can't spell pain without UI

* the ocho

* it's big brain time

* just a touch wider

* UI polish pass - forgive the sins

* look at my attributions dog

* EDITED

* Text screen layer init deferred until startup

* that's a new one

---------

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
2026-08-15 22:03:22 +00:00

135 lines
3.9 KiB
C#

using System.Numerics;
using Robust.Client.Graphics;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
namespace Content.Client.TextScreen;
/// <summary>
/// A component for rendering text on a screen.
/// Can show scrolling text, timers, or other specific-use information (e.g. arrivals timer)
/// </summary>
[RegisterComponent]
public sealed partial class TextScreenVisualsComponent : Component
{
/// <summary>
/// 1/32 - the size of a pixel in meters.
/// </summary>
public const float PixelSize = 1f / EyeManager.PixelsPerMeter;
/// <summary>
/// The color of the text drawn.
/// </summary>
/// <remarks>
/// 15,151,251 is the old ss13 color, from tg
/// </remarks>
[DataField]
public Color Color = new Color(15, 151, 251);
/// <summary>
/// Offset for centering the text.
/// </summary>
[DataField]
public Vector2 TextOffset = Vector2.Zero;
/// <summary>
/// Offset for centering the timer.
/// </summary>
[DataField]
public Vector2 TimerOffset = Vector2.Zero;
/// <summary>
/// Number of rows of text this screen can render.
/// </summary>
[DataField]
public int Rows = 2;
/// <summary>
/// Vertical distance between the top pixel of each row.
/// </summary>
[DataField]
public int RowOffset = 7;
/// <summary>
/// The amount of characters this component can show per row.
/// </summary>
/// <remarks>
/// Note that scrolling text can show one more than this.
/// </remarks>
[DataField]
public int RowLength = 5;
/// <summary>
/// Text the screen should show when it finishes a timer.
/// </summary>
[DataField]
public string?[] Text = new string?[2];
/// <summary>
/// Text the screen will draw whenever appearance is updated.
/// </summary>
public string?[] TextToDraw = new string?[2];
/// <summary>
/// Per-character layers, for mapping into the sprite component.
/// </summary>
[DataField]
public Dictionary<string, string?> LayerStatesToDraw = new();
/// <summary>
/// If true, the screen is able to scroll its text.
/// Not used for timers.
/// </summary>
[DataField]
public bool ScrollEnabled;
/// <summary>
/// The next time that the text on each row should be scrolled.
/// </summary>
[DataField(customTypeSerializer: typeof(CustomArraySerializer<TimeSpan, TimeOffsetSerializer>))]
public TimeSpan[] NextScrollTime = [TimeSpan.MaxValue, TimeSpan.MaxValue];
/// <summary>
/// The amount of time between scrolling individual pixels per row.
/// </summary>
[DataField]
public TimeSpan[] TimeBetweenScrolls = [TimeSpan.MaxValue, TimeSpan.MaxValue];
/// <summary>
/// A counter the scroll position of each row.
/// Should be used modulo the pixel width of the actual strings.
/// </summary>
[DataField]
public int[] ScrollPosition = new int[2];
/// <summary>
/// The last received text for this screen. Prevents resetting the scroll state on updates.
/// </summary>
[DataField]
public string? LastText;
/// <summary>
/// The layer for the outer frame of the text screen.
/// Will be registered on top of the other layers.
/// </summary>
[DataField]
public PrototypeLayerData? FrameState;
/// <summary>
/// The format string to use for displaying hours when used as a timer.
/// </summary>
[DataField]
public string HourFormat = "D2";
/// <summary>
/// The format string to use for displaying minutes when used as a timer.
/// </summary>
[DataField]
public string MinuteFormat = "D2";
/// <summary>
/// The format string to use for displaying seconds when used as a timer.
/// </summary>
[DataField]
public string SecondFormat = "D2";
}