diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs
index 4d4bf23392..9ba634072a 100644
--- a/Content.Client/Entry/IgnoredComponents.cs
+++ b/Content.Client/Entry/IgnoredComponents.cs
@@ -17,6 +17,8 @@ namespace Content.Client.Entry
"OnUseTimerTrigger",
"WarpPoint",
"EmitSoundOnUse",
+ "EmitSoundOnLand",
+ "EmitSoundOnActivate",
"FootstepModifier",
"HeatResistance",
"ItemTeleporter",
diff --git a/Content.Server/Interaction/Components/EmitSoundOnUseComponent.cs b/Content.Server/Interaction/Components/EmitSoundOnUseComponent.cs
index 7a65f2e1bd..c4f2070b78 100644
--- a/Content.Server/Interaction/Components/EmitSoundOnUseComponent.cs
+++ b/Content.Server/Interaction/Components/EmitSoundOnUseComponent.cs
@@ -1,45 +1,15 @@
-using Content.Shared.Audio;
-using Content.Shared.Interaction;
-using Robust.Shared.Audio;
+using Content.Server.Sound;
using Robust.Shared.GameObjects;
-using Robust.Shared.Player;
-using Robust.Shared.Serialization.Manager.Attributes;
-using Robust.Shared.ViewVariables;
namespace Content.Server.Interaction.Components
{
///
- /// Simple sound emitter that emits sound on use in hand
+ /// Simple sound emitter that emits sound on UseInHand
///
[RegisterComponent]
- public class EmitSoundOnUseComponent : Component, IUse
+ public class EmitSoundOnUseComponent : BaseEmitSoundComponent
{
///
- ///
public override string Name => "EmitSoundOnUse";
-
- [ViewVariables(VVAccess.ReadWrite)] [DataField("sound")] public string? _soundName;
- [ViewVariables(VVAccess.ReadWrite)] [DataField("variation")] public float _pitchVariation;
- [ViewVariables(VVAccess.ReadWrite)] [DataField("semitoneVariation")] public int _semitoneVariation;
-
- bool IUse.UseEntity(UseEntityEventArgs eventArgs)
- {
- if (!string.IsNullOrWhiteSpace(_soundName))
- {
- if (_pitchVariation > 0.0)
- {
- SoundSystem.Play(Filter.Pvs(Owner), _soundName, Owner, AudioHelpers.WithVariation(_pitchVariation).WithVolume(-2f));
- return true;
- }
- if (_semitoneVariation > 0)
- {
- SoundSystem.Play(Filter.Pvs(Owner), _soundName, Owner, AudioHelpers.WithSemitoneVariation(_semitoneVariation).WithVolume(-2f));
- return true;
- }
- SoundSystem.Play(Filter.Pvs(Owner), _soundName, Owner, AudioParams.Default.WithVolume(-2f));
- return true;
- }
- return false;
- }
}
}
diff --git a/Content.Server/Sound/BaseEmitSoundComponent.cs b/Content.Server/Sound/BaseEmitSoundComponent.cs
new file mode 100644
index 0000000000..a1a4df3a56
--- /dev/null
+++ b/Content.Server/Sound/BaseEmitSoundComponent.cs
@@ -0,0 +1,15 @@
+using Robust.Shared.GameObjects;
+using Robust.Shared.Serialization.Manager.Attributes;
+using Robust.Shared.ViewVariables;
+
+namespace Content.Server.Sound
+{
+ ///
+ /// Base sound emitter which defines most of the data fields.
+ ///
+ public abstract class BaseEmitSoundComponent : Component
+ {
+ [ViewVariables(VVAccess.ReadWrite)] [DataField("variation")] public float PitchVariation { get; set; } = 0.0f;
+ [ViewVariables(VVAccess.ReadWrite)] [DataField("soundCollection", required: true)] public string SoundCollectionName { get; set; } = default!;
+ }
+}
diff --git a/Content.Server/Sound/EmitSoundOnActivateComponent.cs b/Content.Server/Sound/EmitSoundOnActivateComponent.cs
new file mode 100644
index 0000000000..fdbb9f7aed
--- /dev/null
+++ b/Content.Server/Sound/EmitSoundOnActivateComponent.cs
@@ -0,0 +1,14 @@
+using Robust.Shared.GameObjects;
+
+namespace Content.Server.Sound
+{
+ ///
+ /// Simple sound emitter that emits sound on ActivateInWorld
+ ///
+ [RegisterComponent]
+ public class EmitSoundOnActivateComponent : BaseEmitSoundComponent
+ {
+ ///
+ public override string Name => "EmitSoundOnActivate";
+ }
+}
diff --git a/Content.Server/Sound/EmitSoundOnLandComponent.cs b/Content.Server/Sound/EmitSoundOnLandComponent.cs
new file mode 100644
index 0000000000..1d6286abdd
--- /dev/null
+++ b/Content.Server/Sound/EmitSoundOnLandComponent.cs
@@ -0,0 +1,14 @@
+using Robust.Shared.GameObjects;
+
+namespace Content.Server.Sound
+{
+ ///
+ /// Simple sound emitter that emits sound on LandEvent
+ ///
+ [RegisterComponent]
+ public class EmitSoundOnLandComponent : BaseEmitSoundComponent
+ {
+ ///
+ public override string Name => "EmitSoundOnLand";
+ }
+}
diff --git a/Content.Server/Sound/EmitSoundSystem.cs b/Content.Server/Sound/EmitSoundSystem.cs
new file mode 100644
index 0000000000..3459522a3e
--- /dev/null
+++ b/Content.Server/Sound/EmitSoundSystem.cs
@@ -0,0 +1,56 @@
+using Content.Shared.Audio;
+using Content.Shared.Interaction;
+using Content.Shared.Throwing;
+using Content.Server.Interaction.Components;
+using Content.Server.Throwing;
+using JetBrains.Annotations;
+using Robust.Shared.Audio;
+using Robust.Shared.GameObjects;
+using Robust.Shared.IoC;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Player;
+using Robust.Shared.Random;
+
+namespace Content.Server.Sound
+{
+ [UsedImplicitly]
+ public class EmitSoundSystem : EntitySystem
+ {
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ ///
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent((eUI, comp, arg) => PlaySound(comp));
+ SubscribeLocalEvent((eUI, comp, arg) => PlaySound(comp));
+ SubscribeLocalEvent((eUI, comp, arg) => PlaySound(comp));
+ SubscribeLocalEvent((eUI, comp, args) => PlaySound(comp));
+ }
+
+ private void PlaySound(BaseEmitSoundComponent component)
+ {
+ PlayRandomSoundFromCollection(component);
+ }
+
+ private void PlayRandomSoundFromCollection(BaseEmitSoundComponent component)
+ {
+ var file = SelectRandomSoundFromSoundCollection(component.SoundCollectionName!);
+ PlaySingleSound(file, component);
+ }
+
+ private string SelectRandomSoundFromSoundCollection(string soundCollectionName)
+ {
+ var soundCollection = _prototypeManager.Index(soundCollectionName);
+ return _random.Pick(soundCollection.PickFiles);
+ }
+
+ private static void PlaySingleSound(string soundName, BaseEmitSoundComponent component)
+ {
+ SoundSystem.Play(Filter.Pvs(component.Owner), soundName, component.Owner,
+ AudioHelpers.WithVariation(component.PitchVariation).WithVolume(-2f));
+ }
+ }
+}
+
diff --git a/Content.Server/Throwing/EmitSoundOnThrowComponent.cs b/Content.Server/Throwing/EmitSoundOnThrowComponent.cs
index c5cfdb2a44..d56af69811 100644
--- a/Content.Server/Throwing/EmitSoundOnThrowComponent.cs
+++ b/Content.Server/Throwing/EmitSoundOnThrowComponent.cs
@@ -1,42 +1,15 @@
-using Content.Shared.Audio;
-using Content.Shared.Throwing;
-using Robust.Shared.Audio;
+using Content.Server.Sound;
using Robust.Shared.GameObjects;
-using Robust.Shared.Player;
-using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Throwing
{
///
- /// Simple sound emitter that emits sound on use in hand
+ /// Simple sound emitter that emits sound on ThrowEvent
///
[RegisterComponent]
- public class EmitSoundOnThrowComponent : Component, ILand
+ public class EmitSoundOnThrowComponent : BaseEmitSoundComponent
{
///
- ///
public override string Name => "EmitSoundOnThrow";
-
- [DataField("sound")]
- public string? _soundName;
- [DataField("variation")]
- public float _pitchVariation;
-
- public void PlaySoundEffect()
- {
- if (!string.IsNullOrWhiteSpace(_soundName))
- {
- if (_pitchVariation > 0.0)
- {
- SoundSystem.Play(Filter.Pvs(Owner), _soundName, Owner, AudioHelpers.WithVariation(_pitchVariation).WithVolume(-2f));
- }
- SoundSystem.Play(Filter.Pvs(Owner), _soundName, Owner, AudioParams.Default.WithVolume(-2f));
- }
- }
-
- void ILand.Land(LandEventArgs eventArgs)
- {
- PlaySoundEffect();
- }
}
}
diff --git a/Content.Shared/Throwing/ThrownItemSystem.cs b/Content.Shared/Throwing/ThrownItemSystem.cs
index 8c743b93ab..61b94ef4cf 100644
--- a/Content.Shared/Throwing/ThrownItemSystem.cs
+++ b/Content.Shared/Throwing/ThrownItemSystem.cs
@@ -99,7 +99,7 @@ namespace Content.Shared.Throwing
// LandInteraction
// TODO: Refactor these to system messages
var landMsg = new LandEvent(user, landing, coordinates);
- RaiseLocalEvent(landMsg);
+ RaiseLocalEvent(landing.Uid, landMsg);
if (landMsg.Handled)
{
return;
diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml
index 64b32c7112..42ad54d637 100644
--- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml
+++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml
@@ -2,96 +2,81 @@
- type: entity
parent: BaseItem
+ id: BasePlushie
+ components:
+ - type: EmitSoundOnUse
+ soundCollection: ToySqueak
+ - type: EmitSoundOnLand
+ soundCollection: ToySqueak
+ - type: EmitSoundOnActivate
+ soundCollection: ToySqueak
+ - type: LoopingSound
+ - type: ItemCooldown
+ - type: UseDelay
+ delay: 1.0
+
+- type: entity
+ parent: BasePlushie
id: PlushieBee
name: bee plushie
description: A cute toy that resembles an even cuter programmer.
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: plushie_h
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
- parent: BaseItem
+ parent: BasePlushie
id: PlushieNuke
name: nukie plushie
description: A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious.
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: plushie_nuke
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
- parent: BaseItem
+ parent: BasePlushie
id: PlushieLizard
name: lizard plushie
description: An adorable stuffed toy that resembles a lizardperson. Made by CentCom as a token initiative to combat speciesism in work environments. "Welcome your new colleges as you do this plush, with open arms!"
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: plushie_lizard
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
- parent: BaseItem
+ parent: BasePlushie
id: PlushieNar
name: nar'sie plushie
description: A small stuffed doll of the elder goddess Nar'Sie.
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: narplush
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
- parent: BaseItem
+ parent: BasePlushie
id: PlushieCarp
name: carp plushie
description: An adorable stuffed toy that resembles the monstrous space carp.
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: carpplush
- type: Item
sprite: Objects/Fun/toys.rsi
HeldPrefix: carpplush
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
- parent: BaseItem
+ parent: BasePlushie
id: PlushieSlime
name: slime plushie
description: An adorable stuffed toy that resembles a slime. It's basically a hacky sack.
components:
- - type: Toys
- - type: LoopingSound
- type: Sprite
sprite: Objects/Fun/toys.rsi
state: plushie_slime
- - type: ItemCooldown
- - type: UseDelay
- delay: 1.0
- type: entity
parent: BaseItem