]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix debug asserts when unequipping items (#38274)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Sat, 21 Jun 2025 13:40:56 +0000 (15:40 +0200)
committerGitHub <noreply@github.com>
Sat, 21 Jun 2025 13:40:56 +0000 (16:40 +0300)
Content.Shared/Clothing/Components/ClothingComponent.cs
Content.Shared/Clothing/EntitySystems/ClothingSystem.cs
Content.Shared/Clothing/EntitySystems/MaskSystem.cs

index 260af210e0dd8c5a5b65827934da9fb716c054c4..ff1d422189f8c6f27f96cc878c9b981f11957a74 100644 (file)
@@ -11,12 +11,11 @@ namespace Content.Shared.Clothing.Components;
 /// <summary>
 ///     This handles entities which can be equipped.
 /// </summary>
-[NetworkedComponent]
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
 [Access(typeof(ClothingSystem), typeof(InventorySystem))]
 public sealed partial class ClothingComponent : Component
 {
-    [DataField("clothingVisuals")]
+    [DataField]
     public Dictionary<string, List<PrototypeLayerData>> ClothingVisuals = new();
 
     /// <summary>
@@ -25,8 +24,7 @@ public sealed partial class ClothingComponent : Component
     [DataField]
     public string? MappedLayer;
 
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("quickEquip")]
+    [DataField]
     public bool QuickEquip = true;
 
     /// <summary>
@@ -36,22 +34,18 @@ public sealed partial class ClothingComponent : Component
     /// <remarks>
     /// Note that this may be a combination of different slot flags, not a singular bit.
     /// </remarks>
-    [ViewVariables(VVAccess.ReadWrite)]
     [DataField(required: true)]
     [Access(typeof(ClothingSystem), typeof(InventorySystem), Other = AccessPermissions.ReadExecute)]
     public SlotFlags Slots = SlotFlags.NONE;
 
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("equipSound")]
+    [DataField]
     public SoundSpecifier? EquipSound;
 
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("unequipSound")]
+    [DataField]
     public SoundSpecifier? UnequipSound;
 
     [Access(typeof(ClothingSystem))]
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("equippedPrefix")]
+    [DataField, AutoNetworkedField]
     public string? EquippedPrefix;
 
     /// <summary>
@@ -59,11 +53,9 @@ public sealed partial class ClothingComponent : Component
     /// useful when prototyping INNERCLOTHING items into OUTERCLOTHING items without duplicating/modifying RSIs etc.
     /// </summary>
     [Access(typeof(ClothingSystem))]
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("equippedState")]
+    [DataField, AutoNetworkedField]
     public string? EquippedState;
 
-    [ViewVariables(VVAccess.ReadWrite)]
     [DataField("sprite")]
     public string? RsiPath;
 
@@ -72,7 +64,7 @@ public sealed partial class ClothingComponent : Component
     /// Note that this being non-null does not mean the clothing is considered "worn" or "equipped" unless the slot
     /// satisfies the <see cref="Slots"/> flags.
     /// </summary>
-    [DataField]
+    [DataField, AutoNetworkedField]
     public string? InSlot;
     // TODO CLOTHING
     // Maybe keep this null unless its in a valid slot?
@@ -82,16 +74,16 @@ public sealed partial class ClothingComponent : Component
     /// <summary>
     /// Slot flags of the slot the clothing is currently in. See also <see cref="InSlot"/>.
     /// </summary>
-    [DataField]
+    [DataField, AutoNetworkedField]
     public SlotFlags? InSlotFlag;
     // TODO CLOTHING
     // Maybe keep this null unless its in a valid slot?
     // And when doing this, combine InSlot and InSlotFlag, as it'd be a breaking change for downstreams anyway
 
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
     public TimeSpan EquipDelay = TimeSpan.Zero;
 
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
     public TimeSpan UnequipDelay = TimeSpan.Zero;
 
     /// <summary>
@@ -102,17 +94,6 @@ public sealed partial class ClothingComponent : Component
     public TimeSpan StripDelay = TimeSpan.Zero;
 }
 
-[Serializable, NetSerializable]
-public sealed class ClothingComponentState : ComponentState
-{
-    public string? EquippedPrefix;
-
-    public ClothingComponentState(string? equippedPrefix)
-    {
-        EquippedPrefix = equippedPrefix;
-    }
-}
-
 public enum ClothingMask : byte
 {
     NoMask = 0,
index 10417045ff2dfa0ea10da745c678ccc6c6b79753..6ebaa94e2e1bbc591fd5d8ac2fec82ceeb92b3da 100644 (file)
@@ -21,8 +21,7 @@ public abstract class ClothingSystem : EntitySystem
         base.Initialize();
 
         SubscribeLocalEvent<ClothingComponent, UseInHandEvent>(OnUseInHand);
-        SubscribeLocalEvent<ClothingComponent, ComponentGetState>(OnGetState);
-        SubscribeLocalEvent<ClothingComponent, ComponentHandleState>(OnHandleState);
+        SubscribeLocalEvent<ClothingComponent, AfterAutoHandleStateEvent>(AfterAutoHandleState);
         SubscribeLocalEvent<ClothingComponent, GotEquippedEvent>(OnGotEquipped);
         SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
 
@@ -84,6 +83,7 @@ public abstract class ClothingSystem : EntitySystem
     {
         component.InSlot = args.Slot;
         component.InSlotFlag = args.SlotFlags;
+        Dirty(uid, component);
 
         if ((component.Slots & args.SlotFlags) == SlotFlags.NONE)
             return;
@@ -108,19 +108,12 @@ public abstract class ClothingSystem : EntitySystem
 
         component.InSlot = null;
         component.InSlotFlag = null;
+        Dirty(uid, component);
     }
 
-    private void OnGetState(EntityUid uid, ClothingComponent component, ref ComponentGetState args)
+    private void AfterAutoHandleState(Entity<ClothingComponent> ent, ref AfterAutoHandleStateEvent args)
     {
-        args.State = new ClothingComponentState(component.EquippedPrefix);
-    }
-
-    private void OnHandleState(EntityUid uid, ClothingComponent component, ref ComponentHandleState args)
-    {
-        if (args.Current is not ClothingComponentState state)
-            return;
-
-        SetEquippedPrefix(uid, state.EquippedPrefix, component);
+        _itemSys.VisualsChanged(ent.Owner);
     }
 
     private void OnEquipDoAfter(Entity<ClothingComponent> ent, ref ClothingEquipDoAfterEvent args)
index 4f89b111bda14243901ec2a742fc29c748505f82..30e00faf0ac1a0acbd576c5b1313526ccf96365b 100644 (file)
@@ -75,13 +75,13 @@ public sealed class MaskSystem : EntitySystem
     private void ToggleMaskComponents(EntityUid uid, MaskComponent mask, EntityUid wearer, string? equippedPrefix = null, bool isEquip = false)
     {
         Dirty(uid, mask);
-        if (mask.ToggleActionEntity is {} action)
+        if (mask.ToggleActionEntity is { } action)
             _actionSystem.SetToggled(action, mask.IsToggled);
 
-        var maskEv = new ItemMaskToggledEvent((wearer, mask), wearer);
+        var maskEv = new ItemMaskToggledEvent((uid, mask), wearer);
         RaiseLocalEvent(uid, ref maskEv);
 
-        var wearerEv = new WearerMaskToggledEvent((wearer, mask));
+        var wearerEv = new WearerMaskToggledEvent((uid, mask));
         RaiseLocalEvent(wearer, ref wearerEv);
     }