diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
index d6377ba84f..dfdfece979 100644
--- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
+++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
@@ -9,7 +9,6 @@ using Content.Client.Players.PlayTimeTracking;
using Content.Client.Sprite;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Systems.Guidebook;
-using Content.Shared._CP14.Humanoid;
using Content.Shared.CCVar;
using Content.Shared.Clothing;
using Content.Shared.GameTicking;
@@ -1123,22 +1122,6 @@ namespace Content.Client.Lobby.UI
break;
}
- // CP14 - Custom HumanoidSkinColor - Start
- case HumanoidSkinColor.TieflingHues:
- {
- if (!RgbSkinColorContainer.Visible)
- {
- Skin.Visible = false;
- RgbSkinColorContainer.Visible = true;
- }
-
- var color = CP14SkinColor.MakeTieflingHueValid(_rgbSkinColorSelector.Color);
-
- Markings.CurrentSkinColor = color;
- Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
- break;
- }
- // CP14 - Custom HumanoidSkinColor - End
}
ReloadProfilePreview();
@@ -1343,19 +1326,6 @@ namespace Content.Client.Lobby.UI
break;
}
- // CP14 - Custom HumanoidSkinColor - Start
- case HumanoidSkinColor.TieflingHues:
- {
- if (!RgbSkinColorContainer.Visible)
- {
- Skin.Visible = false;
- RgbSkinColorContainer.Visible = true;
- }
-
- _rgbSkinColorSelector.Color = CP14SkinColor.MakeTieflingHueValid(Profile.Appearance.SkinColor);
- break;
- }
- // CP14 - Custom HumanoidSkinColor - End
}
}
diff --git a/Content.Shared/_CP14/Humanoid/CP14ElfTonedSkinColoration.cs b/Content.Shared/_CP14/Humanoid/CP14ElfTonedSkinColoration.cs
new file mode 100644
index 0000000000..9f4fc373b2
--- /dev/null
+++ b/Content.Shared/_CP14/Humanoid/CP14ElfTonedSkinColoration.cs
@@ -0,0 +1,75 @@
+using System.Numerics;
+using Content.Shared.Humanoid;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._CP14.Humanoid;
+
+///
+/// Unary coloration strategy that returns human skin tones, with 0 being lightest and 100 being darkest
+///
+[DataDefinition]
+[Serializable, NetSerializable]
+public sealed partial class CP14ElfTonedSkinColoration : ISkinColorationStrategy
+{
+ [DataField]
+ public Color ValidElfSkinTone = Color.FromHsv(new Vector4(0.07f, 0.05f, 1f, 1f));
+
+ public SkinColorationStrategyInput InputType => SkinColorationStrategyInput.Unary;
+
+ public bool VerifySkinColor(Color color)
+ {
+ var hsv = Color.ToHsv(color);
+ var hue = Math.Round(hsv.X * 360f);
+ var sat = Math.Round(hsv.Y * 100f);
+ var val = Math.Round(hsv.Z * 100f);
+
+ if (hue < 20f || hue > 270f)
+ return false;
+
+ if (sat < 5f || sat > 35f)
+ return false;
+
+ if (val < 20f || val > 100f)
+ return false;
+
+ return true;
+ }
+
+ public Color ClosestSkinColor(Color color)
+ {
+ return ValidElfSkinTone;
+ }
+
+ public Color FromUnary(float t)
+ {
+ var tone = Math.Clamp(t, 0f, 100f);
+
+ var startSat = 5f;
+ var startVal = 100f;
+
+ var endSat = 30f;
+ var endVal = 25f;
+
+ var hue = 260f;
+ var sat = MathHelper.Lerp(startSat, endSat, tone / 100f);
+ var val = MathHelper.Lerp(startVal, endVal, tone / 100f);
+
+ return Color.FromHsv(new Vector4(hue / 360f, sat / 100f, val / 100f, 1.0f));
+ }
+
+ public float ToUnary(Color color)
+ {
+ var hsv = Color.ToHsv(color);
+
+ // Вычисляем относительное положение между светлой и тёмной точкой
+ var hue = hsv.X * 360f;
+ var sat = hsv.Y * 100f;
+ var val = hsv.Z * 100f;
+
+ // Нормируем по value, потому что основной градиент идёт по яркости
+ var progressVal = (100f - val) / (100f - 25f);
+
+ // Можно слегка учитывать hue/sat, но value остаётся главным драйвером
+ return Math.Clamp(progressVal * 100f, 0f, 100f);
+ }
+}
diff --git a/Content.Shared/_CP14/Humanoid/CP14SkinColor.cs b/Content.Shared/_CP14/Humanoid/CP14SkinColor.cs
deleted file mode 100644
index 5f92fca0ed..0000000000
--- a/Content.Shared/_CP14/Humanoid/CP14SkinColor.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace Content.Shared._CP14.Humanoid;
-
-public static class CP14SkinColor
-{
- public const float MinTieflingHuesLightness = 10f / 100f;
- public const float MaxTieflingHuesLightness = 35f / 100f;
-
- public static Color TieflingHues(Color color)
- {
- return color;
- }
-
- public static Color MakeTieflingHueValid(Color color)
- {
- color.G = Math.Min(color.G, color.B);
-
- var hsl = Color.ToHsl(color);
- hsl.Z = Math.Clamp(hsl.Z, MinTieflingHuesLightness, MaxTieflingHuesLightness);
-
- return Color.FromHsl(hsl);
- }
-
- public static bool VerifyTieflingHues(Color color)
- {
- var hsl = Color.ToHsl(color);
- var lightness = hsl.Z;
-
- // Allows you to use shades of green, but not make green tieflings
- if (color.G > color.B)
- return false;
-
- // No black or white holes instead of tieflings
- if (lightness is < MinTieflingHuesLightness or > MaxTieflingHuesLightness)
- return false;
-
- return true;
- }
-}
diff --git a/Content.Shared/_CP14/MagicEnergy/CP14SharedMagicEnergySystem.cs b/Content.Shared/_CP14/MagicEnergy/CP14SharedMagicEnergySystem.cs
index 4ebd0fd36f..581e55d153 100644
--- a/Content.Shared/_CP14/MagicEnergy/CP14SharedMagicEnergySystem.cs
+++ b/Content.Shared/_CP14/MagicEnergy/CP14SharedMagicEnergySystem.cs
@@ -39,7 +39,7 @@ public abstract class CP14SharedMagicEnergySystem : EntitySystem
if (ent.Comp.MagicAlert is null)
return;
- _alerts.ClearAlert(ent, ent.Comp.MagicAlert.Value);
+ _alerts.ClearAlert(ent.Owner, ent.Comp.MagicAlert.Value);
}
private void OnExamined(Entity ent, ref ExaminedEvent args)
@@ -68,7 +68,7 @@ public abstract class CP14SharedMagicEnergySystem : EntitySystem
(float) ent.Comp.MaxEnergy,
_alerts.GetMaxSeverity(ent.Comp.MagicAlert.Value));
- _alerts.ShowAlert(ent, ent.Comp.MagicAlert.Value, (short) level);
+ _alerts.ShowAlert(ent.Owner, ent.Comp.MagicAlert.Value, (short) level);
}
public void ChangeEnergy(Entity ent,
diff --git a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs
index 05c3480a95..d12aea3d03 100644
--- a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs
+++ b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs
@@ -122,12 +122,12 @@ public abstract partial class CP14SharedReligionGodSystem
private void OnPendingFollowerInit(Entity ent, ref MapInitEvent args)
{
- _alerts.ShowAlert(ent, AlertProto);
+ _alerts.ShowAlert(ent.Owner, AlertProto);
}
private void OnPendingFollowerShutdown(Entity ent, ref ComponentShutdown args)
{
- _alerts.ClearAlert(ent, AlertProto);
+ _alerts.ClearAlert(ent.Owner, AlertProto);
}
private bool CanBecomeFollower(EntityUid target, ProtoId religion)
diff --git a/Resources/Prototypes/Species/vulpkanin.yml b/Resources/Prototypes/Species/vulpkanin.yml
index 6f8acfa73e..c5009bf732 100644
--- a/Resources/Prototypes/Species/vulpkanin.yml
+++ b/Resources/Prototypes/Species/vulpkanin.yml
@@ -1,7 +1,7 @@
- type: species
id: Vulpkanin
name: species-name-vulpkanin
- roundStart: true
+ roundStart: false
prototype: MobVulpkanin
sprites: MobVulpkaninSprites
defaultSkinTone: "#5a3f2d"
diff --git a/Resources/Prototypes/_CP14/Species/carcat.yml b/Resources/Prototypes/_CP14/Species/carcat.yml
index 4c1201a103..eba1ee6788 100644
--- a/Resources/Prototypes/_CP14/Species/carcat.yml
+++ b/Resources/Prototypes/_CP14/Species/carcat.yml
@@ -6,7 +6,7 @@
sprites: CP14MobCarcatSprites
markingLimits: CP14MobCarcatMarkingLimits
dollPrototype: CP14MobCarcatDummy
- skinColoration: Hues
+ skinColoration: CP14CarcatHues
defaultSkinTone: "#4a382f"
maleFirstNames: CP14_Names_Carcat_First
femaleFirstNames: CP14_Names_Carcat_First
diff --git a/Resources/Prototypes/_CP14/Species/elf.yml b/Resources/Prototypes/_CP14/Species/elf.yml
index 98e87d3d99..a0ccbd3776 100644
--- a/Resources/Prototypes/_CP14/Species/elf.yml
+++ b/Resources/Prototypes/_CP14/Species/elf.yml
@@ -6,7 +6,7 @@
sprites: CP14MobElfSprites
markingLimits: CP14MobElfMarkingLimits
dollPrototype: CP14MobElfDummy
- skinColoration: HumanToned
+ skinColoration: CP14Elf
maleFirstNames: CP14_Names_Elf_Male_First
femaleFirstNames: CP14_Names_Elf_Female_First
lastNames: CP14_Names_Elf_Last
diff --git a/Resources/Prototypes/_CP14/Species/silva.yml b/Resources/Prototypes/_CP14/Species/silva.yml
index e408bb0607..d5edeb6a80 100644
--- a/Resources/Prototypes/_CP14/Species/silva.yml
+++ b/Resources/Prototypes/_CP14/Species/silva.yml
@@ -6,7 +6,7 @@
sprites: CP14MobSilvaSprites
markingLimits: CP14MobSilvaMarkingLimits
dollPrototype: CP14MobSilvaDummy
- skinColoration: VoxFeathers
+ skinColoration: CP14SilvasHues
defaultSkinTone: "#6c741d"
maleFirstNames: CP14_Names_Silva_Male_First
femaleFirstNames: CP14_Names_Silva_Female_First
diff --git a/Resources/Prototypes/_CP14/Species/skin_colorations.yml b/Resources/Prototypes/_CP14/Species/skin_colorations.yml
new file mode 100644
index 0000000000..e542b07c39
--- /dev/null
+++ b/Resources/Prototypes/_CP14/Species/skin_colorations.yml
@@ -0,0 +1,24 @@
+- type: skinColoration
+ id: CP14TieflingHues
+ strategy: !type:ClampedHsvColoration
+ hue: [0.8, 1.05]
+ saturation: [0.15, 0.8]
+ value: [0.25, 0.55]
+
+- type: skinColoration
+ id: CP14Elf
+ strategy: !type:CP14ElfTonedSkinColoration {}
+
+- type: skinColoration
+ id: CP14SilvasHues
+ strategy: !type:ClampedHsvColoration
+ hue: [0.1, 0.4]
+ saturation: [0.15, 0.8]
+ value: [0.25, 0.55]
+
+- type: skinColoration
+ id: CP14CarcatHues
+ strategy: !type:ClampedHsvColoration
+ hue: [0.05, 0.55]
+ saturation: [0.15, 0.8]
+ value: [0.25, 0.55]
\ No newline at end of file
diff --git a/Resources/Prototypes/_CP14/Species/tiefling.yml b/Resources/Prototypes/_CP14/Species/tiefling.yml
index 8d2e633cff..3caaff0976 100644
--- a/Resources/Prototypes/_CP14/Species/tiefling.yml
+++ b/Resources/Prototypes/_CP14/Species/tiefling.yml
@@ -6,7 +6,7 @@
sprites: CP14MobTieflingSprites
markingLimits: CP14MobTieflingMarkingLimits
dollPrototype: CP14MobTieflingDummy
- skinColoration: TieflingHues
+ skinColoration: CP14TieflingHues
maleFirstNames: CP14_Names_Tiefling_Male_First
femaleFirstNames: CP14_Names_Tiefling_Female_First
lastNames: CP14_Names_Tiefling_Last