Add undergarments & "Censor Nudity" toggle to options (#33185)

* Initial commit

* Attribution

* Review changes

* Added comment for upstream
This commit is contained in:
SlamBamActionman
2025-03-05 10:14:01 +01:00
committed by GitHub
parent 8785085be6
commit 27cfc0939c
42 changed files with 483 additions and 4 deletions

View File

@@ -1,8 +1,10 @@
using Content.Shared.CCVar;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Robust.Client.GameObjects;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@@ -12,12 +14,15 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly MarkingManager _markingManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<HumanoidAppearanceComponent, AfterAutoHandleStateEvent>(OnHandleState);
Subs.CVar(_configurationManager, CCVars.AccessibilityClientCensorNudity, OnCvarChanged, true);
Subs.CVar(_configurationManager, CCVars.AccessibilityServerCensorNudity, OnCvarChanged, true);
}
private void OnHandleState(EntityUid uid, HumanoidAppearanceComponent component, ref AfterAutoHandleStateEvent args)
@@ -25,6 +30,15 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
UpdateSprite(component, Comp<SpriteComponent>(uid));
}
private void OnCvarChanged(bool value)
{
var humanoidQuery = EntityManager.AllEntityQueryEnumerator<HumanoidAppearanceComponent, SpriteComponent>();
while (humanoidQuery.MoveNext(out var _, out var humanoidComp, out var spriteComp))
{
UpdateSprite(humanoidComp, spriteComp);
}
}
private void UpdateSprite(HumanoidAppearanceComponent component, SpriteComponent sprite)
{
UpdateLayers(component, sprite);
@@ -207,16 +221,30 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
// Really, markings should probably be a separate component altogether.
ClearAllMarkings(humanoid, sprite);
var censorNudity = _configurationManager.GetCVar(CCVars.AccessibilityClientCensorNudity) ||
_configurationManager.GetCVar(CCVars.AccessibilityServerCensorNudity);
// The reason we're splitting this up is in case the character already has undergarment equipped in that slot.
var applyUndergarmentTop = censorNudity;
var applyUndergarmentBottom = censorNudity;
foreach (var markingList in humanoid.MarkingSet.Markings.Values)
{
foreach (var marking in markingList)
{
if (_markingManager.TryGetMarking(marking, out var markingPrototype))
{
ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite);
if (markingPrototype.BodyPart == HumanoidVisualLayers.UndergarmentTop)
applyUndergarmentTop = false;
else if (markingPrototype.BodyPart == HumanoidVisualLayers.UndergarmentBottom)
applyUndergarmentBottom = false;
}
}
}
humanoid.ClientOldMarkings = new MarkingSet(humanoid.MarkingSet);
AddUndergarments(humanoid, sprite, applyUndergarmentTop, applyUndergarmentBottom);
}
private void ClearAllMarkings(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
@@ -264,6 +292,31 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
spriteComp.RemoveLayer(index);
}
}
private void AddUndergarments(HumanoidAppearanceComponent humanoid, SpriteComponent sprite, bool undergarmentTop, bool undergarmentBottom)
{
if (undergarmentTop && humanoid.UndergarmentTop != null)
{
var marking = new Marking(humanoid.UndergarmentTop, new List<Color> { new Color() });
if (_markingManager.TryGetMarking(marking, out var prototype))
{
// Markings are added to ClientOldMarkings because otherwise it causes issues when toggling the feature on/off.
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentTop, new List<Marking>{ marking });
ApplyMarking(prototype, null, true, humanoid, sprite);
}
}
if (undergarmentBottom && humanoid.UndergarmentBottom != null)
{
var marking = new Marking(humanoid.UndergarmentBottom, new List<Color> { new Color() });
if (_markingManager.TryGetMarking(marking, out var prototype))
{
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentBottom, new List<Marking>{ marking });
ApplyMarking(prototype, null, true, humanoid, sprite);
}
}
}
private void ApplyMarking(MarkingPrototype markingPrototype,
IReadOnlyList<Color>? colors,
bool visible,

View File

@@ -4,6 +4,8 @@
<BoxContainer Orientation="Vertical">
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
<BoxContainer Orientation="Vertical" Margin="8">
<Label Text="{Loc 'ui-options-accessability-header-visuals'}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
@@ -12,6 +14,9 @@
<ui:OptionSlider Name="SpeechBubbleTextOpacitySlider" Title="{Loc 'ui-options-speech-bubble-text-opacity'}" />
<ui:OptionSlider Name="SpeechBubbleSpeakerOpacitySlider" Title="{Loc 'ui-options-speech-bubble-speaker-opacity'}" />
<ui:OptionSlider Name="SpeechBubbleBackgroundOpacitySlider" Title="{Loc 'ui-options-speech-bubble-background-opacity'}" />
<Label Text="{Loc 'ui-options-accessability-header-content'}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="CensorNudityCheckBox" Text="{Loc 'ui-options-censor-nudity'}" />
</BoxContainer>
</ScrollContainer>
<ui:OptionsTabControlRow Name="Control" Access="Public" />

View File

@@ -21,6 +21,8 @@ public sealed partial class AccessibilityTab : Control
Control.AddOptionPercentSlider(CCVars.SpeechBubbleSpeakerOpacity, SpeechBubbleSpeakerOpacitySlider);
Control.AddOptionPercentSlider(CCVars.SpeechBubbleBackgroundOpacity, SpeechBubbleBackgroundOpacitySlider);
Control.AddOptionCheckBox(CCVars.AccessibilityClientCensorNudity, CensorNudityCheckBox);
Control.Initialize();
}
}

View File

@@ -60,5 +60,17 @@ public sealed partial class CCVars
public static readonly CVarDef<float> SpeechBubbleBackgroundOpacity =
CVarDef.Create("accessibility.speech_bubble_background_opacity", 0.75f, CVar.CLIENTONLY | CVar.ARCHIVE);
/// <summary>
/// If enabled, censors character nudity by forcing clothes markings on characters, selected by the client.
/// Both this and AccessibilityServerCensorNudity must be false to display nudity on the client.
/// </summary>
public static readonly CVarDef<bool> AccessibilityClientCensorNudity =
CVarDef.Create("accessibility.censor_nudity", false, CVar.CLIENTONLY | CVar.ARCHIVE);
/// <summary>
/// If enabled, censors character nudity by forcing clothes markings on characters, selected by the server.
/// Both this and AccessibilityClientCensorNudity must be false to display nudity on the client.
/// </summary>
public static readonly CVarDef<bool> AccessibilityServerCensorNudity =
CVarDef.Create("accessibility.server_censor_nudity", false, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
}

View File

@@ -88,6 +88,15 @@ public sealed partial class HumanoidAppearanceComponent : Component
/// </summary>
[DataField]
public HashSet<HumanoidVisualLayers> HideLayersOnEquip = [HumanoidVisualLayers.Hair];
/// <summary>
/// Which markings the humanoid defaults to when nudity is toggled off.
/// </summary>
[DataField]
public ProtoId<MarkingPrototype>? UndergarmentTop = new ProtoId<MarkingPrototype>("UndergarmentTopTanktop");
[DataField]
public ProtoId<MarkingPrototype>? UndergarmentBottom = new ProtoId<MarkingPrototype>("UndergarmentBottomBoxers");
}
[DataDefinition]

View File

@@ -10,6 +10,8 @@ namespace Content.Shared.Humanoid
Tail,
Hair,
FacialHair,
UndergarmentTop,
UndergarmentBottom,
Chest,
Head,
Snout,
@@ -19,7 +21,6 @@ namespace Content.Shared.Humanoid
RArm,
LArm,
RHand,
LHand,
RLeg,
LLeg,

View File

@@ -13,6 +13,8 @@ namespace Content.Shared.Humanoid.Markings
HeadSide,
Snout,
Chest,
UndergarmentTop,
UndergarmentBottom,
Arms,
Legs,
Tail,
@@ -33,6 +35,8 @@ namespace Content.Shared.Humanoid.Markings
HumanoidVisualLayers.HeadSide => MarkingCategories.HeadSide,
HumanoidVisualLayers.Snout => MarkingCategories.Snout,
HumanoidVisualLayers.Chest => MarkingCategories.Chest,
HumanoidVisualLayers.UndergarmentTop => MarkingCategories.UndergarmentTop,
HumanoidVisualLayers.UndergarmentBottom => MarkingCategories.UndergarmentBottom,
HumanoidVisualLayers.RArm => MarkingCategories.Arms,
HumanoidVisualLayers.LArm => MarkingCategories.Arms,
HumanoidVisualLayers.RHand => MarkingCategories.Arms,

View File

@@ -89,7 +89,7 @@ public static class MarkingColoring
public sealed partial class LayerColoringDefinition
{
[DataField("type")]
public LayerColoringType Type = new SkinColoring();
public LayerColoringType? Type = new SkinColoring();
/// <summary>
/// Coloring types that will be used if main coloring type will return nil
@@ -105,7 +105,9 @@ public sealed partial class LayerColoringDefinition
public Color GetColor(Color? skin, Color? eyes, MarkingSet markingSet)
{
var color = Type.GetColor(skin, eyes, markingSet);
Color? color = null;
if (Type != null)
color = Type.GetColor(skin, eyes, markingSet);
if (color == null)
{
foreach (var type in FallbackTypes)

View File

@@ -279,15 +279,21 @@ cmd-options-help = Usage: options [tab]
## Accessibility menu
ui-options-accessability-header-visuals = Visuals
ui-options-accessability-header-content = Content
ui-options-enable-color-name = Add colors to character names
ui-options-colorblind-friendly = Colorblind friendly mode
ui-options-reduced-motion = Reduce motion of visual effects
ui-options-screen-shake-intensity = Screen shake intensity
ui-options-chat-window-opacity = Chat window opacity
ui-options-speech-bubble-text-opacity = Speech bubble text opacity
ui-options-speech-bubble-speaker-opacity = Speech bubble speaker opacity
ui-options-speech-bubble-background-opacity = Speech bubble background opacity
ui-options-censor-nudity = Censor character nudity
## Admin menu
ui-options-enable-classic-overlay = Revert antag overlay to classic mode

View File

@@ -0,0 +1,21 @@
marking-UndergarmentTopTanktop = Tanktop
marking-UndergarmentTopBinder = Binder
marking-UndergarmentTopBra = Classic Bra
marking-UndergarmentTopSportsbra = Sports Bra
marking-UndergarmentBottomBoxers = Boxers
marking-UndergarmentBottomBriefs = Briefs
marking-UndergarmentBottomSatin = Satin
marking-UndergarmentTopTanktopVox = Tanktop
marking-UndergarmentTopBinderVox = Binder
marking-UndergarmentTopBraVox = Classic Bra
marking-UndergarmentTopSportsbraVox = Sports Bra
marking-UndergarmentBottomBoxersVox = Boxers
marking-UndergarmentBottomBriefsVox = Briefs
marking-UndergarmentBottomSatinVox = Satin
marking-UndergarmentBottomBoxersReptilian = Boxers
marking-UndergarmentBottomBriefsReptilian = Briefs
marking-UndergarmentBottomSatinReptilian = Satin

View File

@@ -21,6 +21,8 @@ markings-category-Head = Head
markings-category-HeadTop = Head (Top)
markings-category-HeadSide = Head (Side)
markings-category-Snout = Snout
markings-category-UndergarmentTop = Undergarment (Top)
markings-category-UndergarmentBottom = Undergarment (Bottom)
markings-category-Chest = Chest
markings-category-Arms = Arms
markings-category-Legs = Legs

View File

@@ -0,0 +1,223 @@
# These options are kept very sparse to not put emphasis on nudity, and to provide a base for players to feel comfortable with.
# It's unlikely more will be added to upstream for cosmetic reasons.
- type: marking
id: UndergarmentBottomBoxers
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: boxers
- type: marking
id: UndergarmentBottomBriefs
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: briefs
- type: marking
id: UndergarmentBottomSatin
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: satin
- type: marking
id: UndergarmentTopBra
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, Reptilian, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: classic
- type: marking
id: UndergarmentTopSportsbra
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, Reptilian, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: sports
- type: marking
id: UndergarmentTopBinder
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, Reptilian, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: binder
- type: marking
id: UndergarmentTopTanktop
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Arachnid, Diona, Human, Dwarf, Moth, Reptilian, SlimePerson]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: tanktop
- type: marking
id: UndergarmentBottomBoxersVox # Voxers.
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: boxers_vox
- type: marking
id: UndergarmentBottomBriefsVox
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: briefs_vox
- type: marking
id: UndergarmentBottomSatinVox
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: satin_vox
- type: marking
id: UndergarmentTopBraVox
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: classic_vox
- type: marking
id: UndergarmentTopSportsbraVox
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: sports_vox
- type: marking
id: UndergarmentTopBinderVox
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: binder_vox
- type: marking
id: UndergarmentTopTanktopVox
bodyPart: UndergarmentTop
markingCategory: UndergarmentTop
speciesRestriction: [Vox]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: tanktop_vox
- type: marking
id: UndergarmentBottomBoxersReptilian
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Reptilian]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: boxers_reptilian
- type: marking
id: UndergarmentBottomBriefsReptilian
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Reptilian]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: briefs_reptilian
- type: marking
id: UndergarmentBottomSatinReptilian
bodyPart: UndergarmentBottom
markingCategory: UndergarmentBottom
speciesRestriction: [Reptilian]
coloring:
default:
type: null
fallbackColor: '#FFFFFF'
sprites:
- sprite: Mobs/Customization/undergarments.rsi
state: satin_reptilian

View File

@@ -81,6 +81,8 @@
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentBottom" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentTop" ]
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]

View File

@@ -19,6 +19,8 @@
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentBottom" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentTop" ]
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]
@@ -305,6 +307,8 @@
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentBottom" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentTop" ]
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]

View File

@@ -83,6 +83,8 @@
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentBottom" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentTop" ]
- map: [ "jumpsuit" ]
- map: [ "enum.HumanoidVisualLayers.LHand" ]
- map: [ "enum.HumanoidVisualLayers.RHand" ]

View File

@@ -11,6 +11,7 @@
- Snout
- HeadTop
- HeadSide
undergarmentBottom: UndergarmentBottomBoxersReptilian
- type: Hunger
- type: Puller
needsHands: false
@@ -90,6 +91,7 @@
- Snout
- HeadTop
- HeadSide
undergarmentBottom: UndergarmentBottomBoxersReptilian
- type: Inventory
speciesId: reptilian
femaleDisplacements:

View File

@@ -11,8 +11,10 @@
- type: Body
prototype: Vox
requiredLegs: 2
- type: HumanoidAppearance
- type: HumanoidAppearance
species: Vox
undergarmentTop: UndergarmentTopTanktopVox
undergarmentBottom: UndergarmentBottomBoxersVox
#- type: VoxAccent # Not yet coded
- type: Speech
speechVerb: Vox
@@ -71,6 +73,8 @@
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentBottom" ]
- map: [ "enum.HumanoidVisualLayers.UndergarmentTop" ]
- map: [ "jumpsuit" ]
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
- map: [ "enum.HumanoidVisualLayers.RFoot" ]
@@ -150,6 +154,8 @@
components:
- type: HumanoidAppearance
species: Vox
undergarmentTop: UndergarmentTopTanktopVox
undergarmentBottom: UndergarmentBottomBoxersVox
- type: Body
prototype: Vox
- type: Inventory

View File

@@ -19,6 +19,8 @@
sprites:
Head: MobArachnidHead
Snout: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobArachnidTorso
HeadTop: MobHumanoidAnyMarking
HeadSide: MobHumanoidAnyMarking

View File

@@ -19,6 +19,8 @@
Head: MobDionaHead
HeadTop: MobHumanoidAnyMarking
HeadSide: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobDionaTorso
Eyes: MobDionaEyes
LArm: MobDionaLArm
@@ -43,6 +45,12 @@
HeadSide:
points: 1
required: false
UndergarmentTop:
points: 1
required: false
UndergarmentBottom:
points: 1
required: false
Chest:
points: 1
required: false

View File

@@ -22,6 +22,8 @@
Hair: MobHumanoidAnyMarking
FacialHair: MobHumanoidAnyMarking
Snout: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobHumanTorso
Eyes: MobHumanoidEyes
HeadTop: MobHumanoidAnyMarking
@@ -55,6 +57,12 @@
HeadTop:
points: 1
required: false
UndergarmentTop:
points: 1
required: false
UndergarmentBottom:
points: 1
required: false
Chest:
points: 1
required: false

View File

@@ -17,6 +17,8 @@
sprites:
Head: MobMothHead
Snout: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobMothTorso
HeadTop: MobHumanoidAnyMarking
HeadSide: MobHumanoidAnyMarking
@@ -64,6 +66,12 @@
Head:
points: 1
required: false
UndergarmentTop:
points: 1
required: false
UndergarmentBottom:
points: 1
required: false
Chest:
points: 1
required: false

View File

@@ -17,6 +17,8 @@
sprites:
Head: MobReptilianHead
Snout: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobReptilianTorso
HeadTop: MobHumanoidAnyMarking
HeadSide: MobHumanoidAnyMarking
@@ -55,6 +57,12 @@
HeadSide:
points: 1
required: false
UndergarmentTop:
points: 1
required: false
UndergarmentBottom:
points: 1
required: false
Chest:
points: 3
required: false

View File

@@ -15,6 +15,8 @@
Head: MobSlimeHead
Hair: MobSlimeMarkingFollowSkin
FacialHair: MobSlimeMarkingFollowSkin
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobSlimeTorso
Eyes: MobHumanoidEyes
LArm: MobSlimeLArm

View File

@@ -21,6 +21,8 @@
Snout: MobHumanoidAnyMarking
Hair: MobHumanoidAnyMarking
FacialHair: MobHumanoidAnyMarking
UndergarmentTop: MobHumanoidAnyMarking
UndergarmentBottom: MobHumanoidAnyMarking
Chest: MobVoxTorso
Eyes: MobVoxEyes
LArm: MobVoxLArm
@@ -58,6 +60,12 @@
points: 4
required: true
defaultMarkings: [ VoxLLegScales, VoxRLegScales, VoxRFootScales, VoxLFootScales ]
UndergarmentTop:
points: 1
required: false
UndergarmentBottom:
points: 1
required: false
Chest:
points: 1
required: false

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,79 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "sprites taken from https://github.com/cmss13-devs/cmss13/blob/884ab172389b6fc54ef063f5fbea5e8b0a0a2235/icons/mob/humans/underwear.dmi and https://github.com/cmss13-devs/cmss13/blob/884ab172389b6fc54ef063f5fbea5e8b0a0a2235/icons/mob/humans/undershirt.dmi, edited by SlamBamActionman",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "briefs",
"directions": 4
},
{
"name": "satin",
"directions": 4
},
{
"name": "boxers",
"directions": 4
},
{
"name": "classic",
"directions": 4
},
{
"name": "sports",
"directions": 4
},
{
"name": "binder",
"directions": 4
},
{
"name": "tanktop",
"directions": 4
},
{
"name": "briefs_vox",
"directions": 4
},
{
"name": "satin_vox",
"directions": 4
},
{
"name": "boxers_vox",
"directions": 4
},
{
"name": "classic_vox",
"directions": 4
},
{
"name": "sports_vox",
"directions": 4
},
{
"name": "binder_vox",
"directions": 4
},
{
"name": "tanktop_vox",
"directions": 4
},
{
"name": "briefs_reptilian",
"directions": 4
},
{
"name": "satin_reptilian",
"directions": 4
},
{
"name": "boxers_reptilian",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB