using System.Linq; using Content.Shared.Humanoid.Prototypes; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Humanoid.Markings { [DataDefinition] [Serializable, NetSerializable] public sealed partial class Marking : IEquatable, IComparable, IComparable { [DataField("markingColor")] private List _markingColors = new(); private Marking() { } public Marking(string markingId, List markingColors) { MarkingId = markingId; _markingColors = markingColors; } public Marking(string markingId, IReadOnlyList markingColors) : this(markingId, new List(markingColors)) { } public Marking(string markingId, int colorCount) { MarkingId = markingId; List colors = new(); for (int i = 0; i < colorCount; i++) colors.Add(Color.White); _markingColors = colors; } public Marking(Marking other) { MarkingId = other.MarkingId; _markingColors = new(other.MarkingColors); Visible = other.Visible; Forced = other.Forced; } /// /// ID of the marking prototype. /// [DataField("markingId", required: true)] public string MarkingId { get; private set; } = default!; /// /// All colors currently on this marking. /// [ViewVariables] public IReadOnlyList MarkingColors => _markingColors; /// /// If this marking is currently visible. /// [DataField("visible")] public bool Visible = true; /// /// If this marking should be forcefully applied, regardless of points. /// [ViewVariables] public bool Forced; public void SetColor(int colorIndex, Color color) => _markingColors[colorIndex] = color; public void SetColor(Color color) { for (int i = 0; i < _markingColors.Count; i++) { _markingColors[i] = color; } } public int CompareTo(Marking? marking) { if (marking == null) { return 1; } return string.Compare(MarkingId, marking.MarkingId, StringComparison.Ordinal); } public int CompareTo(string? markingId) { if (markingId == null) return 1; return string.Compare(MarkingId, markingId, StringComparison.Ordinal); } public bool Equals(Marking? other) { if (other == null) { return false; } return MarkingId.Equals(other.MarkingId) && _markingColors.SequenceEqual(other._markingColors) && Visible.Equals(other.Visible) && Forced.Equals(other.Forced); } // VERY BIG TODO: TURN THIS INTO JSONSERIALIZER IMPLEMENTATION // look this could be better but I don't think serializing // colors is the correct thing to do // // this is still janky imo but serializing a color and feeding // it into the default JSON serializer (which is just *fine*) // doesn't seem to have compatible interfaces? this 'works' // for now but should eventually be improved so that this can, // in fact just be serialized through a convenient interface new public string ToString() { // reserved character string sanitizedName = this.MarkingId.Replace('@', '_'); List colorStringList = new(); foreach (Color color in _markingColors) colorStringList.Add(color.ToHex()); return $"{sanitizedName}@{String.Join(',', colorStringList)}"; } public static Marking? ParseFromDbString(string input) { if (input.Length == 0) return null; var split = input.Split('@'); if (split.Length != 2) return null; List colorList = new(); foreach (string color in split[1].Split(',')) colorList.Add(Color.FromHex(color)); return new Marking(split[0], colorList); } } }