]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
predict itemcabinet (#14045)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sun, 12 Feb 2023 02:35:05 +0000 (21:35 -0500)
committerGitHub <noreply@github.com>
Sun, 12 Feb 2023 02:35:05 +0000 (02:35 +0000)
Content.Client/Cabinet/ItemCabinetSystem.cs
Content.Client/Cabinet/ItemCabinetVisualsComponent.cs [deleted file]
Content.Server/Cabinet/ItemCabinetComponent.cs [deleted file]
Content.Server/Cabinet/ItemCabinetSystem.cs
Content.Shared/Cabinet/ItemCabinetComponent.cs [new file with mode: 0644]
Content.Shared/Cabinet/ItemCabinetVisuals.cs [deleted file]
Content.Shared/Cabinet/SharedItemCabinetSystem.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Structures/Wallmounts/extinguisher_cabinet.yml
Resources/Prototypes/Entities/Structures/Wallmounts/fireaxe_cabinet.yml

index ec14c4049e590f491a6fd814b52e5faecfc6cf8a..aba4fdae00e99616b20780c369a6b9b08e157c33 100644 (file)
@@ -3,20 +3,20 @@ using Robust.Client.GameObjects;
 
 namespace Content.Client.Cabinet;
 
-public sealed class ItemCabinetSystem : VisualizerSystem<ItemCabinetVisualsComponent>
+public sealed class ItemCabinetSystem : SharedItemCabinetSystem
 {
-    protected override void OnAppearanceChange(EntityUid uid, ItemCabinetVisualsComponent component, ref AppearanceChangeEvent args)
+    protected override void UpdateAppearance(EntityUid uid, ItemCabinetComponent? cabinet = null)
     {
-        if (args.Sprite == null)
+        if (!Resolve(uid, ref cabinet))
             return;
 
-        if (AppearanceSystem.TryGetData<bool>(uid, ItemCabinetVisuals.IsOpen, out var isOpen, args.Component)
-            && AppearanceSystem.TryGetData<bool>(uid, ItemCabinetVisuals.ContainsItem, out var contains, args.Component))
-        {
-            var state = isOpen ? component.OpenState : component.ClosedState;
-            args.Sprite.LayerSetState(ItemCabinetVisualLayers.Door, state);
-            args.Sprite.LayerSetVisible(ItemCabinetVisualLayers.ContainsItem, contains);
-        }
+        if (!TryComp<SpriteComponent>(uid, out var sprite))
+            return;
+
+        var state = cabinet.Opened ? cabinet.OpenState : cabinet.ClosedState;
+        if (state != null)
+            sprite.LayerSetState(ItemCabinetVisualLayers.Door, state);
+        sprite.LayerSetVisible(ItemCabinetVisualLayers.ContainsItem, cabinet.CabinetSlot.HasItem);
     }
 }
 
diff --git a/Content.Client/Cabinet/ItemCabinetVisualsComponent.cs b/Content.Client/Cabinet/ItemCabinetVisualsComponent.cs
deleted file mode 100644 (file)
index 480445e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Content.Client.Cabinet;
-
-[RegisterComponent]
-public sealed class ItemCabinetVisualsComponent : Component
-{
-    [DataField("openState", required: true)]
-    public string OpenState = default!;
-
-    [DataField("closedState", required: true)]
-    public string ClosedState = default!;
-}
diff --git a/Content.Server/Cabinet/ItemCabinetComponent.cs b/Content.Server/Cabinet/ItemCabinetComponent.cs
deleted file mode 100644 (file)
index 92cdb87..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-using Content.Shared.Containers.ItemSlots;
-using Robust.Shared.Audio;
-
-namespace Content.Server.Cabinet
-{
-    /// <summary>
-    ///     Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets.
-    /// </summary>
-    [RegisterComponent]
-    public sealed class ItemCabinetComponent : Component
-    {
-        /// <summary>
-        ///     Sound to be played when the cabinet door is opened.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("doorSound", required: true)]
-        public SoundSpecifier DoorSound { get; set; } = default!;
-
-        /// <summary>
-        ///     The <see cref="ItemSlot"/> that stores the actual item. The entity whitelist, sounds, and other
-        ///     behaviours are specified by this <see cref="ItemSlot"/> definition.
-        /// </summary>
-        [DataField("cabinetSlot")]
-        public ItemSlot CabinetSlot = new();
-
-        /// <summary>
-        ///     Whether the cabinet is currently open or not.
-        /// </summary>
-        [DataField("opened")]
-        public bool Opened { get; set; } = false;
-    }
-}
index 439c6e7da55f4945bcdfbf3b55c5efa8091b0b88..a21532ad0cef415c51051c2eb4d6fa7b7f06143b 100644 (file)
@@ -1,130 +1,9 @@
-using Content.Server.Storage.Components;
-using Content.Shared.Audio;
 using Content.Shared.Cabinet;
-using Content.Shared.Containers.ItemSlots;
-using Content.Shared.Interaction;
-using Content.Shared.Lock;
-using Content.Shared.Verbs;
-using Robust.Server.GameObjects;
-using Robust.Shared.Audio;
-using Robust.Shared.Containers;
-using Robust.Shared.Player;
 
-namespace Content.Server.Cabinet
-{
-    public sealed class ItemCabinetSystem : EntitySystem
-    {
-        [Dependency] private readonly IComponentFactory _factory = default!;
-        [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
-        [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
-
-        public override void Initialize()
-        {
-            base.Initialize();
-
-            SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit);
-            SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove);
-            SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup);
-
-            SubscribeLocalEvent<ItemCabinetComponent, ActivateInWorldEvent>(OnActivateInWorld);
-            SubscribeLocalEvent<ItemCabinetComponent, GetVerbsEvent<ActivationVerb>>(AddToggleOpenVerb);
-
-            SubscribeLocalEvent<ItemCabinetComponent, EntInsertedIntoContainerMessage>(OnContainerModified);
-            SubscribeLocalEvent<ItemCabinetComponent, EntRemovedFromContainerMessage>(OnContainerModified);
-
-            SubscribeLocalEvent<ItemCabinetComponent, LockToggleAttemptEvent>(OnLockToggleAttempt);
-        }
-
-        private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args)
-        {
-            _itemSlotsSystem.AddItemSlot(uid, _factory.GetComponentName(cabinet.GetType()), cabinet.CabinetSlot);
-        }
-        private void OnComponentRemove(EntityUid uid, ItemCabinetComponent cabinet, ComponentRemove args)
-        {
-            _itemSlotsSystem.RemoveItemSlot(uid, cabinet.CabinetSlot);
-        }
-
-        private void OnComponentStartup(EntityUid uid, ItemCabinetComponent cabinet, ComponentStartup args)
-        {
-            UpdateAppearance(uid, cabinet);
-            _itemSlotsSystem.SetLock(uid, cabinet.CabinetSlot, !cabinet.Opened);
-        }
-
-        private void UpdateAppearance(EntityUid uid,
-            ItemCabinetComponent? cabinet = null,
-            AppearanceComponent? appearance = null)
-        {
-            if (!Resolve(uid, ref cabinet, ref appearance, false))
-                return;
-
-            _appearance.SetData(uid, ItemCabinetVisuals.IsOpen, cabinet.Opened, appearance);
-            _appearance.SetData(uid, ItemCabinetVisuals.ContainsItem, cabinet.CabinetSlot.HasItem, appearance);
-        }
-
-        private void OnContainerModified(EntityUid uid, ItemCabinetComponent cabinet, ContainerModifiedMessage args)
-        {
-            if (!cabinet.Initialized) return;
-
-            if (args.Container.ID == cabinet.CabinetSlot.ID)
-                UpdateAppearance(uid, cabinet);
-        }
+namespace Content.Server.Cabinet;
 
-        private void OnLockToggleAttempt(EntityUid uid, ItemCabinetComponent cabinet, ref LockToggleAttemptEvent args)
-        {
-            // Cannot lock or unlock while open.
-            if (cabinet.Opened)
-                args.Cancelled = true;
-        }
-
-        private void AddToggleOpenVerb(EntityUid uid, ItemCabinetComponent cabinet, GetVerbsEvent<ActivationVerb> args)
-        {
-            if (args.Hands == null || !args.CanAccess || !args.CanInteract)
-                return;
-
-            if (TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
-                return;
-
-            // Toggle open verb
-            ActivationVerb toggleVerb = new();
-            toggleVerb.Act = () => ToggleItemCabinet(uid, cabinet);
-            if (cabinet.Opened)
-            {
-                toggleVerb.Text = Loc.GetString("verb-common-close");
-                toggleVerb.IconTexture = "/Textures/Interface/VerbIcons/close.svg.192dpi.png";
-            }
-            else
-            {
-                toggleVerb.Text = Loc.GetString("verb-common-open");
-                toggleVerb.IconTexture = "/Textures/Interface/VerbIcons/open.svg.192dpi.png";
-            }
-            args.Verbs.Add(toggleVerb);
-        }
-
-        private void OnActivateInWorld(EntityUid uid, ItemCabinetComponent comp, ActivateInWorldEvent args)
-        {
-            if (args.Handled)
-                return;
-
-            args.Handled = true;
-            ToggleItemCabinet(uid, comp);
-        }
-
-        /// <summary>
-        ///     Toggles the ItemCabinet's state.
-        /// </summary>
-        private void ToggleItemCabinet(EntityUid uid, ItemCabinetComponent? cabinet = null)
-        {
-            if (!Resolve(uid, ref cabinet))
-                return;
-
-            if (TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
-                return;
-
-            cabinet.Opened = !cabinet.Opened;
-            SoundSystem.Play(cabinet.DoorSound.GetSound(), Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.15f));
-            _itemSlotsSystem.SetLock(uid, cabinet.CabinetSlot, !cabinet.Opened);
-
-            UpdateAppearance(uid, cabinet);
-        }
-    }
+public sealed class ItemCabinetSystem : SharedItemCabinetSystem
+{
+    // shitposting on main???
 }
+
diff --git a/Content.Shared/Cabinet/ItemCabinetComponent.cs b/Content.Shared/Cabinet/ItemCabinetComponent.cs
new file mode 100644 (file)
index 0000000..adb5f6d
--- /dev/null
@@ -0,0 +1,65 @@
+using Content.Shared.Containers.ItemSlots;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Cabinet;
+
+/// <summary>
+///     Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed class ItemCabinetComponent : Component
+{
+    /// <summary>
+    ///     Sound to be played when the cabinet door is opened.
+    /// </summary>
+    [DataField("doorSound"), ViewVariables(VVAccess.ReadWrite)]
+    public SoundSpecifier? DoorSound;
+
+    /// <summary>
+    ///     The <see cref="ItemSlot"/> that stores the actual item. The entity whitelist, sounds, and other
+    ///     behaviours are specified by this <see cref="ItemSlot"/> definition.
+    /// </summary>
+    [DataField("cabinetSlot"), ViewVariables]
+    public ItemSlot CabinetSlot = new();
+
+    /// <summary>
+    ///     Whether the cabinet is currently open or not.
+    /// </summary>
+    [DataField("opened")]
+    public bool Opened;
+
+    /// <summary>
+    /// The state for when the cabinet is open
+    /// </summary>
+    [DataField("openState"), ViewVariables(VVAccess.ReadWrite)]
+    public string? OpenState;
+
+    /// <summary>
+    /// The state for when the cabinet is closed
+    /// </summary>
+    [DataField("closedState"), ViewVariables(VVAccess.ReadWrite)]
+    public string? ClosedState;
+}
+
+[Serializable, NetSerializable]
+public sealed class ItemCabinetComponentState : ComponentState
+{
+    public SoundSpecifier? DoorSound;
+
+    public bool Opened;
+
+    public string? OpenState;
+
+    public string? ClosedState;
+
+    public ItemCabinetComponentState(SoundSpecifier? doorSound, bool opened, string? openState, string? closedState)
+    {
+        DoorSound = doorSound;
+        Opened = opened;
+        OpenState = openState;
+        ClosedState = closedState;
+    }
+}
+
diff --git a/Content.Shared/Cabinet/ItemCabinetVisuals.cs b/Content.Shared/Cabinet/ItemCabinetVisuals.cs
deleted file mode 100644 (file)
index d09e1ba..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Cabinet
-{
-    [Serializable, NetSerializable]
-    public enum ItemCabinetVisuals : byte
-    {
-        IsOpen,
-        ContainsItem
-    }
-}
diff --git a/Content.Shared/Cabinet/SharedItemCabinetSystem.cs b/Content.Shared/Cabinet/SharedItemCabinetSystem.cs
new file mode 100644 (file)
index 0000000..766373c
--- /dev/null
@@ -0,0 +1,148 @@
+using Content.Shared.Containers.ItemSlots;
+using Content.Shared.Interaction;
+using Content.Shared.Lock;
+using Content.Shared.Verbs;
+using Robust.Shared.Audio;
+using Robust.Shared.Containers;
+using Robust.Shared.GameStates;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Cabinet;
+
+public abstract class SharedItemCabinetSystem : EntitySystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
+    [Dependency] private readonly SharedAudioSystem _audio = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<ItemCabinetComponent, ComponentGetState>(OnGetState);
+        SubscribeLocalEvent<ItemCabinetComponent, ComponentHandleState>(OnHandleState);
+
+        SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit);
+        SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove);
+        SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup);
+
+        SubscribeLocalEvent<ItemCabinetComponent, ActivateInWorldEvent>(OnActivateInWorld);
+        SubscribeLocalEvent<ItemCabinetComponent, GetVerbsEvent<AlternativeVerb>>(AddToggleOpenVerb);
+
+        SubscribeLocalEvent<ItemCabinetComponent, EntInsertedIntoContainerMessage>(OnContainerModified);
+        SubscribeLocalEvent<ItemCabinetComponent, EntRemovedFromContainerMessage>(OnContainerModified);
+
+        SubscribeLocalEvent<ItemCabinetComponent, LockToggleAttemptEvent>(OnLockToggleAttempt);
+    }
+
+    private void OnGetState(EntityUid uid, ItemCabinetComponent component, ref ComponentGetState args)
+    {
+        args.State = new ItemCabinetComponentState(component.DoorSound,
+            component.Opened,
+            component.OpenState,
+            component.ClosedState);
+    }
+
+    private void OnHandleState(EntityUid uid, ItemCabinetComponent component, ref ComponentHandleState args)
+    {
+        if (args.Current is not ItemCabinetComponentState state)
+            return;
+        component.DoorSound = state.DoorSound;
+        component.Opened = state.Opened;
+        component.OpenState = state.OpenState;
+        component.ClosedState = state.ClosedState;
+    }
+
+    private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args)
+    {
+        _itemSlots.AddItemSlot(uid, "ItemCabinet", cabinet.CabinetSlot);
+    }
+
+    private void OnComponentRemove(EntityUid uid, ItemCabinetComponent cabinet, ComponentRemove args)
+    {
+        _itemSlots.RemoveItemSlot(uid, cabinet.CabinetSlot);
+    }
+
+    private void OnComponentStartup(EntityUid uid, ItemCabinetComponent cabinet, ComponentStartup args)
+    {
+        UpdateAppearance(uid, cabinet);
+        _itemSlots.SetLock(uid, cabinet.CabinetSlot, !cabinet.Opened);
+    }
+
+    protected virtual void UpdateAppearance(EntityUid uid, ItemCabinetComponent? cabinet = null)
+    {
+        // we don't fuck with appearance data, and instead just manually update the sprite on the client
+    }
+
+    private void OnContainerModified(EntityUid uid, ItemCabinetComponent cabinet, ContainerModifiedMessage args)
+    {
+        if (!cabinet.Initialized)
+            return;
+
+        if (args.Container.ID == cabinet.CabinetSlot.ID)
+            UpdateAppearance(uid, cabinet);
+    }
+
+    private void OnLockToggleAttempt(EntityUid uid, ItemCabinetComponent cabinet, ref LockToggleAttemptEvent args)
+    {
+        // Cannot lock or unlock while open.
+        if (cabinet.Opened)
+            args.Cancelled = true;
+    }
+
+    private void AddToggleOpenVerb(EntityUid uid, ItemCabinetComponent cabinet, GetVerbsEvent<AlternativeVerb> args)
+    {
+        if (args.Hands == null || !args.CanAccess || !args.CanInteract)
+            return;
+
+        if (TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
+            return;
+
+        // Toggle open verb
+        AlternativeVerb toggleVerb = new()
+        {
+            Act = () => ToggleItemCabinet(uid, args.User, cabinet)
+        };
+        if (cabinet.Opened)
+        {
+            toggleVerb.Text = Loc.GetString("verb-common-close");
+            toggleVerb.IconTexture = "/Textures/Interface/VerbIcons/close.svg.192dpi.png";
+        }
+        else
+        {
+            toggleVerb.Text = Loc.GetString("verb-common-open");
+            toggleVerb.IconTexture = "/Textures/Interface/VerbIcons/open.svg.192dpi.png";
+        }
+        args.Verbs.Add(toggleVerb);
+    }
+
+    private void OnActivateInWorld(EntityUid uid, ItemCabinetComponent comp, ActivateInWorldEvent args)
+    {
+        if (args.Handled)
+            return;
+
+        args.Handled = true;
+        ToggleItemCabinet(uid, args.User, comp);
+    }
+
+    /// <summary>
+    ///     Toggles the ItemCabinet's state.
+    /// </summary>
+    public void ToggleItemCabinet(EntityUid uid, EntityUid? user = null, ItemCabinetComponent? cabinet = null)
+    {
+        if (!Resolve(uid, ref cabinet))
+            return;
+
+        if (TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
+            return;
+
+        cabinet.Opened = !cabinet.Opened;
+        Dirty(cabinet);
+        _itemSlots.SetLock(uid, cabinet.CabinetSlot, !cabinet.Opened);
+
+        if (_timing.IsFirstTimePredicted)
+        {
+            UpdateAppearance(uid, cabinet);
+            _audio.PlayPredicted(cabinet.DoorSound, uid, user, AudioParams.Default.WithVariation(0.15f));
+        }
+    }
+}
index 644e89d97689b7f47eb8138bc5fc9f7f20916701..91c744f33a56841057da0c869eb036e4885051ec 100644 (file)
           - FireExtinguisher
       doorSound:
         path: /Audio/Machines/machine_switch.ogg
-    - type: Appearance
-    - type: ItemCabinetVisuals
       openState: open
       closedState: closed
+    - type: Appearance
     - type: ItemSlots
     - type: ContainerContainer
       containers:
   components:
   - type: ItemCabinet
     opened: true
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: open
+    closedState: closed
 
 - type: entity
   id: ExtinguisherCabinetFilled
       whitelist:
         components:
         - FireExtinguisher
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: open
+    closedState: closed
 
 - type: entity
   id: ExtinguisherCabinetFilledOpen
@@ -82,3 +89,7 @@
   components:
   - type: ItemCabinet
     opened: true
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: open
+    closedState: closed
index 19111ec26c33e45a5875eeb0d59c4ea3632292da..1d021c50a4ff464b82adf9822e3c0d8926ba6715 100644 (file)
@@ -3,43 +3,42 @@
   name: fire axe cabinet
   description: There is a small label that reads "For Emergency use only" along with details for safe use of the axe. As if.
   components:
-    - type: MeleeSound
-      soundGroups:
-        Brute:
-          path:
-            "/Audio/Effects/glass_hit.ogg"
-    - type: WallMount
-    - type: Clickable
-    - type: InteractionOutline
-    - type: Sprite
-      sprite: Structures/Wallmounts/fireaxe_cabinet.rsi
-      netsync: false
-      layers:
-      - state: cabinet
-      - state: fireaxe
-        map: ["enum.ItemCabinetVisualLayers.ContainsItem"]
-        visible: true
-      - state: glass
-        map: ["enum.ItemCabinetVisualLayers.Door"]
-    - type: ItemCabinet
-      cabinetSlot:
-        ejectOnInteract: true
-        whitelist:
-          tags:
-          - FireAxe
-      doorSound:
-        path: /Audio/Machines/machine_switch.ogg
-    - type: Appearance
-    - type: ItemCabinetVisuals
-      openState: glass-up
-      closedState: glass
-    - type: Lock      
-    - type: AccessReader
-      access: [["Atmospherics"]]
-    - type: ItemSlots
-    - type: ContainerContainer
-      containers:
-        ItemCabinet: !type:ContainerSlot
+  - type: MeleeSound
+    soundGroups:
+      Brute:
+        path:
+          "/Audio/Effects/glass_hit.ogg"
+  - type: WallMount
+  - type: Clickable
+  - type: InteractionOutline
+  - type: Sprite
+    sprite: Structures/Wallmounts/fireaxe_cabinet.rsi
+    netsync: false
+    layers:
+    - state: cabinet
+    - state: fireaxe
+      map: ["enum.ItemCabinetVisualLayers.ContainsItem"]
+      visible: true
+    - state: glass
+      map: ["enum.ItemCabinetVisualLayers.Door"]
+  - type: ItemCabinet
+    cabinetSlot:
+      ejectOnInteract: true
+      whitelist:
+        tags:
+        - FireAxe
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: glass-up
+    closedState: glass
+  - type: Appearance
+  - type: Lock
+  - type: AccessReader
+    access: [["Atmospherics"]]
+  - type: ItemSlots
+  - type: ContainerContainer
+    containers:
+      ItemCabinet: !type:ContainerSlot
   placement:
     mode: SnapgridCenter
 
   components:
   - type: ItemCabinet
     opened: true
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: glass-up
+    closedState: glass
 
 - type: entity
   id: FireAxeCabinetFilled
       whitelist:
         tags:
         - FireAxe
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: glass-up
+    closedState: glass
 
 - type: entity
   id: FireAxeCabinetFilledOpen
@@ -71,3 +78,7 @@
   components:
   - type: ItemCabinet
     opened: true
+    doorSound:
+      path: /Audio/Machines/machine_switch.ogg
+    openState: glass-up
+    closedState: glass