Skip to content

Commit 98c7d7c

Browse files
committed
basic refactor
1 parent c947f74 commit 98c7d7c

File tree

22 files changed

+303
-425
lines changed

22 files changed

+303
-425
lines changed

Content.Client/Lobby/UI/HumanoidProfileEditor.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@
9595
<!-- Skin -->
9696
<BoxContainer Margin="10" HorizontalExpand="True" Orientation="Vertical">
9797
<Label Text="{Loc 'humanoid-profile-editor-skin-color-label'}" />
98-
<Slider HorizontalExpand="True" Name="Skin" MinValue="0" MaxValue="100" Value="20" />
99-
<BoxContainer Name="RgbSkinColorContainer" Visible="False" Orientation="Vertical" HorizontalExpand="True"></BoxContainer>
98+
<Slider HorizontalExpand="True" Name="Skin" MinValue="0" MaxValue="100" Value="20" Visible="False" />
99+
<BoxContainer Name="RgbSkinColorContainer" Visible="True" Orientation="Vertical" HorizontalExpand="True"></BoxContainer>
100100
</BoxContainer>
101101
<!-- Hair -->
102102
<BoxContainer Margin="10" Orientation="Horizontal">

Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs

Lines changed: 25 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,68 +1085,26 @@ private void OnMarkingChange(MarkingSet markings)
10851085

10861086
private void OnSkinColorOnValueChanged()
10871087
{
1088-
if (Profile is null) return;
1089-
1090-
var skin = _prototypeManager.Index<SpeciesPrototype>(Profile.Species).SkinColoration;
1091-
1092-
switch (skin)
1093-
{
1094-
case HumanoidSkinColor.HumanToned:
1095-
{
1096-
if (!Skin.Visible)
1097-
{
1098-
Skin.Visible = true;
1099-
RgbSkinColorContainer.Visible = false;
1100-
}
1101-
1102-
var color = SkinColor.HumanSkinTone((int) Skin.Value);
1103-
1104-
Markings.CurrentSkinColor = color;
1105-
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));//
1106-
break;
1107-
}
1108-
case HumanoidSkinColor.Hues:
1109-
{
1110-
if (!RgbSkinColorContainer.Visible)
1111-
{
1112-
Skin.Visible = false;
1113-
RgbSkinColorContainer.Visible = true;
1114-
}
1115-
1116-
Markings.CurrentSkinColor = _rgbSkinColorSelector.Color;
1117-
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(_rgbSkinColorSelector.Color));
1118-
break;
1119-
}
1120-
case HumanoidSkinColor.TintedHues:
1121-
{
1122-
if (!RgbSkinColorContainer.Visible)
1123-
{
1124-
Skin.Visible = false;
1125-
RgbSkinColorContainer.Visible = true;
1126-
}
1088+
if (Profile is null)
1089+
return;
11271090

1128-
var color = SkinColor.TintedHues(_rgbSkinColorSelector.Color);
1091+
var speciesPrototype = _prototypeManager.Index(Profile.Species);
1092+
var coloringRules = speciesPrototype.ColoringRules;
11291093

1130-
Markings.CurrentSkinColor = color;
1131-
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
1132-
break;
1133-
}
1134-
case HumanoidSkinColor.VoxFeathers:
1135-
{
1136-
if (!RgbSkinColorContainer.Visible)
1137-
{
1138-
Skin.Visible = false;
1139-
RgbSkinColorContainer.Visible = true;
1140-
}
1094+
if (coloringRules.Count == 0)
1095+
return;
11411096

1142-
var color = SkinColor.ClosestVoxColor(_rgbSkinColorSelector.Color);
1097+
var inputColor = _rgbSkinColorSelector.Color;
1098+
var outputColor = inputColor;
11431099

1144-
Markings.CurrentSkinColor = color;
1145-
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
1146-
break;
1147-
}
1100+
foreach (var rule in coloringRules)
1101+
{
1102+
outputColor = rule.Clamp(outputColor);
11481103
}
11491104

1105+
Markings.CurrentSkinColor = outputColor;
1106+
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(outputColor));
1107+
11501108
ReloadProfilePreview();
11511109
}
11521110

@@ -1317,63 +1275,24 @@ private void UpdateSexControls()
13171275

13181276
private void UpdateSkinColor()
13191277
{
1320-
if (Profile == null)
1278+
if (Profile is null)
13211279
return;
13221280

1323-
var skin = _prototypeManager.Index<SpeciesPrototype>(Profile.Species).SkinColoration;
1324-
1325-
switch (skin)
1326-
{
1327-
case HumanoidSkinColor.HumanToned:
1328-
{
1329-
if (!Skin.Visible)
1330-
{
1331-
Skin.Visible = true;
1332-
RgbSkinColorContainer.Visible = false;
1333-
}
1334-
1335-
Skin.Value = SkinColor.HumanSkinToneFromColor(Profile.Appearance.SkinColor);
1336-
1337-
break;
1338-
}
1339-
case HumanoidSkinColor.Hues:
1340-
{
1341-
if (!RgbSkinColorContainer.Visible)
1342-
{
1343-
Skin.Visible = false;
1344-
RgbSkinColorContainer.Visible = true;
1345-
}
1346-
1347-
// set the RGB values to the direct values otherwise
1348-
_rgbSkinColorSelector.Color = Profile.Appearance.SkinColor;
1349-
break;
1350-
}
1351-
case HumanoidSkinColor.TintedHues:
1352-
{
1353-
if (!RgbSkinColorContainer.Visible)
1354-
{
1355-
Skin.Visible = false;
1356-
RgbSkinColorContainer.Visible = true;
1357-
}
1281+
var speciesPrototype = _prototypeManager.Index(Profile.Species);
1282+
var coloringRules = speciesPrototype.ColoringRules;
13581283

1359-
// set the RGB values to the direct values otherwise
1360-
_rgbSkinColorSelector.Color = Profile.Appearance.SkinColor;
1361-
break;
1362-
}
1363-
case HumanoidSkinColor.VoxFeathers:
1364-
{
1365-
if (!RgbSkinColorContainer.Visible)
1366-
{
1367-
Skin.Visible = false;
1368-
RgbSkinColorContainer.Visible = true;
1369-
}
1284+
if (coloringRules.Count == 0)
1285+
return;
13701286

1371-
_rgbSkinColorSelector.Color = SkinColor.ClosestVoxColor(Profile.Appearance.SkinColor);
1287+
var skinColor = Profile.Appearance.SkinColor;
13721288

1373-
break;
1374-
}
1289+
// Apply all coloring rules to ensure the color is valid.
1290+
foreach (var rule in coloringRules)
1291+
{
1292+
skinColor = rule.Clamp(skinColor);
13751293
}
13761294

1295+
_rgbSkinColorSelector.Color = skinColor;
13771296
}
13781297

13791298
public void UpdateSpeciesGuidebookIcon()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using JetBrains.Annotations;
2+
using Robust.Shared.Random;
3+
4+
namespace Content.Shared.Humanoid.ColoringScheme;
5+
6+
/// <summary>
7+
/// Abstract rule for validating, clamping, and randomizing colors for a specific part of a coloring scheme.
8+
/// </summary>
9+
[ImplicitDataDefinitionForInheritors]
10+
[MeansImplicitUse]
11+
public abstract partial class ColoringSchemeRule
12+
{
13+
/// <summary>
14+
/// Verify that the color is valid according to this rule.
15+
/// </summary>
16+
/// <param name="color"></param>
17+
/// <returns></returns>
18+
public abstract bool Verify(Color color);
19+
20+
/// <summary>
21+
/// Clamp the color to be valid according to this rule.
22+
/// </summary>
23+
/// <param name="color"></param>
24+
/// <returns></returns>
25+
public abstract Color Clamp(Color color);
26+
27+
/// <summary>
28+
/// Generate a random color according to this rule.
29+
/// </summary>
30+
/// <param name="random"></param>
31+
/// <returns></returns>
32+
public abstract Color Randomize(IRobustRandom random);
33+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Numerics;
2+
using Robust.Shared.Random;
3+
4+
namespace Content.Shared.Humanoid.ColoringScheme;
5+
6+
public sealed partial class Hues : ColoringSchemeRule
7+
{
8+
private const float MinLightness = 0.175f;
9+
10+
public override Color Randomize(IRobustRandom random)
11+
{
12+
var hsv = new Vector4(random.NextFloat(1f), random.NextFloat(1f), random.NextFloat(1f) * (1f - MinLightness) + MinLightness, 1f);
13+
return Color.FromHsv(hsv);
14+
}
15+
16+
public override bool Verify(Color color)
17+
{
18+
var hsv = Color.ToHsv(color);
19+
return hsv.Z >= MinLightness;
20+
}
21+
22+
public override Color Clamp(Color color)
23+
{
24+
var hsv = Color.ToHsv(color);
25+
hsv.Z = Math.Max(hsv.Z, MinLightness);
26+
return Color.FromHsv(hsv);
27+
}
28+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System.Numerics;
2+
using Robust.Shared.Random;
3+
4+
namespace Content.Shared.Humanoid.ColoringScheme;
5+
6+
public sealed partial class HumanToned : ColoringSchemeRule
7+
{
8+
public override Color Randomize(IRobustRandom random)
9+
{
10+
var tone = random.Next(0, 101);
11+
return ToneToColor(tone);
12+
}
13+
14+
public override bool Verify(Color color)
15+
{
16+
var hsv = Color.ToHsv(color);
17+
float hue = hsv.X * 360f;
18+
float sat = hsv.Y * 100f;
19+
float val = hsv.Z * 100f;
20+
21+
return hue >= 25 && hue <= 45 && sat >= 20 && val >= 20;
22+
}
23+
24+
public override Color Clamp(Color color)
25+
{
26+
float tone = ColorToTone(color);
27+
return ToneToColor((int)Math.Clamp(tone, 0, 100));
28+
}
29+
30+
private static Color ToneToColor(int tone)
31+
{
32+
// 0 - 100, 0 being gold/yellowish and 100 being dark
33+
// HSV based
34+
//
35+
// 0 - 20 changes the hue
36+
// 20 - 100 changes the value
37+
// 0 is 45 - 20 - 100
38+
// 20 is 25 - 20 - 100
39+
// 100 is 25 - 100 - 20
40+
41+
tone = Math.Clamp(tone, 0, 100);
42+
float rangeOffset = tone - 20;
43+
44+
float hue = 25f;
45+
float sat = 20f;
46+
float val = 100f;
47+
48+
if (rangeOffset <= 0)
49+
{
50+
hue += Math.Abs(rangeOffset);
51+
}
52+
else
53+
{
54+
sat += rangeOffset;
55+
val -= rangeOffset;
56+
}
57+
58+
return Color.FromHsv(new Vector4(hue / 360f, sat / 100f, val / 100f, 1f));
59+
}
60+
61+
private static float ColorToTone(Color color)
62+
{
63+
var hsv = Color.ToHsv(color);
64+
65+
if (Math.Clamp(hsv.X, 25f / 360f, 1f) > 25f / 360f && hsv.Z == 1f)
66+
return Math.Abs(45 - (hsv.X * 360f));
67+
68+
return hsv.Y * 100f;
69+
}
70+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Numerics;
2+
using Robust.Shared.Random;
3+
4+
namespace Content.Shared.Humanoid.ColoringScheme;
5+
6+
public sealed partial class TintedHues : ColoringSchemeRule
7+
{
8+
private const float MaxSaturation = 0.1f;
9+
private const float MinLightness = 0.85f;
10+
11+
public override Color Randomize(IRobustRandom random)
12+
{
13+
var hsv = new Vector4(random.NextFloat(1f), MaxSaturation, random.NextFloat(1f) * (1f - MinLightness) + MinLightness, 1f);
14+
return Color.FromHsv(hsv);
15+
}
16+
17+
public override bool Verify(Color color)
18+
{
19+
var hsl = Color.ToHsl(color);
20+
return hsl.Y <= MaxSaturation && hsl.Z >= MinLightness;
21+
}
22+
23+
public override Color Clamp(Color color)
24+
{
25+
var hsl = Color.ToHsl(color);
26+
hsl.Y = Math.Min(hsl.Y, MaxSaturation);
27+
hsl.Z = Math.Max(hsl.Z, MinLightness);
28+
return Color.FromHsv(hsl);
29+
}
30+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.Numerics;
2+
using Robust.Shared.Random;
3+
4+
namespace Content.Shared.Humanoid.ColoringScheme;
5+
6+
public sealed partial class VoxFeathers : ColoringSchemeRule
7+
{
8+
private const float MinHue = 29f / 360f;
9+
private const float MaxHue = 174f / 360f;
10+
private const float MinSaturation = 0.2f;
11+
private const float MaxSaturation = 0.88f;
12+
private const float MinValue = 0.36f;
13+
private const float MaxValue = 0.55f;
14+
15+
public override Color Randomize(IRobustRandom random)
16+
{
17+
var h = random.NextFloat() * (MaxHue - MinHue) + MinHue;
18+
var s = random.NextFloat() * (MaxSaturation - MinSaturation) + MinSaturation;
19+
var v = random.NextFloat() * (MaxValue - MinValue) + MinValue;
20+
return Color.FromHsv(new Vector4(h, s, v, 1f));
21+
}
22+
23+
public override bool Verify(Color color)
24+
{
25+
var hsv = Color.ToHsv(color);
26+
return hsv.X >= MinHue && hsv.X <= MaxHue &&
27+
hsv.Y >= MinSaturation && hsv.Y <= MaxSaturation &&
28+
hsv.Z >= MinValue && hsv.Z <= MaxValue;
29+
}
30+
31+
public override Color Clamp(Color color)
32+
{
33+
var hsv = Color.ToHsv(color);
34+
hsv.X = Math.Clamp(hsv.X, MinHue, MaxHue);
35+
hsv.Y = Math.Clamp(hsv.Y, MinSaturation, MaxSaturation);
36+
hsv.Z = Math.Clamp(hsv.Z, MinValue, MaxValue);
37+
return Color.FromHsv(hsv);
38+
}
39+
}

0 commit comments

Comments
 (0)