FoldableClothingSystem.cs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Content.Shared.Clothing.Components;
  2. using Content.Shared.Foldable;
  3. using Content.Shared.Inventory;
  4. using Content.Shared.Item;
  5. namespace Content.Shared.Clothing.EntitySystems;
  6. public sealed class FoldableClothingSystem : EntitySystem
  7. {
  8. [Dependency] private readonly ClothingSystem _clothingSystem = default!;
  9. [Dependency] private readonly InventorySystem _inventorySystem = default!;
  10. [Dependency] private readonly SharedItemSystem _itemSystem = default!;
  11. public override void Initialize()
  12. {
  13. base.Initialize();
  14. SubscribeLocalEvent<FoldableClothingComponent, FoldAttemptEvent>(OnFoldAttempt);
  15. SubscribeLocalEvent<FoldableClothingComponent, FoldedEvent>(OnFolded,
  16. after: [typeof(MaskSystem)]); // Mask system also modifies clothing / equipment RSI state prefixes.
  17. }
  18. private void OnFoldAttempt(Entity<FoldableClothingComponent> ent, ref FoldAttemptEvent args)
  19. {
  20. if (args.Cancelled)
  21. return;
  22. if (!_inventorySystem.TryGetContainingSlot(ent.Owner, out var slot))
  23. return;
  24. // Cannot fold clothing equipped to a slot if the slot becomes disallowed
  25. var newSlots = args.Comp.IsFolded ? ent.Comp.UnfoldedSlots : ent.Comp.FoldedSlots;
  26. if (newSlots != null && (newSlots.Value & slot.SlotFlags) != slot.SlotFlags)
  27. {
  28. args.Cancelled = true;
  29. return;
  30. }
  31. // Setting hidden layers while equipped is not currently supported.
  32. if (ent.Comp.FoldedHideLayers != null || ent.Comp.UnfoldedHideLayers != null)
  33. args.Cancelled = true;
  34. }
  35. private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
  36. {
  37. if (!TryComp<ClothingComponent>(ent.Owner, out var clothingComp) ||
  38. !TryComp<ItemComponent>(ent.Owner, out var itemComp))
  39. return;
  40. if (args.IsFolded)
  41. {
  42. if (ent.Comp.FoldedSlots.HasValue)
  43. _clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp);
  44. if (ent.Comp.FoldedEquippedPrefix != null)
  45. _clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
  46. if (ent.Comp.FoldedHeldPrefix != null)
  47. _itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
  48. // This is janky and likely to lead to bugs.
  49. // I.e., overriding this and resetting it again later will lead to bugs if someone tries to modify clothing
  50. // in yaml, but doesn't realise theres actually two other fields on an unrelated component that they also need
  51. // to modify.
  52. // This should instead work via an event or something that gets raised to optionally modify the currently hidden layers.
  53. // Or at the very least it should stash the old layers and restore them when unfolded.
  54. // TODO CLOTHING fix this.
  55. if (ent.Comp.FoldedHideLayers != null && TryComp<HideLayerClothingComponent>(ent.Owner, out var hideLayerComp))
  56. hideLayerComp.Slots = ent.Comp.FoldedHideLayers;
  57. }
  58. else
  59. {
  60. if (ent.Comp.UnfoldedSlots.HasValue)
  61. _clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
  62. if (ent.Comp.FoldedEquippedPrefix != null)
  63. _clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
  64. if (ent.Comp.FoldedHeldPrefix != null)
  65. _itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
  66. // TODO CLOTHING fix this.
  67. if (ent.Comp.UnfoldedHideLayers != null && TryComp<HideLayerClothingComponent>(ent.Owner, out var hideLayerComp))
  68. hideLayerComp.Slots = ent.Comp.UnfoldedHideLayers;
  69. }
  70. }
  71. }