Sex restriction for markings (#19894)
* Add sex restriction to markings * Apply to existing systems
This commit is contained in:
@@ -188,7 +188,7 @@ namespace Content.Shared.Humanoid
|
||||
return new(color.RByte, color.GByte, color.BByte);
|
||||
}
|
||||
|
||||
public static HumanoidCharacterAppearance EnsureValid(HumanoidCharacterAppearance appearance, string species)
|
||||
public static HumanoidCharacterAppearance EnsureValid(HumanoidCharacterAppearance appearance, string species, Sex sex)
|
||||
{
|
||||
var hairStyleId = appearance.HairStyleId;
|
||||
var facialHairStyleId = appearance.FacialHairStyleId;
|
||||
@@ -223,6 +223,7 @@ namespace Content.Shared.Humanoid
|
||||
}
|
||||
|
||||
markingSet.EnsureSpecies(species, skinColor, markingManager);
|
||||
markingSet.EnsureSexes(sex, markingManager);
|
||||
}
|
||||
|
||||
return new HumanoidCharacterAppearance(
|
||||
|
||||
@@ -66,6 +66,74 @@ namespace Content.Shared.Humanoid.Markings
|
||||
{
|
||||
continue;
|
||||
}
|
||||
res.Add(key, marking);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Markings by category and sex.
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="sex"></param>
|
||||
/// <remarks>
|
||||
/// This is done per category, as enumerating over every single marking by species isn't useful.
|
||||
/// Please make a pull request if you find a use case for that behavior.
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public IReadOnlyDictionary<string, MarkingPrototype> MarkingsByCategoryAndSex(MarkingCategories category,
|
||||
Sex sex)
|
||||
{
|
||||
var res = new Dictionary<string, MarkingPrototype>();
|
||||
|
||||
foreach (var (key, marking) in MarkingsByCategory(category))
|
||||
{
|
||||
if (marking.SexRestriction != null && marking.SexRestriction != sex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
res.Add(key, marking);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Markings by category, species and sex.
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="species"></param>
|
||||
/// <param name="sex"></param>
|
||||
/// <remarks>
|
||||
/// This is done per category, as enumerating over every single marking by species isn't useful.
|
||||
/// Please make a pull request if you find a use case for that behavior.
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public IReadOnlyDictionary<string, MarkingPrototype> MarkingsByCategoryAndSpeciesAndSex(MarkingCategories category,
|
||||
string species, Sex sex)
|
||||
{
|
||||
var speciesProto = _prototypeManager.Index<SpeciesPrototype>(species);
|
||||
var onlyWhitelisted = _prototypeManager.Index<MarkingPointsPrototype>(speciesProto.MarkingPoints).OnlyWhitelisted;
|
||||
var res = new Dictionary<string, MarkingPrototype>();
|
||||
|
||||
foreach (var (key, marking) in MarkingsByCategory(category))
|
||||
{
|
||||
if (onlyWhitelisted && marking.SpeciesRestrictions == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marking.SpeciesRestrictions != null && !marking.SpeciesRestrictions.Contains(species))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marking.SexRestriction != null && marking.SexRestriction != sex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
res.Add(key, marking);
|
||||
}
|
||||
@@ -84,8 +152,9 @@ namespace Content.Shared.Humanoid.Markings
|
||||
/// <param name="marking"></param>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="species"></param>
|
||||
/// <param name="sex"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsValidMarking(Marking marking, MarkingCategories category, string species)
|
||||
public bool IsValidMarking(Marking marking, MarkingCategories category, string species, Sex sex)
|
||||
{
|
||||
if (!TryGetMarking(marking, out var proto))
|
||||
{
|
||||
@@ -93,7 +162,8 @@ namespace Content.Shared.Humanoid.Markings
|
||||
}
|
||||
|
||||
if (proto.MarkingCategory != category ||
|
||||
proto.SpeciesRestrictions != null && !proto.SpeciesRestrictions.Contains(species))
|
||||
proto.SpeciesRestrictions != null && !proto.SpeciesRestrictions.Contains(species) ||
|
||||
proto.SexRestriction != null && proto.SexRestriction != sex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -121,7 +191,7 @@ namespace Content.Shared.Humanoid.Markings
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanBeApplied(string species, Marking marking, IPrototypeManager? prototypeManager = null)
|
||||
public bool CanBeApplied(string species, Sex sex, Marking marking, IPrototypeManager? prototypeManager = null)
|
||||
{
|
||||
IoCManager.Resolve(ref prototypeManager);
|
||||
|
||||
@@ -143,10 +213,16 @@ namespace Content.Shared.Humanoid.Markings
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prototype.SexRestriction != null && prototype.SexRestriction != sex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanBeApplied(string species, MarkingPrototype prototype, IPrototypeManager? prototypeManager = null)
|
||||
public bool CanBeApplied(string species, Sex sex, MarkingPrototype prototype, IPrototypeManager? prototypeManager = null)
|
||||
{
|
||||
IoCManager.Resolve(ref prototypeManager);
|
||||
|
||||
@@ -163,6 +239,12 @@ namespace Content.Shared.Humanoid.Markings
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prototype.SexRestriction != null && prototype.SexRestriction != sex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -181,7 +263,7 @@ namespace Content.Shared.Humanoid.Markings
|
||||
alpha = 1f;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
alpha = sprite.LayerAlpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace Content.Shared.Humanoid.Markings
|
||||
[DataField("speciesRestriction")]
|
||||
public List<string>? SpeciesRestrictions { get; private set; }
|
||||
|
||||
[DataField("sexRestriction")]
|
||||
public Sex? SexRestriction { get; private set; }
|
||||
|
||||
[DataField("followSkinColor")]
|
||||
public bool FollowSkinColor { get; private set; } = false;
|
||||
|
||||
|
||||
@@ -199,6 +199,40 @@ public sealed partial class MarkingSet
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters markings based on sex and it's restrictions in the marking's prototype from this marking set.
|
||||
/// </summary>
|
||||
/// <param name="sex">The species to filter.</param>
|
||||
/// <param name="markingManager">Marking manager.</param>
|
||||
public void EnsureSexes(Sex sex, MarkingManager? markingManager = null)
|
||||
{
|
||||
IoCManager.Resolve(ref markingManager);
|
||||
|
||||
var toRemove = new List<(MarkingCategories category, string id)>();
|
||||
|
||||
foreach (var (category, list) in Markings)
|
||||
{
|
||||
foreach (var marking in list)
|
||||
{
|
||||
if (!markingManager.TryGetMarking(marking, out var prototype))
|
||||
{
|
||||
toRemove.Add((category, marking.MarkingId));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prototype.SexRestriction != null && prototype.SexRestriction != sex)
|
||||
{
|
||||
toRemove.Add((category, marking.MarkingId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var remove in toRemove)
|
||||
{
|
||||
Remove(remove.category, remove.id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that all markings in this set are valid.
|
||||
/// </summary>
|
||||
|
||||
@@ -254,6 +254,7 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
|
||||
|
||||
var oldSex = humanoid.Sex;
|
||||
humanoid.Sex = sex;
|
||||
humanoid.MarkingSet.EnsureSexes(sex, _markingManager);
|
||||
RaiseLocalEvent(uid, new SexChangedEvent(oldSex, sex));
|
||||
|
||||
if (sync)
|
||||
@@ -308,13 +309,13 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
|
||||
? profile.Appearance.SkinColor.WithAlpha(facialHairAlpha) : profile.Appearance.FacialHairColor;
|
||||
|
||||
if (_markingManager.Markings.TryGetValue(profile.Appearance.HairStyleId, out var hairPrototype) &&
|
||||
_markingManager.CanBeApplied(profile.Species, hairPrototype, _prototypeManager))
|
||||
_markingManager.CanBeApplied(profile.Species, profile.Sex, hairPrototype, _prototypeManager))
|
||||
{
|
||||
AddMarking(uid, profile.Appearance.HairStyleId, hairColor, false);
|
||||
}
|
||||
|
||||
if (_markingManager.Markings.TryGetValue(profile.Appearance.FacialHairStyleId, out var facialHairPrototype) &&
|
||||
_markingManager.CanBeApplied(profile.Species, facialHairPrototype, _prototypeManager))
|
||||
_markingManager.CanBeApplied(profile.Species, profile.Sex, facialHairPrototype, _prototypeManager))
|
||||
{
|
||||
AddMarking(uid, profile.Appearance.FacialHairStyleId, facialHairColor, false);
|
||||
}
|
||||
|
||||
@@ -45,18 +45,21 @@ public sealed class HumanoidMarkingModifierState : BoundUserInterfaceState
|
||||
public HumanoidMarkingModifierState(
|
||||
MarkingSet markingSet,
|
||||
string species,
|
||||
Sex sex,
|
||||
Color skinColor,
|
||||
Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> customBaseLayers
|
||||
)
|
||||
{
|
||||
MarkingSet = markingSet;
|
||||
Species = species;
|
||||
Sex = sex;
|
||||
SkinColor = skinColor;
|
||||
CustomBaseLayers = customBaseLayers;
|
||||
}
|
||||
|
||||
public MarkingSet MarkingSet { get; }
|
||||
public string Species { get; }
|
||||
public Sex Sex { get; }
|
||||
public Color SkinColor { get; }
|
||||
public Color EyeColor { get; }
|
||||
public Color? HairColor { get; }
|
||||
|
||||
Reference in New Issue
Block a user