using System.Numerics; using Robust.Client.Graphics; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Client.TextScreen; /// /// A component for rendering text on a screen. /// Can show scrolling text, timers, or other specific-use information (e.g. arrivals timer). /// /// /// Pausing handled manually due to logic. /// [RegisterComponent, Access(typeof(TextScreenSystem))] public sealed partial class TextScreenVisualsComponent : Component { /// /// 1/32 - the size of a pixel in meters. /// public const float PixelSize = 1f / EyeManager.PixelsPerMeter; #region Appearance /// /// The color of the text drawn. /// /// /// 15,151,251 is the old SS13 color used on tgstation. /// [DataField] public Color Color = new(15, 151, 251); /// /// The current color being drawn on the screen. /// [ViewVariables] public Color CurrentColor; /// /// Offset for centering the text. /// /// /// Values in pixels. /// [DataField] public Vector2 TextOffset = Vector2.Zero; /// /// Vertical distance between the top pixel of each row. /// [DataField] public int RowOffset = 7; /// /// The amount of characters this component can show per row. /// /// /// Note that scrolling text can show one more than this. /// [DataField] public int RowLength = 5; /// /// The longest that a message should take to cross the screen before wrapping around. /// [DataField] public TimeSpan MaxMessageScrollTime = TimeSpan.FromSeconds(5); /// /// The longest that it should take to scroll one pixel on a screen. /// [DataField] public TimeSpan MaxPixelScrollTime = TimeSpan.FromMilliseconds(100); /// /// The maximum number of characters to display per row. /// [DataField] public int MaxScrollingCharacters = 32; /// /// When scrolling, a horizontal offset for the scrolling, in pixels. /// /// /// Needed for finer adjustments of scroll bounds, along with /// and /// /// [DataField] public int HorizontalScrollOffset; /// /// When scrolling, the number of pixels that the leftmost letters should be invisible for. /// Value should be between [0,CharWidth). /// /// [DataField] public int LeftInvisiblePixels; /// /// When scrolling, the number of pixels that the rightmost letters should be invisible for. /// Value should be between [0,CharWidth). /// /// [DataField] public int RightInvisiblePixels; /// /// The layer for the outer frame of the text screen. /// /// /// Will be registered on top of the other layers. /// Should be at least 2 pixels thick on either side for the illusion to work. /// [DataField] public PrototypeLayerData? FrameState; #endregion #region Text State /// /// If true, the screen is able to scroll its text. /// [DataField] public bool ScrollEnabled; /// /// The list of row data for the text screens. /// /// /// Each row needs its own entry. To declare a three row timer, the yaml could look like rowData: [{},{},{}]. /// [DataField] public TextScreenRow[] RowData = { new(), new() }; /// /// The text to display on the screen. /// Each row delimited with a newline (\n) character. /// [ViewVariables] public string? TextToDisplay; /// /// The time that the text was sent. /// Used for scrolling. /// [ViewVariables] public TimeSpan TextTime; /// /// If true, text to display has been updated and should redraw. /// [ViewVariables] public bool NewTextToDisplay; #endregion } /// /// All information about a given row of text. /// [DataDefinition, Serializable] public partial struct TextScreenRow() { /// /// The time this row should next scroll the text by a pixel. /// [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan NextScroll = TimeSpan.MaxValue; /// /// The delay between each pixel scrolled on this screen. /// [DataField] public TimeSpan ScrollDelay = TimeSpan.MaxValue; /// /// The current position of the row in the string, in pixels. /// /// /// Increases monotonically, should be taken modulo the text length. /// Each character is a fixed size (pixel width defined in ). /// [DataField] public int ScrollPosition; /// /// A list with each of the row's sprite layers, with the key inside of it and the state it's currently on. /// /// /// Currently not removed from the sprite when the component is removed. /// [DataField] public List<(string Key, string? State)> Layers = new(); /// /// The full text currently being drawn on the row. May not all fit on the screen at once. /// [DataField] public string Text = string.Empty; }