diff --git a/Content.Client/CharacterAppearance/Systems/HumanoidAppearanceSystem.cs b/Content.Client/CharacterAppearance/Systems/HumanoidAppearanceSystem.cs index 4c126ee9c3..a8856db011 100644 --- a/Content.Client/CharacterAppearance/Systems/HumanoidAppearanceSystem.cs +++ b/Content.Client/CharacterAppearance/Systems/HumanoidAppearanceSystem.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Content.Client.Cuffs.Components; using Content.Shared.Body.Components; using Content.Shared.CharacterAppearance; @@ -25,6 +26,19 @@ namespace Content.Client.CharacterAppearance.Systems SubscribeLocalEvent(BodyPartRemoved); } + private List _bodyPartLayers = new List + { + HumanoidVisualLayers.Chest, + HumanoidVisualLayers.Head, + HumanoidVisualLayers.Eyes, + HumanoidVisualLayers.RArm, + HumanoidVisualLayers.LArm, + HumanoidVisualLayers.RHand, + HumanoidVisualLayers.LHand, + HumanoidVisualLayers.RLeg, + HumanoidVisualLayers.LLeg, + }; + private void UpdateLooks(EntityUid uid, HumanoidAppearanceComponent component, ChangedHumanoidAppearanceEvent args) { if(!EntityManager.TryGetComponent(uid, out SpriteComponent? sprite)) @@ -47,6 +61,9 @@ namespace Content.Client.CharacterAppearance.Systems sprite.LayerSetColor(HumanoidVisualLayers.FacialHair, component.CanColorFacialHair ? component.Appearance.FacialHairColor : Color.White); + foreach (var layer in _bodyPartLayers) + sprite.LayerSetColor(layer, component.Appearance.SkinColor); + sprite.LayerSetColor(HumanoidVisualLayers.Eyes, component.Appearance.EyeColor); sprite.LayerSetState(HumanoidVisualLayers.Chest, component.Sex == Sex.Male ? "torso_m" : "torso_f"); diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.Random.cs b/Content.Client/Preferences/UI/HumanoidProfileEditor.Random.cs index 26e22b0e93..3b62aa6434 100644 --- a/Content.Client/Preferences/UI/HumanoidProfileEditor.Random.cs +++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.Random.cs @@ -22,6 +22,8 @@ namespace Content.Client.Preferences.UI UpdateNameEdit(); UpdateHairPickers(); UpdateEyePickers(); + + _skinColor.Value = _random.Next(0, 100); } private void RandomizeName() diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml index 60d045b1b2..815ada6273 100644 --- a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml +++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml @@ -76,6 +76,13 @@ + + + + + diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs index bbd2934ee9..4f55735b32 100644 --- a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs @@ -21,6 +21,7 @@ using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Prototypes; @@ -59,6 +60,7 @@ namespace Content.Client.Preferences.UI private Button _sexFemaleButton => CSexFemale; private Button _sexMaleButton => CSexMale; private OptionButton _genderButton => CPronounsButton; + private Slider _skinColor => CSkin; private OptionButton _clothingButton => CClothingButton; private OptionButton _backpackButton => CBackpackButton; private HairStylePicker _hairPicker => CHairStylePicker; @@ -170,6 +172,46 @@ namespace Content.Client.Preferences.UI #endregion Gender + #region Skin + + // 0 - 100, 0 being gold/yellowish and 100 being dark + // HSV based + // + // 0 - 20 changes the hue + // 20 - 100 changes the value + // 0 is 45 - 20 - 100 + // 20 is 25 - 20 - 100 + // 100 is 25 - 100 - 20 + _skinColor.OnValueChanged += range => + { + if (Profile is null) + return; + + int rangeOffset = (int) range.Value - 20; + + float hue = 25; + float sat = 20; + float val = 100; + + if (rangeOffset < 0) + { + hue += Math.Abs(rangeOffset); + } + else if (rangeOffset > 0) + { + sat += rangeOffset; + val -= rangeOffset; + } + + var color = Color.FromHsv(new Vector4(hue / 360, sat / 100, val / 100, 1.0f)); + + Profile = Profile.WithCharacterAppearance( + Profile.Appearance.WithSkinColor(color)); + IsDirty = true; + }; + + #endregion + #region Hair _hairPicker.Populate(); @@ -528,6 +570,27 @@ namespace Content.Client.Preferences.UI _sexFemaleButton.Pressed = true; } + private void UpdateSkinColor() + { + if (Profile == null) + return; + + var color = Color.ToHsv(Profile.Appearance.SkinColor); + // check for hue/value first, if hue is lower than this percentage + // and value is 1.0 + // then it'll be hue + if (Math.Clamp(color.X, 25f / 360f, 1) > 25f / 360f + && color.Z == 1.0) + { + _skinColor.Value = Math.Abs(45 - (color.X * 360)); + } + // otherwise it'll directly be the saturation + else + { + _skinColor.Value = color.Y * 100; + } + } + private void UpdateGenderControls() { if (Profile == null) @@ -607,6 +670,7 @@ namespace Content.Client.Preferences.UI UpdateNameEdit(); UpdateSexControls(); UpdateGenderControls(); + UpdateSkinColor(); UpdateClothingControls(); UpdateBackpackControls(); UpdateAgeEdit(); diff --git a/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl b/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl index 94985cd837..b6fadc2d50 100644 --- a/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl +++ b/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl @@ -6,6 +6,7 @@ humanoid-profile-editor-sex-label = Sex: humanoid-profile-editor-sex-male-button = Male humanoid-profile-editor-sex-female-button = Female humanoid-profile-editor-age-label = Age: +humanoid-profile-editor-skin-color-label = Skin color: humanoid-profile-editor-pronouns-label = Pronouns: humanoid-profile-editor-pronouns-male-text = He / Him humanoid-profile-editor-pronouns-female-text = She / Her