]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
use manual component state for BaseEmitSoundComponent (#35030)
authorMilon <milonpl.git@proton.me>
Sun, 30 Mar 2025 13:41:11 +0000 (15:41 +0200)
committerGitHub <noreply@github.com>
Sun, 30 Mar 2025 13:41:11 +0000 (00:41 +1100)
* why

* cursed

13 files changed:
Content.Shared/Sound/Components/BaseEmitSoundComponent.cs
Content.Shared/Sound/Components/EmitSoundOnActivateComponent.cs
Content.Shared/Sound/Components/EmitSoundOnCollideComponent.cs
Content.Shared/Sound/Components/EmitSoundOnDropComponent.cs
Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs
Content.Shared/Sound/Components/EmitSoundOnLandComponent.cs
Content.Shared/Sound/Components/EmitSoundOnPickupComponent.cs
Content.Shared/Sound/Components/EmitSoundOnSpawnComponent.cs
Content.Shared/Sound/Components/EmitSoundOnThrowComponent.cs
Content.Shared/Sound/Components/EmitSoundOnUseComponent.cs
Content.Shared/Sound/Components/SpamEmitSoundComponent.cs
Content.Shared/Sound/Components/SpamEmitSoundRequirePowerComponent.cs
Content.Shared/Sound/SharedEmitSoundSystem.cs

index 870d20457ef761e6f360b90c4e1f6bc2c591a705..7011f72ef0bf9fd23fdaf3df4b51d5b16758f948 100644 (file)
@@ -1,4 +1,6 @@
 using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
 
 namespace Content.Shared.Sound.Components;
 
@@ -8,10 +10,9 @@ namespace Content.Shared.Sound.Components;
 /// </summary>
 public abstract partial class BaseEmitSoundComponent : Component
 {
-    public static readonly AudioParams DefaultParams = AudioParams.Default.WithVolume(-2f);
-
-    [AutoNetworkedField]
-    [ViewVariables(VVAccess.ReadWrite)]
+    /// <summary>
+    /// The <see cref="SoundSpecifier"/> to play.
+    /// </summary>
     [DataField(required: true)]
     public SoundSpecifier? Sound;
 
@@ -22,3 +23,15 @@ public abstract partial class BaseEmitSoundComponent : Component
     [DataField]
     public bool Positional;
 }
+
+/// <summary>
+/// Represents the state of <see cref="BaseEmitSoundComponent"/>.
+/// </summary>
+/// <remarks>This is obviously very cursed, but since the BaseEmitSoundComponent is abstract, we cannot network it.
+/// AutoGenerateComponentState attribute won't work here, and since everything revolves around inheritance for some fucking reason,
+/// there's no better way of doing this.</remarks>
+[Serializable, NetSerializable]
+public struct EmitSoundComponentState(SoundSpecifier? sound) : IComponentState
+{
+    public SoundSpecifier? Sound { get; } = sound;
+}
index 810f132d8318b7b4a7dcecfa3c6139493d90ba85..d6aa42177e82d0c1ca03bcd2a61f8e87b1807517 100644 (file)
@@ -17,6 +17,6 @@ public sealed partial class EmitSoundOnActivateComponent : BaseEmitSoundComponen
     ///     otherwise this might enable sound spamming, as use-delays are only initiated if the interaction was
     ///     handled.
     /// </remarks>
-    [DataField("handle")]
+    [DataField]
     public bool Handle = true;
 }
index a2cdd63ab70703b146c2808c619fa3c7731a8ab6..4cdea05220c7c1f841d55406178426589d2e1182 100644 (file)
@@ -11,13 +11,12 @@ public sealed partial class EmitSoundOnCollideComponent : BaseEmitSoundComponent
     /// <summary>
     /// Minimum velocity required for the sound to play.
     /// </summary>
-    [ViewVariables(VVAccess.ReadWrite), DataField("minVelocity")]
+    [DataField("minVelocity")]
     public float MinimumVelocity = 3f;
 
     /// <summary>
     /// To avoid sound spam add a cooldown to it.
     /// </summary>
-    [ViewVariables(VVAccess.ReadWrite), DataField("nextSound", customTypeSerializer: typeof(TimeOffsetSerializer))]
-    [AutoPausedField]
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
     public TimeSpan NextSound;
 }
index 5e04295607a717ae4193a044b1977cfa77f97714..64ed5e60dc94e4406aec857752199f701fcb1814 100644 (file)
@@ -6,6 +6,4 @@ namespace Content.Shared.Sound.Components;
 /// Simple sound emitter that emits sound on entity drop
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-public sealed partial class EmitSoundOnDropComponent : BaseEmitSoundComponent
-{
-}
+public sealed partial class EmitSoundOnDropComponent : BaseEmitSoundComponent;
index 49118d97999f46dbf9ed0a8b888e5e74da7b6573..d0b16fcec801314bfbada768f2793b33ca8d6d3e 100644 (file)
@@ -1,5 +1,4 @@
 using Content.Shared.Whitelist;
-using Robust.Shared.Prototypes;
 using Robust.Shared.GameStates;
 
 namespace Content.Shared.Sound.Components;
@@ -10,6 +9,9 @@ namespace Content.Shared.Sound.Components;
 [RegisterComponent, NetworkedComponent]
 public sealed partial class EmitSoundOnInteractUsingComponent : BaseEmitSoundComponent
 {
+    /// <summary>
+    /// The <see cref="EntityWhitelist"/> for the entities that can use this item.
+    /// </summary>
     [DataField(required: true)]
     public EntityWhitelist Whitelist = new();
 }
index 2d33a7f5f2c432f77ae0c105587958dd549fbb88..d3fceb85dd90b485007a3a7aaaf1848ba5670eca 100644 (file)
@@ -6,6 +6,4 @@ namespace Content.Shared.Sound.Components;
 /// Simple sound emitter that emits sound on LandEvent
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-public sealed partial class EmitSoundOnLandComponent : BaseEmitSoundComponent
-{
-}
+public sealed partial class EmitSoundOnLandComponent : BaseEmitSoundComponent;
index ee4b4b16886eb0c59d533aef380680255a75a5a8..dcf73b7ac2605b78c5a4a838b6bb693f8587c229 100644 (file)
@@ -6,6 +6,4 @@ namespace Content.Shared.Sound.Components;
 /// Simple sound emitter that emits sound on entity pickup
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-public sealed partial class EmitSoundOnPickupComponent : BaseEmitSoundComponent
-{
-}
+public sealed partial class EmitSoundOnPickupComponent : BaseEmitSoundComponent;
index 49d40ce185a4f16a73ba79c8787a377bc8361ef3..20d39b34600c28c440a674d09363d86207f7e6eb 100644 (file)
@@ -6,6 +6,4 @@ namespace Content.Shared.Sound.Components;
 ///     Simple sound emitter that emits sound on entity spawn.
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-public sealed partial class EmitSoundOnSpawnComponent : BaseEmitSoundComponent
-{
-}
+public sealed partial class EmitSoundOnSpawnComponent : BaseEmitSoundComponent;
index 5e3650a4a3c1c7046e541cc5e795e1865ed6223b..f8c0d1181b6c2fbb22c845a2caf5195862921986 100644 (file)
@@ -6,6 +6,4 @@ namespace Content.Shared.Sound.Components;
 /// Simple sound emitter that emits sound on ThrowEvent
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-public sealed partial class EmitSoundOnThrowComponent : BaseEmitSoundComponent
-{
-}
+public sealed partial class EmitSoundOnThrowComponent : BaseEmitSoundComponent;
index a99a01cec42acea7ac162761e30f2684ddbe7b22..ec7a277e92448b10a47bfaea7dc14a864b30cefa 100644 (file)
@@ -5,7 +5,7 @@ namespace Content.Shared.Sound.Components;
 /// <summary>
 /// Simple sound emitter that emits sound on UseInHand
 /// </summary>
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent]
 public sealed partial class EmitSoundOnUseComponent : BaseEmitSoundComponent
 {
     /// <summary>
@@ -17,6 +17,6 @@ public sealed partial class EmitSoundOnUseComponent : BaseEmitSoundComponent
     ///     otherwise this might enable sound spamming, as use-delays are only initiated if the interaction was
     ///     handled.
     /// </remarks>
-    [DataField("handle")]
+    [DataField]
     public bool Handle = true;
 }
index 149728a5baaf79b720de0efab3e1d013f939146a..7c1428798c1ecc7a5f9c63cdc8fb07901333c96f 100644 (file)
@@ -1,4 +1,5 @@
 using Robust.Shared.GameStates;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
 
 namespace Content.Shared.Sound.Components;
 
@@ -12,7 +13,7 @@ public sealed partial class SpamEmitSoundComponent : BaseEmitSoundComponent
     /// <summary>
     /// The time at which the next sound will play.
     /// </summary>
-    [DataField, AutoPausedField, AutoNetworkedField]
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField, AutoNetworkedField]
     public TimeSpan NextSound;
 
     /// <summary>
index b0547ea398eba4440adf3698da54bc24962342ba..bf5e925e0df0244f4a87b0a247a5d34cba0e8baa 100644 (file)
@@ -5,6 +5,4 @@ namespace Content.Shared.Sound.Components;
 /// on the powered state of the entity.
 /// </summary>
 [RegisterComponent]
-public sealed partial class SpamEmitSoundRequirePowerComponent : Component
-{
-}
+public sealed partial class SpamEmitSoundRequirePowerComponent : Component;
index 67aabbb74d2da8ff5e7d936613656f578fc73885..58d541e363e47545a3243c9352f1998171813e23 100644 (file)
@@ -12,6 +12,7 @@ using Content.Shared.Whitelist;
 using JetBrains.Annotations;
 using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.GameStates;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Network;
@@ -54,6 +55,47 @@ public abstract class SharedEmitSoundSystem : EntitySystem
         SubscribeLocalEvent<EmitSoundOnCollideComponent, StartCollideEvent>(OnEmitSoundOnCollide);
 
         SubscribeLocalEvent<SoundWhileAliveComponent, MobStateChangedEvent>(OnMobState);
+
+        // We need to handle state manually here
+        // BaseEmitSoundComponent isn't registered so we have to subscribe to each one
+        // TODO: Make it use autonetworking instead of relying on inheritance
+        SubscribeEmitComponent<EmitSoundOnActivateComponent>();
+        SubscribeEmitComponent<EmitSoundOnCollideComponent>();
+        SubscribeEmitComponent<EmitSoundOnDropComponent>();
+        SubscribeEmitComponent<EmitSoundOnInteractUsingComponent>();
+        SubscribeEmitComponent<EmitSoundOnLandComponent>();
+        SubscribeEmitComponent<EmitSoundOnPickupComponent>();
+        SubscribeEmitComponent<EmitSoundOnSpawnComponent>();
+        SubscribeEmitComponent<EmitSoundOnThrowComponent>();
+        SubscribeEmitComponent<EmitSoundOnUIOpenComponent>();
+        SubscribeEmitComponent<EmitSoundOnUseComponent>();
+
+        // Helper method so it's a little less ugly
+        void SubscribeEmitComponent<T>() where T : BaseEmitSoundComponent
+        {
+            SubscribeLocalEvent<T, ComponentGetState>(GetBaseEmitState);
+            SubscribeLocalEvent<T, ComponentHandleState>(HandleBaseEmitState);
+        }
+    }
+
+    private static void GetBaseEmitState<T>(Entity<T> ent, ref ComponentGetState args) where T : BaseEmitSoundComponent
+    {
+        args.State = new EmitSoundComponentState(ent.Comp.Sound);
+    }
+
+    private static void HandleBaseEmitState<T>(Entity<T> ent, ref ComponentHandleState args) where T : BaseEmitSoundComponent
+    {
+        if (args.Current is not EmitSoundComponentState state)
+            return;
+
+        ent.Comp.Sound = state.Sound switch
+        {
+            SoundPathSpecifier pathSpec => new SoundPathSpecifier(pathSpec.Path, pathSpec.Params),
+            SoundCollectionSpecifier collectionSpec => collectionSpec.Collection != null
+                ? new SoundCollectionSpecifier(collectionSpec.Collection, collectionSpec.Params)
+                : null,
+            _ => null,
+        };
     }
 
     private void HandleEmitSoundOnUIOpen(EntityUid uid, EmitSoundOnUIOpenComponent component, AfterActivatableUIOpenEvent args)