]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Move MaskComponent to shared and add toggle events (#22395)
authorDrSmugleaf <DrSmugleaf@users.noreply.github.com>
Wed, 13 Dec 2023 02:02:35 +0000 (19:02 -0700)
committerGitHub <noreply@github.com>
Wed, 13 Dec 2023 02:02:35 +0000 (19:02 -0700)
* Move MaskComponent to shared and add toggle events

* Datafield and network IsToggled

* Add missing dirty

12 files changed:
Content.Server/Body/Systems/LungSystem.cs
Content.Server/Clothing/Components/MaskComponent.cs [deleted file]
Content.Server/Clothing/MaskSystem.cs [deleted file]
Content.Server/IdentityManagement/IdentitySystem.cs
Content.Server/Nutrition/Components/IngestionBlockerComponent.cs
Content.Server/Nutrition/EntitySystems/IngestionBlockerSystem.cs [new file with mode: 0644]
Content.Server/VoiceMask/VoiceMaskSystem.cs
Content.Shared/Clothing/ClothingEvents.cs
Content.Shared/Clothing/Components/MaskComponent.cs [new file with mode: 0644]
Content.Shared/Clothing/EntitySystems/ClothingSystem.cs
Content.Shared/Clothing/EntitySystems/MaskSystem.cs [new file with mode: 0644]
Content.Shared/IdentityManagement/SharedIdentitySystem.cs

index 301cf1431167d2e4c59e96403765ee53467f403e..954b55322778a35164be4dbe33ae6ef60a186787 100644 (file)
@@ -3,12 +3,14 @@ using Content.Server.Atmos.EntitySystems;
 using Content.Server.Body.Components;
 using Content.Shared.Atmos;
 using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Clothing;
 using Content.Shared.Inventory.Events;
 
 namespace Content.Server.Body.Systems;
 
 public sealed class LungSystem : EntitySystem
 {
+    [Dependency] private readonly AtmosphereSystem _atmos = default!;
     [Dependency] private readonly InternalsSystem _internals = default!;
     [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
     [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
@@ -21,6 +23,7 @@ public sealed class LungSystem : EntitySystem
         SubscribeLocalEvent<LungComponent, ComponentInit>(OnComponentInit);
         SubscribeLocalEvent<BreathToolComponent, GotEquippedEvent>(OnGotEquipped);
         SubscribeLocalEvent<BreathToolComponent, GotUnequippedEvent>(OnGotUnequipped);
+        SubscribeLocalEvent<BreathToolComponent, ItemMaskToggledEvent>(OnMaskToggled);
     }
 
     private void OnGotUnequipped(EntityUid uid, BreathToolComponent component, GotUnequippedEvent args)
@@ -48,6 +51,28 @@ public sealed class LungSystem : EntitySystem
         component.LungSolution.CanReact = false; // No dexalin lungs
     }
 
+    private void OnMaskToggled(Entity<BreathToolComponent> ent, ref ItemMaskToggledEvent args)
+    {
+        // toggle breath tool connection (skip during equip since that is handled in LungSystem)
+        if (args.IsEquip)
+        {
+            if (args.IsToggled)
+            {
+                _atmos.DisconnectInternals(ent.Comp);
+            }
+            else
+            {
+                ent.Comp.IsFunctional = true;
+
+                if (TryComp(args.Wearer, out InternalsComponent? internals))
+                {
+                    ent.Comp.ConnectedInternalsEntity = args.Wearer;
+                    _internals.ConnectBreathTool((args.Wearer, internals), ent);
+                }
+            }
+        }
+    }
+
     public void GasToReagent(EntityUid uid, LungComponent lung)
     {
         foreach (var gas in Enum.GetValues<Gas>())
diff --git a/Content.Server/Clothing/Components/MaskComponent.cs b/Content.Server/Clothing/Components/MaskComponent.cs
deleted file mode 100644 (file)
index 704ea11..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Server.Clothing.Components
-{
-    [Access(typeof(MaskSystem))]
-    [RegisterComponent]
-    public sealed partial class MaskComponent : Component
-    {
-        [DataField("toggleAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-        public string ToggleAction = "ActionToggleMask";
-
-        /// <summary>
-        /// This mask can be toggled (pulled up/down)
-        /// </summary>
-        [DataField("toggleActionEntity")]
-        public EntityUid? ToggleActionEntity;
-
-        public bool IsToggled = false;
-    }
-}
diff --git a/Content.Server/Clothing/MaskSystem.cs b/Content.Server/Clothing/MaskSystem.cs
deleted file mode 100644 (file)
index 7769791..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-using Content.Server.Actions;
-using Content.Server.Atmos.Components;
-using Content.Server.Atmos.EntitySystems;
-using Content.Server.Body.Components;
-using Content.Server.Body.Systems;
-using Content.Server.Clothing.Components;
-using Content.Server.IdentityManagement;
-using Content.Server.Nutrition.EntitySystems;
-using Content.Server.Popups;
-using Content.Server.VoiceMask;
-using Content.Shared.Actions;
-using Content.Shared.Clothing;
-using Content.Shared.Clothing.Components;
-using Content.Shared.Clothing.EntitySystems;
-using Content.Shared.IdentityManagement.Components;
-using Content.Shared.Inventory;
-using Content.Shared.Inventory.Events;
-
-namespace Content.Server.Clothing
-{
-    public sealed class MaskSystem : EntitySystem
-    {
-        [Dependency] private readonly ActionsSystem _actionSystem = default!;
-        [Dependency] private readonly AtmosphereSystem _atmos = default!;
-        [Dependency] private readonly InternalsSystem _internals = default!;
-        [Dependency] private readonly InventorySystem _inventorySystem = default!;
-        [Dependency] private readonly PopupSystem _popupSystem = default!;
-        [Dependency] private readonly IdentitySystem _identity = default!;
-        [Dependency] private readonly ClothingSystem _clothing = default!;
-
-        public override void Initialize()
-        {
-            base.Initialize();
-
-            SubscribeLocalEvent<MaskComponent, ToggleMaskEvent>(OnToggleMask);
-            SubscribeLocalEvent<MaskComponent, GetItemActionsEvent>(OnGetActions);
-            SubscribeLocalEvent<MaskComponent, GotUnequippedEvent>(OnGotUnequipped);
-        }
-
-        private void OnGetActions(EntityUid uid, MaskComponent component, GetItemActionsEvent args)
-        {
-            if (!args.InHands)
-                args.AddAction(ref component.ToggleActionEntity, component.ToggleAction);
-        }
-
-        private void OnToggleMask(Entity<MaskComponent> ent, ref ToggleMaskEvent args)
-        {
-            var (uid, mask) = ent;
-            if (mask.ToggleActionEntity == null)
-                return;
-
-            if (!_inventorySystem.TryGetSlotEntity(args.Performer, "mask", out var existing) || !uid.Equals(existing))
-                return;
-
-            mask.IsToggled ^= true;
-            _actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled);
-
-            // Pulling mask down can change identity, so we want to update that
-            _identity.QueueIdentityUpdate(args.Performer);
-
-            if (mask.IsToggled)
-                _popupSystem.PopupEntity(Loc.GetString("action-mask-pull-down-popup-message", ("mask", uid)), args.Performer, args.Performer);
-            else
-                _popupSystem.PopupEntity(Loc.GetString("action-mask-pull-up-popup-message", ("mask", uid)), args.Performer, args.Performer);
-
-            ToggleMaskComponents(uid, mask, args.Performer);
-        }
-
-        // set to untoggled when unequipped, so it isn't left in a 'pulled down' state
-        private void OnGotUnequipped(EntityUid uid, MaskComponent mask, GotUnequippedEvent args)
-        {
-            if (mask.ToggleActionEntity == null)
-                return;
-
-            mask.IsToggled = false;
-            _actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled);
-
-            ToggleMaskComponents(uid, mask, args.Equipee, true);
-        }
-
-        private void ToggleMaskComponents(EntityUid uid, MaskComponent mask, EntityUid wearer, bool isEquip = false)
-        {
-            // toggle visuals
-            if (TryComp<ClothingComponent>(uid, out var clothing))
-            {
-                //TODO: sprites for 'pulled down' state. defaults to invisible due to no sprite with this prefix
-                _clothing.SetEquippedPrefix(uid, mask.IsToggled ? "toggled" : null, clothing);
-            }
-
-            // shouldn't this be an event?
-
-            // toggle ingestion blocking
-            if (TryComp<IngestionBlockerComponent>(uid, out var blocker))
-                blocker.Enabled = !mask.IsToggled;
-
-            // toggle identity
-            if (TryComp<IdentityBlockerComponent>(uid, out var identity))
-                identity.Enabled = !mask.IsToggled;
-
-            // toggle voice masking
-            if (TryComp<VoiceMaskComponent>(wearer, out var voiceMask))
-                voiceMask.Enabled = !mask.IsToggled;
-
-            // toggle breath tool connection (skip during equip since that is handled in LungSystem)
-            if (isEquip || !TryComp<BreathToolComponent>(uid, out var breathTool))
-                return;
-
-            if (mask.IsToggled)
-            {
-                _atmos.DisconnectInternals(breathTool);
-            }
-            else
-            {
-                breathTool.IsFunctional = true;
-
-                if (TryComp(wearer, out InternalsComponent? internals))
-                {
-                    breathTool.ConnectedInternalsEntity = wearer;
-                    _internals.ConnectBreathTool((wearer, internals), uid);
-                }
-            }
-        }
-    }
-}
index cdb4dc7c6c94814c111ec5f30824c0d67e186153..516191125499076d2f7e2304ae1605d95bd72e93 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.Access.Systems;
 using Content.Server.Administration.Logs;
 using Content.Server.Humanoid;
+using Content.Shared.Clothing;
 using Content.Shared.Database;
 using Content.Shared.Hands;
 using Content.Shared.Humanoid;
@@ -33,6 +34,7 @@ public class IdentitySystem : SharedIdentitySystem
         SubscribeLocalEvent<IdentityComponent, DidEquipHandEvent>((uid, _, _) => QueueIdentityUpdate(uid));
         SubscribeLocalEvent<IdentityComponent, DidUnequipEvent>((uid, _, _) => QueueIdentityUpdate(uid));
         SubscribeLocalEvent<IdentityComponent, DidUnequipHandEvent>((uid, _, _) => QueueIdentityUpdate(uid));
+        SubscribeLocalEvent<IdentityComponent, WearerMaskToggledEvent>((uid, _, _) => QueueIdentityUpdate(uid));
         SubscribeLocalEvent<IdentityComponent, MapInitEvent>(OnMapInit);
     }
 
index 68d2b78fbaa63c3a316e42558ee0527e6c86e809..c3188d07a0f5d3c8e361f55820894a8bcfece7cc 100644 (file)
@@ -1,6 +1,6 @@
-using Content.Server.Clothing;
+using Content.Server.Nutrition.EntitySystems;
 
-namespace Content.Server.Nutrition.EntitySystems;
+namespace Content.Server.Nutrition.Components;
 
 /// <summary>
 ///     Component that denotes a piece of clothing that blocks the mouth or otherwise prevents eating & drinking.
@@ -9,7 +9,7 @@ namespace Content.Server.Nutrition.EntitySystems;
 ///     In the event that more head-wear & mask functionality is added (like identity systems, or raising/lowering of
 ///     masks), then this component might become redundant.
 /// </remarks>
-[RegisterComponent, Access(typeof(FoodSystem), typeof(DrinkSystem), typeof(MaskSystem))]
+[RegisterComponent, Access(typeof(FoodSystem), typeof(DrinkSystem), typeof(IngestionBlockerSystem))]
 public sealed partial class IngestionBlockerComponent : Component
 {
     /// <summary>
diff --git a/Content.Server/Nutrition/EntitySystems/IngestionBlockerSystem.cs b/Content.Server/Nutrition/EntitySystems/IngestionBlockerSystem.cs
new file mode 100644 (file)
index 0000000..5c34df4
--- /dev/null
@@ -0,0 +1,18 @@
+using Content.Shared.Clothing;
+
+namespace Content.Server.Nutrition.EntitySystems;
+
+public sealed class IngestionBlockerSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<Components.IngestionBlockerComponent, ItemMaskToggledEvent>(OnBlockerMaskToggled);
+    }
+
+    private void OnBlockerMaskToggled(Entity<Components.IngestionBlockerComponent> ent, ref ItemMaskToggledEvent args)
+    {
+        ent.Comp.Enabled = !args.IsToggled;
+    }
+}
index 81ff76fb7a73fec35cdd893109767e8690fe6739..621ab4e39506f74f3add430a75c560f672be6891 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.Administration.Logs;
 using Content.Server.Chat.Systems;
 using Content.Server.Popups;
+using Content.Shared.Clothing;
 using Content.Shared.Database;
 using Content.Shared.Inventory.Events;
 using Content.Shared.Popups;
@@ -21,6 +22,7 @@ public sealed partial class VoiceMaskSystem : EntitySystem
     {
         SubscribeLocalEvent<VoiceMaskComponent, TransformSpeakerNameEvent>(OnSpeakerNameTransform);
         SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeNameMessage>(OnChangeName);
+        SubscribeLocalEvent<VoiceMaskComponent, ItemMaskToggledEvent>(OnMaskToggled);
         SubscribeLocalEvent<VoiceMaskerComponent, GotEquippedEvent>(OnEquip);
         SubscribeLocalEvent<VoiceMaskerComponent, GotUnequippedEvent>(OnUnequip);
         SubscribeLocalEvent<VoiceMaskSetNameEvent>(OnSetName);
@@ -67,6 +69,11 @@ public sealed partial class VoiceMaskSystem : EntitySystem
         }
     }
 
+    private void OnMaskToggled(Entity<VoiceMaskComponent> ent, ref ItemMaskToggledEvent args)
+    {
+        ent.Comp.Enabled = !args.IsToggled;
+    }
+
     private void OpenUI(EntityUid player, ActorComponent? actor = null)
     {
         if (!Resolve(player, ref actor))
index 028537f8b2b36b73f9ff21e98015313ae20a3fa6..b4c1224ce91d73abd8c9614878a853014a3c4612 100644 (file)
@@ -59,3 +59,15 @@ public sealed class EquipmentVisualsUpdatedEvent : EntityEventArgs
 }
 
 public sealed partial class ToggleMaskEvent : InstantActionEvent { }
+
+/// <summary>
+///     Event raised on the mask entity when it is toggled.
+/// </summary>
+[ByRefEvent]
+public readonly record struct ItemMaskToggledEvent(EntityUid Wearer, bool IsToggled, bool IsEquip);
+
+/// <summary>
+///     Event raised on the entity wearing the mask when it is toggled.
+/// </summary>
+[ByRefEvent]
+public readonly record struct WearerMaskToggledEvent(bool Enabled);
diff --git a/Content.Shared/Clothing/Components/MaskComponent.cs b/Content.Shared/Clothing/Components/MaskComponent.cs
new file mode 100644 (file)
index 0000000..e645524
--- /dev/null
@@ -0,0 +1,22 @@
+using Content.Shared.Clothing.EntitySystems;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Clothing.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(MaskSystem))]
+public sealed partial class MaskComponent : Component
+{
+    [DataField, AutoNetworkedField]
+    public EntProtoId ToggleAction = "ActionToggleMask";
+
+    /// <summary>
+    /// This mask can be toggled (pulled up/down)
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public EntityUid? ToggleActionEntity;
+
+    [DataField, AutoNetworkedField]
+    public bool IsToggled;
+}
index 1c69f1227c996ea3f482e12bba16e54550ee79ca..9aa01580886b3a6e844b45808dcb905417bc2dbf 100644 (file)
@@ -25,6 +25,7 @@ public abstract class ClothingSystem : EntitySystem
         SubscribeLocalEvent<ClothingComponent, ComponentHandleState>(OnHandleState);
         SubscribeLocalEvent<ClothingComponent, GotEquippedEvent>(OnGotEquipped);
         SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
+        SubscribeLocalEvent<ClothingComponent, ItemMaskToggledEvent>(OnMaskToggled);
     }
 
     protected virtual void OnGotEquipped(EntityUid uid, ClothingComponent component, GotEquippedEvent args)
@@ -52,6 +53,12 @@ public abstract class ClothingSystem : EntitySystem
             SetEquippedPrefix(uid, state.EquippedPrefix, component);
     }
 
+    private void OnMaskToggled(Entity<ClothingComponent> ent, ref ItemMaskToggledEvent args)
+    {
+        //TODO: sprites for 'pulled down' state. defaults to invisible due to no sprite with this prefix
+        SetEquippedPrefix(ent, args.IsToggled ? "toggled" : null, ent);
+    }
+
     #region Public API
 
     public void SetEquippedPrefix(EntityUid uid, string? prefix, ClothingComponent? clothing = null)
diff --git a/Content.Shared/Clothing/EntitySystems/MaskSystem.cs b/Content.Shared/Clothing/EntitySystems/MaskSystem.cs
new file mode 100644 (file)
index 0000000..50cf3af
--- /dev/null
@@ -0,0 +1,71 @@
+using Content.Shared.Actions;
+using Content.Shared.Clothing.Components;
+using Content.Shared.Inventory;
+using Content.Shared.Inventory.Events;
+using Content.Shared.Popups;
+
+namespace Content.Shared.Clothing.EntitySystems;
+
+public sealed class MaskSystem : EntitySystem
+{
+    [Dependency] private readonly SharedActionsSystem _actionSystem = default!;
+    [Dependency] private readonly InventorySystem _inventorySystem = default!;
+    [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<MaskComponent, ToggleMaskEvent>(OnToggleMask);
+        SubscribeLocalEvent<MaskComponent, GetItemActionsEvent>(OnGetActions);
+        SubscribeLocalEvent<MaskComponent, GotUnequippedEvent>(OnGotUnequipped);
+    }
+
+    private void OnGetActions(EntityUid uid, MaskComponent component, GetItemActionsEvent args)
+    {
+        if (!args.InHands)
+            args.AddAction(ref component.ToggleActionEntity, component.ToggleAction);
+    }
+
+    private void OnToggleMask(Entity<MaskComponent> ent, ref ToggleMaskEvent args)
+    {
+        var (uid, mask) = ent;
+        if (mask.ToggleActionEntity == null)
+            return;
+
+        if (!_inventorySystem.TryGetSlotEntity(args.Performer, "mask", out var existing) || !uid.Equals(existing))
+            return;
+
+        mask.IsToggled ^= true;
+        _actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled);
+
+        if (mask.IsToggled)
+            _popupSystem.PopupEntity(Loc.GetString("action-mask-pull-down-popup-message", ("mask", uid)), args.Performer, args.Performer);
+        else
+            _popupSystem.PopupEntity(Loc.GetString("action-mask-pull-up-popup-message", ("mask", uid)), args.Performer, args.Performer);
+
+        ToggleMaskComponents(uid, mask, args.Performer);
+    }
+
+    // set to untoggled when unequipped, so it isn't left in a 'pulled down' state
+    private void OnGotUnequipped(EntityUid uid, MaskComponent mask, GotUnequippedEvent args)
+    {
+        if (mask.ToggleActionEntity == null)
+            return;
+
+        mask.IsToggled = false;
+        Dirty(uid, mask);
+        _actionSystem.SetToggled(mask.ToggleActionEntity, mask.IsToggled);
+
+        ToggleMaskComponents(uid, mask, args.Equipee, true);
+    }
+
+    private void ToggleMaskComponents(EntityUid uid, MaskComponent mask, EntityUid wearer, bool isEquip = false)
+    {
+        var maskEv = new ItemMaskToggledEvent(wearer, mask.IsToggled, isEquip);
+        RaiseLocalEvent(uid, ref maskEv);
+
+        var wearerEv = new WearerMaskToggledEvent(mask.IsToggled);
+        RaiseLocalEvent(uid, ref wearerEv);
+    }
+}
index a671884089b92466281492b6aab912411517d3d3..7cb5f41b8a10c51e942d06783755209230db8ca4 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Shared.Clothing;
 using Content.Shared.IdentityManagement.Components;
 using Content.Shared.Inventory;
 using Robust.Shared.Containers;
@@ -16,6 +17,7 @@ public abstract class SharedIdentitySystem : EntitySystem
         SubscribeLocalEvent<IdentityComponent, ComponentInit>(OnComponentInit);
         SubscribeLocalEvent<IdentityBlockerComponent, SeeIdentityAttemptEvent>(OnSeeIdentity);
         SubscribeLocalEvent<IdentityBlockerComponent, InventoryRelayedEvent<SeeIdentityAttemptEvent>>((e, c, ev) => OnSeeIdentity(e, c, ev.Args));
+        SubscribeLocalEvent<IdentityBlockerComponent, ItemMaskToggledEvent>(OnMaskToggled);
     }
 
     private void OnSeeIdentity(EntityUid uid, IdentityBlockerComponent component, SeeIdentityAttemptEvent args)
@@ -28,4 +30,9 @@ public abstract class SharedIdentitySystem : EntitySystem
     {
         component.IdentityEntitySlot = _container.EnsureContainer<ContainerSlot>(uid, SlotName);
     }
+
+    private void OnMaskToggled(Entity<IdentityBlockerComponent> ent, ref ItemMaskToggledEvent args)
+    {
+        ent.Comp.Enabled = !args.IsToggled;
+    }
 }