Files
space-station-14/Content.Shared/Clothing/EntitySystems/HideLayerClothingSystem.cs
pathetic meowmeow 8cf744ec55 Visual nubody (humanoid appearance refactor) (#42476)
* initial visual nubody

* oops overlay

* im so pheeming rn

* conversion...

* tests

* comeback of the underwear

* oops eyes

* blabbl

* zeds

* yaml linted

* search and visible count constraints

* reordering

* preserve previously selected markings colors

* fix test

* some ui niceties

* ordering

* make DB changes backwards-compatible/downgrade-friendly

* fix things again

* fix migration

* vulpkanin markings limit increase

* wrapping

* code cleanup and more code cleanup and more code cleanup and more code cleanup and

* fix slop ports

* better sampling API

* make filter work + use the method i made for its intended purpose

* fix test fails real quick

* magic mirror cleanup, remove TODO

* don't 0-init the organ profile data

* remove deltastates

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
2026-01-20 07:07:53 +00:00

103 lines
3.9 KiB
C#

using Content.Shared.Clothing.Components;
using Content.Shared.Humanoid;
using Content.Shared.Inventory;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Shared.Clothing.EntitySystems;
public sealed class HideLayerClothingSystem : EntitySystem
{
[Dependency] private readonly SharedHideableHumanoidLayersSystem _hideableHumanoidLayers = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize()
{
SubscribeLocalEvent<HideLayerClothingComponent, ClothingGotUnequippedEvent>(OnHideGotUnequipped);
SubscribeLocalEvent<HideLayerClothingComponent, ClothingGotEquippedEvent>(OnHideGotEquipped);
SubscribeLocalEvent<HideLayerClothingComponent, ItemMaskToggledEvent>(OnHideToggled);
}
private void OnHideToggled(Entity<HideLayerClothingComponent> ent, ref ItemMaskToggledEvent args)
{
if (args.Wearer != null)
SetLayerVisibility(ent!, args.Wearer.Value, hideLayers: true);
}
private void OnHideGotEquipped(Entity<HideLayerClothingComponent> ent, ref ClothingGotEquippedEvent args)
{
SetLayerVisibility(ent!, args.Wearer, hideLayers: true);
}
private void OnHideGotUnequipped(Entity<HideLayerClothingComponent> ent, ref ClothingGotUnequippedEvent args)
{
SetLayerVisibility(ent!, args.Wearer, hideLayers: false);
}
private void SetLayerVisibility(
Entity<HideLayerClothingComponent?, ClothingComponent?> clothing,
Entity<HideableHumanoidLayersComponent?> user,
bool hideLayers)
{
if (_timing.ApplyingState)
return;
if (!Resolve(clothing.Owner, ref clothing.Comp1, ref clothing.Comp2))
return;
// logMissing: false, as this clothing might be getting equipped by a non-human.
if (!Resolve(user.Owner, ref user.Comp, false))
return;
hideLayers &= IsEnabled(clothing!);
var hideable = user.Comp.HideLayersOnEquip;
var inSlot = clothing.Comp2.InSlotFlag ?? SlotFlags.NONE;
// This method should only be getting called while the clothing is equipped (though possibly currently in
// the process of getting unequipped).
DebugTools.AssertNotNull(clothing.Comp2.InSlot);
DebugTools.AssertNotNull(clothing.Comp2.InSlotFlag);
DebugTools.AssertNotEqual(inSlot, SlotFlags.NONE);
// iterate the HideLayerClothingComponent's layers map and check that
// the clothing is (or was)equipped in a matching slot.
foreach (var (layer, validSlots) in clothing.Comp1.Layers)
{
if (!hideable.Contains(layer))
continue;
// Only update this layer if we are currently equipped to the relevant slot.
if (validSlots.HasFlag(inSlot))
_hideableHumanoidLayers.SetLayerVisibility(user, layer, !hideLayers, inSlot);
}
// Fallback for obsolete field: assume we want to hide **all** layers, as long as we are equipped to any
// relevant clothing slot
#pragma warning disable CS0618 // Type or member is obsolete
if (clothing.Comp1.Slots is { } slots && clothing.Comp2.Slots.HasFlag(inSlot))
#pragma warning restore CS0618 // Type or member is obsolete
{
foreach (var layer in slots)
{
if (hideable.Contains(layer))
_hideableHumanoidLayers.SetLayerVisibility(user, layer, !hideLayers, inSlot);
}
}
}
private bool IsEnabled(Entity<HideLayerClothingComponent, ClothingComponent> clothing)
{
// TODO Generalize this
// I.e., make this and mask component use some generic toggleable.
if (!clothing.Comp1.HideOnToggle)
return true;
if (!TryComp(clothing, out MaskComponent? mask))
return true;
return !mask.IsToggled;
}
}