[Ready] SoundComponent (#164)

Requires https://github.com/space-wizards/space-station-14/pull/768

- [x] Play sounds
- [x] SoundSchedules actually work
- [x] Send sound to specific users
- [x] Make existing components use SoundComponent
- [x] Add ScheduledSounds from prototypes
- [x] Add Play methods equivalent to those of AudioSystem.
- [x] Document most code.
This commit is contained in:
Víctor Aguilera Puerto
2019-03-28 14:31:49 +01:00
committed by Pieter-Jan Briers
parent 8926669f3a
commit d090e98bd4
21 changed files with 350 additions and 31 deletions

View File

@@ -84,6 +84,7 @@
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" /> <Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" /> <Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
<Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" /> <Compile Include="GameObjects\Components\Power\PowerCellVisualizer2D.cs" />
<Compile Include="GameObjects\Components\Sound\SoundComponent.cs" />
<Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" /> <Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" />
<Compile Include="GameObjects\Components\Weapons\Ranged\BallisticMagazineVisualizer2D.cs" /> <Compile Include="GameObjects\Components\Weapons\Ranged\BallisticMagazineVisualizer2D.cs" />
<Compile Include="GameObjects\Components\Weapons\Ranged\BallisticMagazineWeaponVisualizer2D.cs" /> <Compile Include="GameObjects\Components\Weapons\Ranged\BallisticMagazineWeaponVisualizer2D.cs" />

View File

@@ -26,6 +26,7 @@ using SS14.Shared.IoC;
using SS14.Shared.Prototypes; using SS14.Shared.Prototypes;
using System; using System;
using Content.Client.GameObjects.Components.Mobs; using Content.Client.GameObjects.Components.Mobs;
using Content.Client.GameObjects.Components.Sound;
using Content.Client.UserInterface; using Content.Client.UserInterface;
using Content.Shared.GameObjects.Components.Markers; using Content.Shared.GameObjects.Components.Markers;
using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.GameObjects.Components.Mobs;
@@ -82,6 +83,7 @@ namespace Content.Client
factory.Register<DamageableComponent>(); factory.Register<DamageableComponent>();
factory.Register<ClothingComponent>(); factory.Register<ClothingComponent>();
factory.Register<ItemComponent>(); factory.Register<ItemComponent>();
factory.Register<SoundComponent>();
factory.RegisterReference<ClothingComponent, ItemComponent>(); factory.RegisterReference<ClothingComponent, ItemComponent>();

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Sound;
using SS14.Client.GameObjects.EntitySystems;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
using SS14.Shared.Interfaces.Timers;
using SS14.Shared.IoC;
using SS14.Shared.Log;
using SS14.Shared.Serialization;
using SS14.Shared.Timers;
namespace Content.Client.GameObjects.Components.Sound
{
public class SoundComponent : SharedSoundComponent
{
private readonly List<ScheduledSound> _schedules = new List<ScheduledSound>();
private AudioSystem _audioSystem;
private Random Random;
public override void StopAllSounds()
{
foreach (var schedule in _schedules)
{
schedule.Play = false;
}
_schedules.Clear();
}
public override void StopScheduledSound(string filename)
{
foreach (var schedule in _schedules.ToArray())
{
if (schedule.Filename != filename) continue;
schedule.Play = false;
_schedules.Remove(schedule);
}
}
public override void AddScheduledSound(ScheduledSound schedule)
{
_schedules.Add(schedule);
Play(schedule);
}
public void Play(ScheduledSound schedule)
{
if (!schedule.Play) return;
if (Random == null) Random = new Random(Owner.Uid.GetHashCode() ^ DateTime.Now.GetHashCode());
Timer.Spawn((int) schedule.Delay + (Random.Next((int) schedule.RandomDelay)),() =>
{
if (!schedule.Play) return; // We make sure this hasn't changed.
if (_audioSystem == null) _audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
_audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams);
if (schedule.Times == 0)
{
_schedules.Remove(schedule);
return;
}
if (schedule.Times > 0)
schedule.Times--;
Play(schedule);
});
}
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
switch (message)
{
case ScheduledSoundMessage msg:
AddScheduledSound(msg.Schedule);
break;
case StopSoundScheduleMessage msg:
StopScheduledSound(msg.Filename);
break;
case StopAllSoundsMessage msg:
StopAllSounds();
break;
}
}
public override void Initialize()
{
base.Initialize();
IoCManager.Resolve<IEntitySystemManager>().TryGetEntitySystem(out _audioSystem);
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
if (serializer.Writing) return;
serializer.TryReadDataField("schedules", out List<ScheduledSound> schedules);
if (schedules == null) return;
foreach (var schedule in schedules)
{
if (schedule == null) continue;
AddScheduledSound(schedule);
}
}
}
}

View File

@@ -99,6 +99,7 @@
<Compile Include="GameObjects\Components\Power\PowerTransferComponent.cs" /> <Compile Include="GameObjects\Components\Power\PowerTransferComponent.cs" />
<Compile Include="GameObjects\Components\Projectiles\ProjectileComponent.cs" /> <Compile Include="GameObjects\Components\Projectiles\ProjectileComponent.cs" />
<Compile Include="GameObjects\Components\Projectiles\ThrownItemComponent.cs" /> <Compile Include="GameObjects\Components\Projectiles\ThrownItemComponent.cs" />
<Compile Include="GameObjects\Components\Sound\SoundComponent.cs" />
<Compile Include="GameObjects\Components\Weapon\Melee\MeleeWeaponComponent.cs" /> <Compile Include="GameObjects\Components\Weapon\Melee\MeleeWeaponComponent.cs" />
<Compile Include="GameObjects\Components\Weapon\Ranged\Hitscan\HitscanWeaponComponent.cs" /> <Compile Include="GameObjects\Components\Weapon\Ranged\Hitscan\HitscanWeaponComponent.cs" />
<Compile Include="GameObjects\Components\Weapon\Ranged\Projectile\BallisticBulletComponent.cs" /> <Compile Include="GameObjects\Components\Weapon\Ranged\Projectile\BallisticBulletComponent.cs" />

View File

@@ -35,6 +35,7 @@ using Content.Server.Mobs;
using Content.Server.Players; using Content.Server.Players;
using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Markers; using Content.Server.GameObjects.Components.Markers;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.Components.Weapon.Ranged; using Content.Server.GameObjects.Components.Weapon.Ranged;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Interfaces; using Content.Server.Interfaces;
@@ -107,6 +108,7 @@ namespace Content.Server
factory.Register<MeleeWeaponComponent>(); factory.Register<MeleeWeaponComponent>();
factory.Register<HealingComponent>(); factory.Register<HealingComponent>();
factory.Register<SoundComponent>();
factory.Register<HandheldLightComponent>(); factory.Register<HandheldLightComponent>();

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Content.Server.GameObjects.Components.Interactable.Tools; using Content.Server.GameObjects.Components.Interactable.Tools;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Construction; using Content.Shared.Construction;
@@ -28,7 +29,6 @@ namespace Content.Server.GameObjects.Components.Construction
SpriteComponent Sprite; SpriteComponent Sprite;
ITransformComponent Transform; ITransformComponent Transform;
AudioSystem AudioSystem;
Random random; Random random;
public override void Initialize() public override void Initialize()
@@ -38,7 +38,6 @@ namespace Content.Server.GameObjects.Components.Construction
Sprite = Owner.GetComponent<SpriteComponent>(); Sprite = Owner.GetComponent<SpriteComponent>();
Transform = Owner.GetComponent<ITransformComponent>(); Transform = Owner.GetComponent<ITransformComponent>();
var systemman = IoCManager.Resolve<IEntitySystemManager>(); var systemman = IoCManager.Resolve<IEntitySystemManager>();
AudioSystem = systemman.GetEntitySystem<AudioSystem>();
random = new Random(); random = new Random();
} }
@@ -95,6 +94,8 @@ namespace Content.Server.GameObjects.Components.Construction
bool TryProcessStep(ConstructionStep step, IEntity slapped) bool TryProcessStep(ConstructionStep step, IEntity slapped)
{ {
var sound = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
switch (step) switch (step)
{ {
case ConstructionStepMaterial matStep: case ConstructionStepMaterial matStep:
@@ -105,9 +106,9 @@ namespace Content.Server.GameObjects.Components.Construction
return false; return false;
} }
if (matStep.Material == MaterialType.Cable) if (matStep.Material == MaterialType.Cable)
AudioSystem.Play("/Audio/items/zip.ogg", Transform.GridPosition); sound.Play("/Audio/items/zip.ogg", Transform.GridPosition);
else else
AudioSystem.Play("/Audio/items/deconstruct.ogg", Transform.GridPosition); sound.Play("/Audio/items/deconstruct.ogg", Transform.GridPosition);
return true; return true;
case ConstructionStepTool toolStep: case ConstructionStepTool toolStep:
switch (toolStep.Tool) switch (toolStep.Tool)
@@ -115,7 +116,7 @@ namespace Content.Server.GameObjects.Components.Construction
case ToolType.Crowbar: case ToolType.Crowbar:
if (slapped.HasComponent<CrowbarComponent>()) if (slapped.HasComponent<CrowbarComponent>())
{ {
AudioSystem.Play("/Audio/items/crowbar.ogg", Transform.GridPosition); sound.Play("/Audio/items/crowbar.ogg", Transform.GridPosition);
return true; return true;
} }
return false; return false;
@@ -123,16 +124,16 @@ namespace Content.Server.GameObjects.Components.Construction
if (slapped.TryGetComponent(out WelderComponent welder) && welder.TryUse(toolStep.Amount)) if (slapped.TryGetComponent(out WelderComponent welder) && welder.TryUse(toolStep.Amount))
{ {
if (random.NextDouble() > 0.5) if (random.NextDouble() > 0.5)
AudioSystem.Play("/Audio/items/welder.ogg", Transform.GridPosition); sound.Play("/Audio/items/welder.ogg", Transform.GridPosition);
else else
AudioSystem.Play("/Audio/items/welder2.ogg", Transform.GridPosition); sound.Play("/Audio/items/welder2.ogg", Transform.GridPosition);
return true; return true;
} }
return false; return false;
case ToolType.Wrench: case ToolType.Wrench:
if (slapped.HasComponent<WrenchComponent>()) if (slapped.HasComponent<WrenchComponent>())
{ {
AudioSystem.Play("/Audio/items/ratchet.ogg", Transform.GridPosition); sound.Play("/Audio/items/ratchet.ogg", Transform.GridPosition);
return true; return true;
} }
return false; return false;
@@ -140,16 +141,16 @@ namespace Content.Server.GameObjects.Components.Construction
if (slapped.HasComponent<ScrewdriverComponent>()) if (slapped.HasComponent<ScrewdriverComponent>())
{ {
if (random.NextDouble() > 0.5) if (random.NextDouble() > 0.5)
AudioSystem.Play("/Audio/items/screwdriver.ogg", Transform.GridPosition); sound.Play("/Audio/items/screwdriver.ogg", Transform.GridPosition);
else else
AudioSystem.Play("/Audio/items/screwdriver2.ogg", Transform.GridPosition); sound.Play("/Audio/items/screwdriver2.ogg", Transform.GridPosition);
return true; return true;
} }
return false; return false;
case ToolType.Wirecutters: case ToolType.Wirecutters:
if (slapped.HasComponent<WirecutterComponent>()) if (slapped.HasComponent<WirecutterComponent>())
{ {
AudioSystem.Play("/Audio/items/wirecutter.ogg", Transform.GridPosition); sound.Play("/Audio/items/wirecutter.ogg", Transform.GridPosition);
return true; return true;
} }
return false; return false;

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Content.Server.GameObjects.Components.Materials; using Content.Server.GameObjects.Components.Materials;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Construction; using Content.Shared.Construction;
@@ -75,8 +76,7 @@ namespace Content.Server.GameObjects.Components.Construction
// OK WE'RE GOOD CONSTRUCTION STARTED. // OK WE'RE GOOD CONSTRUCTION STARTED.
var entMgr = IoCManager.Resolve<IServerEntityManager>(); var entMgr = IoCManager.Resolve<IServerEntityManager>();
var AudioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>(); IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play("/Audio/items/deconstruct.ogg", loc);
AudioSystem.Play("/Audio/items/deconstruct.ogg", loc);
if (prototype.Stages.Count == 2) if (prototype.Stages.Count == 2)
{ {
// Exactly 2 stages, so don't make an intermediate frame. // Exactly 2 stages, so don't make an intermediate frame.

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Power; using Content.Shared.GameObjects.Components.Power;
using SS14.Server.GameObjects; using SS14.Server.GameObjects;
using SS14.Server.GameObjects.Components.UserInterface; using SS14.Server.GameObjects.Components.UserInterface;
@@ -118,8 +119,7 @@ namespace Content.Server.GameObjects.Components.Power
private void _clickSound() private void _clickSound()
{ {
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>() Owner.GetComponent<SoundComponent>().Play("/Audio/machines/machine_switch.ogg", AudioParams.Default.WithVolume(-2f));
.Play("/Audio/machines/machine_switch.ogg", Owner, AudioParams.Default.WithVolume(-2f));
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects; using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
@@ -150,8 +151,7 @@ namespace Content.Server.GameObjects.Components.Power
if (time > _lastThunk + _thunkDelay) if (time > _lastThunk + _thunkDelay)
{ {
_lastThunk = time; _lastThunk = time;
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>() Owner.GetComponent<SoundComponent>().Play("/Audio/machines/light_tube_on.ogg", AudioParams.Default.WithVolume(-10f));
.Play("/Audio/machines/light_tube_on.ogg", Owner, AudioParams.Default.WithVolume(-10f));
} }
} }
else else

View File

@@ -0,0 +1,72 @@
using System.Collections.Generic;
using Content.Shared.GameObjects.Components.Sound;
using SS14.Server.GameObjects.EntitySystems;
using SS14.Shared.Audio;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
using SS14.Shared.Log;
using SS14.Shared.Map;
using SS14.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Sound
{
public class SoundComponent : SharedSoundComponent
{
/// <summary>
/// Stops all sounds.
/// </summary>
/// <param name="channel">User that will be affected.</param>
public void StopAllSounds(INetChannel channel)
{
SendNetworkMessage(new StopAllSoundsMessage(), channel);
}
/// <summary>
/// Stops a certain scheduled sound from playing.
/// </summary>
/// <param name="channel">User that will be affected.</param>
public void StopScheduledSound(string filename, INetChannel channel)
{
SendNetworkMessage(new StopSoundScheduleMessage(){Filename = filename}, channel);
}
/// <summary>
/// Adds an scheduled sound to be played.
/// </summary>
/// <param name="channel">User that will be affected.</param>
public void AddScheduledSound(ScheduledSound schedule, INetChannel channel)
{
SendNetworkMessage(new ScheduledSoundMessage() {Schedule = schedule}, channel);
}
public override void StopAllSounds()
{
StopAllSounds(null);
}
public override void StopScheduledSound(string filename)
{
StopScheduledSound(filename, null);
}
public override void AddScheduledSound(ScheduledSound schedule)
{
AddScheduledSound(schedule, null);
}
/// <summary>
/// Play an audio file following the entity.
/// </summary>
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
/// <param name="channel">User that will be affected.</param>
public void Play(string filename, AudioParams? audioParams = null, INetChannel channel = null)
{
AddScheduledSound(new ScheduledSound()
{
Filename = filename,
AudioParams = audioParams,
}, channel);
}
}
}

View File

@@ -12,6 +12,7 @@ using SS14.Shared.Maths;
using SS14.Shared.Physics; using SS14.Shared.Physics;
using SS14.Shared.Serialization; using SS14.Shared.Serialization;
using System; using System;
using Content.Server.GameObjects.Components.Sound;
using SS14.Shared.GameObjects; using SS14.Shared.GameObjects;
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
@@ -81,7 +82,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
}; };
var mgr = IoCManager.Resolve<IEntitySystemManager>(); var mgr = IoCManager.Resolve<IEntitySystemManager>();
mgr.GetEntitySystem<EffectSystem>().CreateParticle(message); mgr.GetEntitySystem<EffectSystem>().CreateParticle(message);
mgr.GetEntitySystem<AudioSystem>().Play("/Audio/laser.ogg", Owner, AudioParams.Default.WithVolume(-5)); Owner.GetComponent<SoundComponent>().Play("/Audio/laser.ogg", AudioParams.Default.WithVolume(-5));
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using Content.Server.GameObjects.Components.Sound;
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged; using Content.Shared.GameObjects.Components.Weapons.Ranged;
@@ -110,8 +111,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
if (_magInSound != null) if (_magInSound != null)
{ {
var audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>(); Owner.GetComponent<SoundComponent>().Play(_magInSound);
audioSystem.Play(_magInSound, Owner);
} }
component.OnAmmoCountChanged += _magazineAmmoCountChanged; component.OnAmmoCountChanged += _magazineAmmoCountChanged;
@@ -142,8 +142,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
entity.Transform.GridPosition = Owner.Transform.GridPosition; entity.Transform.GridPosition = Owner.Transform.GridPosition;
if (_magOutSound != null) if (_magOutSound != null)
{ {
var audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>(); Owner.GetComponent<SoundComponent>().Play(_magOutSound);
audioSystem.Play(_magOutSound, Owner);
} }
_updateAppearance(); _updateAppearance();
@@ -163,9 +162,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
var entity = RemoveFromChamber(chamber); var entity = RemoveFromChamber(chamber);
entity.Transform.GridPosition = Owner.Transform.GridPosition; entity.Transform.GridPosition = Owner.Transform.GridPosition;
entity.Transform.LocalRotation = _bulletDropRandom.Pick(_randomBulletDirs).ToAngle(); entity.Transform.LocalRotation = _bulletDropRandom.Pick(_randomBulletDirs).ToAngle();
var audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
var effect = $"/Audio/items/weapons/casingfall{_bulletDropRandom.Next(1, 4)}.ogg"; var effect = $"/Audio/items/weapons/casingfall{_bulletDropRandom.Next(1, 4)}.ogg";
audioSystem.Play(effect, entity, AudioParams.Default.WithVolume(-3)); Owner.GetComponent<SoundComponent>().Play(effect, AudioParams.Default.WithVolume(-3));
if (Magazine != null) if (Magazine != null)
{ {
@@ -181,7 +179,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
EjectMagazine(); EjectMagazine();
if (_autoEjectSound != null) if (_autoEjectSound != null)
{ {
audioSystem.Play(_autoEjectSound, Owner, AudioParams.Default.WithVolume(-5)); Owner.GetComponent<SoundComponent>().Play(_autoEjectSound, AudioParams.Default.WithVolume(-5));
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Sound;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using SS14.Server.Chat; using SS14.Server.Chat;
using SS14.Server.GameObjects.Components.Container; using SS14.Server.GameObjects.Components.Container;
@@ -69,8 +70,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
{ {
if (_soundGunEmpty != null) if (_soundGunEmpty != null)
{ {
var audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>(); Owner.GetComponent<SoundComponent>().Play(_soundGunEmpty);
audioSystem.Play(_soundGunEmpty, Owner);
} }
} }
var chambered = GetChambered(0); var chambered = GetChambered(0);

View File

@@ -1,6 +1,7 @@
using System; using System;
using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Projectiles; using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Sound;
using SS14.Server.GameObjects; using SS14.Server.GameObjects;
using SS14.Server.GameObjects.EntitySystems; using SS14.Server.GameObjects.EntitySystems;
using SS14.Server.Interfaces.GameObjects; using SS14.Server.Interfaces.GameObjects;
@@ -90,7 +91,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
projectile.Transform.LocalRotation = angle.Theta; projectile.Transform.LocalRotation = angle.Theta;
// Sound! // Sound!
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play("/Audio/gunshot_c20.ogg", user); Owner.GetComponent<SoundComponent>().Play("/Audio/gunshot_c20.ogg");
} }
/// <summary> /// <summary>

View File

@@ -72,6 +72,7 @@
<Compile Include="GameObjects\Components\Mobs\SharedCameraRecoilComponent.cs" /> <Compile Include="GameObjects\Components\Mobs\SharedCameraRecoilComponent.cs" />
<Compile Include="GameObjects\Components\Power\PowerShared.cs" /> <Compile Include="GameObjects\Components\Power\PowerShared.cs" />
<Compile Include="GameObjects\Components\Power\SharedPowerCellComponent.cs" /> <Compile Include="GameObjects\Components\Power\SharedPowerCellComponent.cs" />
<Compile Include="GameObjects\Components\Sound\SharedSoundComponent.cs" />
<Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" /> <Compile Include="GameObjects\Components\Storage\SharedStorageComponent.cs" />
<Compile Include="GameObjects\Components\Weapons\Ranged\SharedBallisticMagazineComponent.cs" /> <Compile Include="GameObjects\Components\Weapons\Ranged\SharedBallisticMagazineComponent.cs" />
<Compile Include="GameObjects\Components\Weapons\Ranged\SharedBallisticMagazineWeaponComponent.cs" /> <Compile Include="GameObjects\Components\Weapons\Ranged\SharedBallisticMagazineWeaponComponent.cs" />

View File

@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.IO;
using Content.Shared.GameObjects;
using SS14.Shared.Audio;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Serialization;
using SS14.Shared.IoC;
using SS14.Shared.Map;
using SS14.Shared.Serialization;
using SS14.Shared.Timers;
namespace Content.Shared.GameObjects.Components.Sound
{
public class SharedSoundComponent : Component
{
public override string Name => "Sound";
public override uint? NetID => ContentNetIDs.SOUND;
/// <summary>
/// Stops all sounds.
/// </summary>
public virtual void StopAllSounds()
{}
/// <summary>
/// Stops a certain scheduled sound from playing.
/// </summary>
public virtual void StopScheduledSound(string filename)
{}
/// <summary>
/// Adds an scheduled sound to be played.
/// </summary>
public virtual void AddScheduledSound(ScheduledSound scheduledSound)
{}
/// <summary>
/// Play an audio file following the entity.
/// </summary>
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
public void Play(string filename, AudioParams? audioParams = null)
{
AddScheduledSound(new ScheduledSound()
{
Filename = filename,
AudioParams = audioParams,
});
}
}
[NetSerializable, Serializable]
public class ScheduledSoundMessage : ComponentMessage
{
public ScheduledSound Schedule;
public ScheduledSoundMessage()
{
Directed = true;
}
}
[NetSerializable, Serializable]
public class StopSoundScheduleMessage : ComponentMessage
{
public string Filename;
public StopSoundScheduleMessage()
{
Directed = true;
}
}
[NetSerializable, Serializable]
public class StopAllSoundsMessage : ComponentMessage
{
public StopAllSoundsMessage()
{
Directed = true;
}
}
[Serializable, NetSerializable]
public class ScheduledSound : IExposeData
{
public string Filename = "";
/// <summary>
/// The parameters to play the sound with.
/// </summary>
public AudioParams? AudioParams;
/// <summary>
/// Delay in milliseconds before playing the sound,
/// and delay between repetitions if Times is not 0.
/// </summary>
public uint Delay = 0;
/// <summary>
/// Maximum number of milliseconds to add to the delay randomly.
/// Useful for random ambience noises. Generated value differs from client to client.
/// </summary>
public uint RandomDelay = 0;
/// <summary>
/// How many times to repeat the sound. If it's 0, it will play the sound once.
/// If it's less than 0, it will repeat the sound indefinitely.
/// If it's greater than 0, it will play the sound n+1 times.
/// </summary>
public int Times = 0;
/// <summary>
/// Whether the sound will play or not.
/// </summary>
public bool Play = true;
public void ExposeData(ObjectSerializer serializer)
{
Filename = serializer.ReadDataField("filename", "");
Delay = serializer.ReadDataField("delay", 0u);
RandomDelay = serializer.ReadDataField("randomdelay", 0u);
Times = serializer.ReadDataField("times", 0);
AudioParams = serializer.ReadDataField("audioparams", SS14.Shared.Audio.AudioParams.Default);
}
}
}

View File

@@ -14,5 +14,6 @@
public const uint SPECIES = 1009; public const uint SPECIES = 1009;
public const uint RANGED_WEAPON = 1010; public const uint RANGED_WEAPON = 1010;
public const uint CAMERA_RECOIL = 1011; public const uint CAMERA_RECOIL = 1011;
public const uint SOUND = 1012;
} }
} }

View File

@@ -4,6 +4,7 @@
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: BoundingBox
- type: Sound
- type: Sprite - type: Sprite
sprite: Buildings/light_tube.rsi sprite: Buildings/light_tube.rsi
state: on state: on

View File

@@ -95,6 +95,7 @@
type: ApcBoundUserInterface type: ApcBoundUserInterface
- type: BoundingBox - type: BoundingBox
aabb: -0.25, -0.25, 0.25, 0.3 aabb: -0.25, -0.25, 0.25, 0.3
- type: Sound
- type: entity - type: entity
id: SMES id: SMES

View File

@@ -18,6 +18,7 @@
Size: 24 Size: 24
sprite: Objects/laser_retro.rsi sprite: Objects/laser_retro.rsi
prefix: 100 prefix: 100
- type: Sound
- type: entity - type: entity
name: Spear name: Spear

View File

@@ -11,6 +11,7 @@
- type: Icon - type: Icon
sprite: Objects/c20r.rsi sprite: Objects/c20r.rsi
state: c20r-5 state: c20r-5
- type: Sound
- type: RangedWeapon - type: RangedWeapon
automatic: true automatic: true
firerate: 8 firerate: 8