Files
tbd-station-14/Content.Shared/Humanoid/Markings/Marking.cs
csqrb 8b3d7728d7 Marking default coloring (#13039)
* Marking coloring WIP

* EnsureDefault now supports coloring!

* Now markings have coloring when they get added

* Many things

* yml files

* cleanup

* Some requested changes

* Nullable type and WIP caching

* Time to resolve that thing with deprecated hair fields

* Latest reviews + im still trying to use these hair markings

* FirstOrDefault thing and Tattoo docs

* IDK

* It's now works a bit more properly in preferences GUI

* THEY SYNCING! However preferences GUI still broken and doesn't work properly

* Markings now updating when changing in GUI. However they still don't work properly with bald humanoids

* Forgor...

* Default hair-colored markings will not color to hair if there is no hair

* Fixed default colors for customizable markings

* Fixed bug in prefs GUI that set current hair to null

* Now markings that must match skin color because of limb (e.x. Slimes) - will match skin color

* final tweaks: if hair uses skin color then markings will use skin color as hair color (slimes)

* fix

* fixed dirty. no more funni invis bug

* Mirrors and client profile loading

* default colors soon TM

* review + better coloring

* Hardcode is gone

* diona markings

* oh my god

* fixed CategoryColoring

* cool fallback, clean up and some other tweaks

* code style

* more style

* a
2023-03-04 18:59:07 -08:00

145 lines
4.4 KiB
C#

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 class Marking : IEquatable<Marking>, IComparable<Marking>, IComparable<string>
{
[DataField("markingColor")]
private List<Color> _markingColors = new();
private Marking(string markingId,
List<Color> markingColors)
{
MarkingId = markingId;
_markingColors = markingColors;
}
public Marking(string markingId,
IReadOnlyList<Color> markingColors)
: this(markingId, new List<Color>(markingColors))
{
}
public Marking(string markingId, int colorCount)
{
MarkingId = markingId;
List<Color> 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;
}
/// <summary>
/// ID of the marking prototype.
/// </summary>
[DataField("markingId")]
public string MarkingId { get; } = default!;
/// <summary>
/// All colors currently on this marking.
/// </summary>
[ViewVariables]
public IReadOnlyList<Color> MarkingColors => _markingColors;
/// <summary>
/// If this marking is currently visible.
/// </summary>
[DataField("visible")]
public bool Visible = true;
/// <summary>
/// If this marking should be forcefully applied, regardless of points.
/// </summary>
[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<string> 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<Color> colorList = new();
foreach (string color in split[1].Split(','))
colorList.Add(Color.FromHex(color));
return new Marking(split[0], colorList);
}
}
}