* Fix broken layer hiding on clothes with multiple equipment slots * Refactor ToggleVisualLayers, HideLayerClothingComponent, and ClothingComponent to allow more precise layer hide behavior and more CPU efficient layer toggling. * Adjust HumanoidAppearaceSystem to track which slots are hiding a given layer (e.g. gas mask and welding mask) Add documentation Change gas masks to use the new HideLayerClothingComponent structure as an example of its usage * Fix the delayed snout bug * Misc cleanup * Make `bool permanent` implicit from SlotFlags any non-permanent visibility toggle with `SlotFlags.None` isn't supported with how its set up. And similarly, the slot flags argument does nothing if permanent = true. So IMO it makes more sense to infer it from a nullable arg. * Split into separate system Too much pasta * Remove (hopefully unnecessary) refresh * Fisk mask networking AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA * Keep old behaviour, use clearer names? I'm just guessing at what this was meant to do * english * Separate slot name & flag * dirty = true * fix comment * Improved SetLayerVisibility with dirtying logic suggested by @ElectroJr * Only set mask toggled if DisableOnFold is true * FoldableClothingSystem fixes * fix bandana state * Better comment --------- Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
90 lines
3.8 KiB
C#
90 lines
3.8 KiB
C#
using Content.Shared.Clothing.Components;
|
|
using Content.Shared.Foldable;
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.Item;
|
|
|
|
namespace Content.Shared.Clothing.EntitySystems;
|
|
|
|
public sealed class FoldableClothingSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly ClothingSystem _clothingSystem = default!;
|
|
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
|
[Dependency] private readonly SharedItemSystem _itemSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<FoldableClothingComponent, FoldAttemptEvent>(OnFoldAttempt);
|
|
SubscribeLocalEvent<FoldableClothingComponent, FoldedEvent>(OnFolded,
|
|
after: [typeof(MaskSystem)]); // Mask system also modifies clothing / equipment RSI state prefixes.
|
|
}
|
|
|
|
private void OnFoldAttempt(Entity<FoldableClothingComponent> ent, ref FoldAttemptEvent args)
|
|
{
|
|
if (args.Cancelled)
|
|
return;
|
|
|
|
if (!_inventorySystem.TryGetContainingSlot(ent.Owner, out var slot))
|
|
return;
|
|
|
|
// Cannot fold clothing equipped to a slot if the slot becomes disallowed
|
|
var newSlots = args.Comp.IsFolded ? ent.Comp.UnfoldedSlots : ent.Comp.FoldedSlots;
|
|
if (newSlots != null && (newSlots.Value & slot.SlotFlags) != slot.SlotFlags)
|
|
{
|
|
args.Cancelled = true;
|
|
return;
|
|
}
|
|
|
|
// Setting hidden layers while equipped is not currently supported.
|
|
if (ent.Comp.FoldedHideLayers != null || ent.Comp.UnfoldedHideLayers != null)
|
|
args.Cancelled = true;
|
|
}
|
|
|
|
private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
|
|
{
|
|
if (!TryComp<ClothingComponent>(ent.Owner, out var clothingComp) ||
|
|
!TryComp<ItemComponent>(ent.Owner, out var itemComp))
|
|
return;
|
|
|
|
if (args.IsFolded)
|
|
{
|
|
if (ent.Comp.FoldedSlots.HasValue)
|
|
_clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp);
|
|
|
|
if (ent.Comp.FoldedEquippedPrefix != null)
|
|
_clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
|
|
|
|
if (ent.Comp.FoldedHeldPrefix != null)
|
|
_itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
|
|
|
|
// This is janky and likely to lead to bugs.
|
|
// I.e., overriding this and resetting it again later will lead to bugs if someone tries to modify clothing
|
|
// in yaml, but doesn't realise theres actually two other fields on an unrelated component that they also need
|
|
// to modify.
|
|
// This should instead work via an event or something that gets raised to optionally modify the currently hidden layers.
|
|
// Or at the very least it should stash the old layers and restore them when unfolded.
|
|
// TODO CLOTHING fix this.
|
|
if (ent.Comp.FoldedHideLayers != null && TryComp<HideLayerClothingComponent>(ent.Owner, out var hideLayerComp))
|
|
hideLayerComp.Slots = ent.Comp.FoldedHideLayers;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (ent.Comp.UnfoldedSlots.HasValue)
|
|
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
|
|
|
|
if (ent.Comp.FoldedEquippedPrefix != null)
|
|
_clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
|
|
|
|
if (ent.Comp.FoldedHeldPrefix != null)
|
|
_itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
|
|
|
|
// TODO CLOTHING fix this.
|
|
if (ent.Comp.UnfoldedHideLayers != null && TryComp<HideLayerClothingComponent>(ent.Owner, out var hideLayerComp))
|
|
hideLayerComp.Slots = ent.Comp.UnfoldedHideLayers;
|
|
|
|
}
|
|
}
|
|
}
|