Ambient sound system (#4552)
* Ambient sound system Client-side system that plays audio from nearby objects that are randomly sampled. * Decent * Tweaks * Tweaks * Comment this out for now * reduce VM sound * Fix rolloff * Fixes * Volume tweak
This commit is contained in:
178
Content.Client/Audio/AmbientSoundSystem.cs
Normal file
178
Content.Client/Audio/AmbientSoundSystem.cs
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Shared.Audio;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Client.Audio
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Samples nearby <see cref="AmbientSoundComponent"/> and plays audio.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
|
||||||
|
{
|
||||||
|
[Dependency] private IEntityLookup _lookup = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
private int _maxAmbientCount;
|
||||||
|
|
||||||
|
private float _maxAmbientRange;
|
||||||
|
private float _cooldown;
|
||||||
|
private float _accumulator;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many times we can be playing 1 particular sound at once.
|
||||||
|
/// </summary>
|
||||||
|
private int _maxSingleSound = 3;
|
||||||
|
|
||||||
|
private Dictionary<AmbientSoundComponent, (IPlayingAudioStream? Stream, string Sound)> _playingSounds = new();
|
||||||
|
|
||||||
|
private const float RangeBuffer = 0.5f;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
var configManager = IoCManager.Resolve<IConfigurationManager>();
|
||||||
|
configManager.OnValueChanged(CCVars.AmbientCooldown, SetCooldown, true);
|
||||||
|
configManager.OnValueChanged(CCVars.MaxAmbientSources, SetAmbientCount, true);
|
||||||
|
configManager.OnValueChanged(CCVars.AmbientRange, SetAmbientRange, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCooldown(float value) => _cooldown = value;
|
||||||
|
private void SetAmbientCount(int value) => _maxAmbientCount = value;
|
||||||
|
private void SetAmbientRange(float value) => _maxAmbientRange = value;
|
||||||
|
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
base.Shutdown();
|
||||||
|
var configManager = IoCManager.Resolve<IConfigurationManager>();
|
||||||
|
configManager.UnsubValueChanged(CCVars.AmbientCooldown, SetCooldown);
|
||||||
|
configManager.UnsubValueChanged(CCVars.MaxAmbientSources, SetAmbientCount);
|
||||||
|
configManager.UnsubValueChanged(CCVars.AmbientRange, SetAmbientRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int PlayingCount(string countSound)
|
||||||
|
{
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
foreach (var (_, (_, sound)) in _playingSounds)
|
||||||
|
{
|
||||||
|
if (sound.Equals(countSound)) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
if (_cooldown <= 0f)
|
||||||
|
{
|
||||||
|
_accumulator = 0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_accumulator += frameTime;
|
||||||
|
if (_accumulator < _cooldown) return;
|
||||||
|
_accumulator -= _cooldown;
|
||||||
|
|
||||||
|
var player = _playerManager.LocalPlayer?.ControlledEntity;
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
ClearSounds();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var coordinates = player.Transform.Coordinates;
|
||||||
|
|
||||||
|
foreach (var (comp, (stream, _)) in _playingSounds.ToArray())
|
||||||
|
{
|
||||||
|
if (!comp.Deleted && comp.Enabled && comp.Owner.Transform.Coordinates.TryDistance(EntityManager, coordinates, out var range) &&
|
||||||
|
range <= comp.Range)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream?.Stop();
|
||||||
|
|
||||||
|
_playingSounds.Remove(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_playingSounds.Count >= _maxAmbientCount) return;
|
||||||
|
|
||||||
|
SampleNearby(coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearSounds()
|
||||||
|
{
|
||||||
|
foreach (var (_, (stream, _)) in _playingSounds)
|
||||||
|
{
|
||||||
|
stream?.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
_playingSounds.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of ambient components in range and determine which ones to start playing.
|
||||||
|
/// </summary>
|
||||||
|
private void SampleNearby(EntityCoordinates coordinates)
|
||||||
|
{
|
||||||
|
var compsInRange = new List<AmbientSoundComponent>();
|
||||||
|
|
||||||
|
foreach (var entity in _lookup.GetEntitiesInRange(coordinates, _maxAmbientRange,
|
||||||
|
LookupFlags.Approximate | LookupFlags.IncludeAnchored))
|
||||||
|
{
|
||||||
|
if (!entity.TryGetComponent(out AmbientSoundComponent? ambientComp) ||
|
||||||
|
_playingSounds.ContainsKey(ambientComp) ||
|
||||||
|
!ambientComp.Enabled ||
|
||||||
|
// We'll also do this crude distance check because it's what we're doing in the active loop above.
|
||||||
|
!entity.Transform.Coordinates.TryDistance(EntityManager, coordinates, out var range) ||
|
||||||
|
range > ambientComp.Range - RangeBuffer)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
compsInRange.Add(ambientComp);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (_playingSounds.Count < _maxAmbientCount)
|
||||||
|
{
|
||||||
|
if (compsInRange.Count == 0) break;
|
||||||
|
|
||||||
|
var comp = _random.PickAndTake(compsInRange);
|
||||||
|
var sound = comp.Sound.GetSound();
|
||||||
|
|
||||||
|
if (PlayingCount(sound) >= _maxSingleSound) continue;
|
||||||
|
|
||||||
|
var audioParams = AudioHelpers
|
||||||
|
.WithVariation(0.01f)
|
||||||
|
.WithVolume(comp.Volume)
|
||||||
|
.WithLoop(true)
|
||||||
|
.WithAttenuation(Attenuation.LinearDistance)
|
||||||
|
// Randomise start so 2 sources don't increase their volume.
|
||||||
|
.WithPlayOffset(_random.NextFloat())
|
||||||
|
.WithMaxDistance(comp.Range);
|
||||||
|
|
||||||
|
var stream = SoundSystem.Play(
|
||||||
|
Filter.Local(),
|
||||||
|
sound,
|
||||||
|
comp.Owner,
|
||||||
|
audioParams);
|
||||||
|
|
||||||
|
if (stream == null) continue;
|
||||||
|
|
||||||
|
_playingSounds[comp] = (stream, sound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,8 +29,8 @@ namespace Content.Client.Audio
|
|||||||
|
|
||||||
private SoundCollectionPrototype _ambientCollection = default!;
|
private SoundCollectionPrototype _ambientCollection = default!;
|
||||||
|
|
||||||
private AudioParams _ambientParams = new(-10f, 1, "Master", 0, 0, true, 0f);
|
private AudioParams _ambientParams = new(-10f, 1, "Master", 0, 0, 0, true, 0f);
|
||||||
private AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, true, 0f);
|
private AudioParams _lobbyParams = new(-5f, 1, "Master", 0, 0, 0, true, 0f);
|
||||||
|
|
||||||
private IPlayingAudioStream? _ambientStream;
|
private IPlayingAudioStream? _ambientStream;
|
||||||
private IPlayingAudioStream? _lobbyStream;
|
private IPlayingAudioStream? _lobbyStream;
|
||||||
|
|||||||
@@ -272,7 +272,8 @@ namespace Content.Client.Entry
|
|||||||
"Advertise",
|
"Advertise",
|
||||||
"PowerNetworkBattery",
|
"PowerNetworkBattery",
|
||||||
"BatteryCharger",
|
"BatteryCharger",
|
||||||
"SpawnItemsOnUse"
|
"SpawnItemsOnUse",
|
||||||
|
"AmbientOnPowered",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
Content.Server/Audio/AmbientOnPoweredComponent.cs
Normal file
14
Content.Server/Audio/AmbientOnPoweredComponent.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Content.Shared.Audio;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Audio
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles <see cref="AmbientSoundComponent"/> on when powered and off when not powered.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public class AmbientOnPoweredComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "AmbientOnPowered";
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Content.Server/Audio/AmbientSoundSystem.cs
Normal file
23
Content.Server/Audio/AmbientSoundSystem.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Shared.Audio;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Audio
|
||||||
|
{
|
||||||
|
public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<AmbientOnPoweredComponent, PowerChangedEvent>(HandlePowerChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandlePowerChange(EntityUid uid, AmbientOnPoweredComponent component, PowerChangedEvent args)
|
||||||
|
{
|
||||||
|
if (!ComponentManager.TryGetComponent<AmbientSoundComponent>(uid, out var ambientSound)) return;
|
||||||
|
if (ambientSound.Enabled == args.Powered) return;
|
||||||
|
ambientSound.Enabled = args.Powered;
|
||||||
|
ambientSound.Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.Acts;
|
using Content.Shared.Acts;
|
||||||
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Gravity;
|
using Content.Shared.Gravity;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -137,6 +138,7 @@ namespace Content.Server.Gravity
|
|||||||
private void MakeBroken()
|
private void MakeBroken()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Broken;
|
_status = GravityGeneratorStatus.Broken;
|
||||||
|
EntitySystem.Get<SharedAmbientSoundSystem>().SetAmbience(Owner.Uid, false);
|
||||||
|
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
||||||
@@ -145,6 +147,7 @@ namespace Content.Server.Gravity
|
|||||||
private void MakeUnpowered()
|
private void MakeUnpowered()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Unpowered;
|
_status = GravityGeneratorStatus.Unpowered;
|
||||||
|
EntitySystem.Get<SharedAmbientSoundSystem>().SetAmbience(Owner.Uid, false);
|
||||||
|
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
||||||
@@ -153,6 +156,7 @@ namespace Content.Server.Gravity
|
|||||||
private void MakeOff()
|
private void MakeOff()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.Off;
|
_status = GravityGeneratorStatus.Off;
|
||||||
|
EntitySystem.Get<SharedAmbientSoundSystem>().SetAmbience(Owner.Uid, false);
|
||||||
|
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, false);
|
||||||
@@ -161,6 +165,7 @@ namespace Content.Server.Gravity
|
|||||||
private void MakeOn()
|
private void MakeOn()
|
||||||
{
|
{
|
||||||
_status = GravityGeneratorStatus.On;
|
_status = GravityGeneratorStatus.On;
|
||||||
|
EntitySystem.Get<SharedAmbientSoundSystem>().SetAmbience(Owner.Uid, true);
|
||||||
|
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
_appearance?.SetData(GravityGeneratorVisuals.State, Status);
|
||||||
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, true);
|
_appearance?.SetData(GravityGeneratorVisuals.CoreVisible, true);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.Hands.Components;
|
|||||||
using Content.Server.Items;
|
using Content.Server.Items;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Temperature.Components;
|
using Content.Server.Temperature.Components;
|
||||||
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Components;
|
using Content.Shared.Damage.Components;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
@@ -226,7 +227,7 @@ namespace Content.Server.Light.Components
|
|||||||
|
|
||||||
if (LightBulb == null) // No light bulb.
|
if (LightBulb == null) // No light bulb.
|
||||||
{
|
{
|
||||||
_currentLit = false;
|
SetLight(false);
|
||||||
powerReceiver.Load = 0;
|
powerReceiver.Load = 0;
|
||||||
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Empty);
|
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Empty);
|
||||||
return;
|
return;
|
||||||
@@ -267,6 +268,7 @@ namespace Content.Server.Light.Components
|
|||||||
private void SetLight(bool value, Color? color = null)
|
private void SetLight(bool value, Color? color = null)
|
||||||
{
|
{
|
||||||
_currentLit = value;
|
_currentLit = value;
|
||||||
|
EntitySystem.Get<SharedAmbientSoundSystem>().SetAmbience(Owner.Uid, value);
|
||||||
|
|
||||||
if (!Owner.TryGetComponent(out PointLightComponent? pointLight)) return;
|
if (!Owner.TryGetComponent(out PointLightComponent? pointLight)) return;
|
||||||
pointLight.Enabled = value;
|
pointLight.Enabled = value;
|
||||||
@@ -327,6 +329,6 @@ namespace Content.Server.Light.Components
|
|||||||
UpdateLight();
|
UpdateLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
46
Content.Shared/Audio/AmbientSoundComponent.cs
Normal file
46
Content.Shared/Audio/AmbientSoundComponent.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Shared.Sound;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Shared.Audio
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[NetworkedComponent]
|
||||||
|
public sealed class AmbientSoundComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "AmbientSound";
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("enabled")]
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
|
||||||
|
[DataField("sound")]
|
||||||
|
public SoundSpecifier Sound = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How far away this ambient sound can potentially be heard.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("range")]
|
||||||
|
public float Range = 2f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies this volume to the sound being played.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("volume")]
|
||||||
|
public float Volume = -10f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class AmbientSoundComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public bool Enabled { get; init; }
|
||||||
|
public float Range { get; init; }
|
||||||
|
public float Volume { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
45
Content.Shared/Audio/SharedAmbientSoundSystem.cs
Normal file
45
Content.Shared/Audio/SharedAmbientSoundSystem.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Audio
|
||||||
|
{
|
||||||
|
public abstract class SharedAmbientSoundSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<AmbientSoundComponent, ComponentGetState>(GetCompState);
|
||||||
|
SubscribeLocalEvent<AmbientSoundComponent, ComponentHandleState>(HandleCompState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAmbience(EntityUid uid, bool value)
|
||||||
|
{
|
||||||
|
// Reason I didn't make this eventbus for the callers is because it seemed a bit silly
|
||||||
|
// trying to account for damageable + powered + toggle, plus we can't just check if it's powered.
|
||||||
|
// So we'll just call it directly for whatever.
|
||||||
|
if (!ComponentManager.TryGetComponent<AmbientSoundComponent>(uid, out var ambience) ||
|
||||||
|
ambience.Enabled == value) return;
|
||||||
|
|
||||||
|
ambience.Enabled = value;
|
||||||
|
ambience.Dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleCompState(EntityUid uid, AmbientSoundComponent component, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not AmbientSoundComponentState state) return;
|
||||||
|
component.Enabled = state.Enabled;
|
||||||
|
component.Range = state.Range;
|
||||||
|
component.Volume = state.Volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetCompState(EntityUid uid, AmbientSoundComponent component, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new AmbientSoundComponentState
|
||||||
|
{
|
||||||
|
Enabled = component.Enabled,
|
||||||
|
Range = component.Range,
|
||||||
|
Volume = component.Volume,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,22 @@ namespace Content.Shared.CCVar
|
|||||||
[CVarDefs]
|
[CVarDefs]
|
||||||
public sealed class CCVars : CVars
|
public sealed class CCVars : CVars
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Ambience
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long we'll wait until re-sampling nearby objects for ambience.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<float> AmbientCooldown =
|
||||||
|
CVarDef.Create("ambience.cooldown", 0.5f, CVar.REPLICATED | CVar.SERVER);
|
||||||
|
|
||||||
|
public static readonly CVarDef<float> AmbientRange =
|
||||||
|
CVarDef.Create("ambience.range", 5f, CVar.REPLICATED | CVar.SERVER);
|
||||||
|
|
||||||
|
public static readonly CVarDef<int> MaxAmbientSources =
|
||||||
|
CVarDef.Create("ambience.max_sounds", 6, CVar.REPLICATED | CVar.SERVER);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status
|
* Status
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace Content.Shared.Light.Component
|
|||||||
[NetworkedComponent]
|
[NetworkedComponent]
|
||||||
public abstract class SharedExpendableLightComponent: Robust.Shared.GameObjects.Component
|
public abstract class SharedExpendableLightComponent: Robust.Shared.GameObjects.Component
|
||||||
{
|
{
|
||||||
public static readonly AudioParams LoopedSoundParams = new(0, 1, "Master", 62.5f, 1, true, 0.3f);
|
public static readonly AudioParams LoopedSoundParams = new(0, 1, "Master", 62.5f, 1, 1, true, 0.3f);
|
||||||
|
|
||||||
public sealed override string Name => "ExpendableLight";
|
public sealed override string Name => "ExpendableLight";
|
||||||
|
|
||||||
|
|||||||
BIN
Resources/Audio/Ambience/Objects/buzzing.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/buzzing.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/emf_buzz.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/emf_buzz.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/engine_hum.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/engine_hum.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/gravity_gen_hum.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/gravity_gen_hum.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/hdd_buzz.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/hdd_buzz.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/light_hum.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/light_hum.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/periodic_beep.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/periodic_beep.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Ambience/Objects/vending_machine_hum.ogg
Normal file
BIN
Resources/Audio/Ambience/Objects/vending_machine_hum.ogg
Normal file
Binary file not shown.
@@ -6,6 +6,10 @@
|
|||||||
placement:
|
placement:
|
||||||
mode: AlignTileAny
|
mode: AlignTileAny
|
||||||
components:
|
components:
|
||||||
|
- type: AmbientSound
|
||||||
|
range: 7
|
||||||
|
sound:
|
||||||
|
path: /Audio/Ambience/Objects/gravity_gen_hum.ogg
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
netsync: false
|
netsync: false
|
||||||
sprite: Structures/Machines/gravity_generator.rsi
|
sprite: Structures/Machines/gravity_generator.rsi
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
description: Just add capitalism!
|
description: Just add capitalism!
|
||||||
abstract: true
|
abstract: true
|
||||||
components:
|
components:
|
||||||
|
- type: AmbientOnPowered
|
||||||
|
- type: AmbientSound
|
||||||
|
volume: -15
|
||||||
|
range: 3
|
||||||
|
sound:
|
||||||
|
path: /Audio/Ambience/Objects/vending_machine_hum.ogg
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Machines/VendingMachines/empty.rsi
|
sprite: Structures/Machines/VendingMachines/empty.rsi
|
||||||
netsync: false
|
netsync: false
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
placement:
|
placement:
|
||||||
mode: SnapgridCenter
|
mode: SnapgridCenter
|
||||||
components:
|
components:
|
||||||
|
#- type: AmbientSound
|
||||||
|
# range: 5
|
||||||
|
# sound:
|
||||||
|
# path: /Audio/Ambience/Objects/engine_hum.ogg
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Physics
|
- type: Physics
|
||||||
|
|||||||
@@ -46,6 +46,9 @@
|
|||||||
placement:
|
placement:
|
||||||
mode: SnapgridCenter
|
mode: SnapgridCenter
|
||||||
components:
|
components:
|
||||||
|
- type: AmbientSound
|
||||||
|
sound:
|
||||||
|
path: /Audio/Ambience/Objects/hdd_buzz.ogg
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: AccessReader
|
- type: AccessReader
|
||||||
access: [["Engineering"]]
|
access: [["Engineering"]]
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
placement:
|
placement:
|
||||||
mode: SnapgridCenter
|
mode: SnapgridCenter
|
||||||
components:
|
components:
|
||||||
|
- type: AmbientSound
|
||||||
|
range: 3
|
||||||
|
sound:
|
||||||
|
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
netsync: false
|
netsync: false
|
||||||
sprite: Structures/Power/smes.rsi
|
sprite: Structures/Power/smes.rsi
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
description: "An unpowered light."
|
description: "An unpowered light."
|
||||||
suffix: Unpowered
|
suffix: Unpowered
|
||||||
components:
|
components:
|
||||||
|
- type: AmbientSound
|
||||||
|
volume: -12
|
||||||
|
sound:
|
||||||
|
path: /Audio/Ambience/Objects/light_hum.ogg
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Construction
|
- type: Construction
|
||||||
|
|||||||
Reference in New Issue
Block a user