Ambient loops (#323)
* ambient loop systems * audio content * Update ContentAudioSystem.CP14AmbientLoop.cs * Update attributions.yml * limit frequency * Update CP14AmbientLoopPrototype.cs * Create IsDaylight.cs * fix problem
This commit is contained in:
@@ -117,6 +117,7 @@ public sealed partial class ContentAudioSystem
|
||||
|
||||
private void OnRoundEndMessage(RoundEndMessageEvent ev)
|
||||
{
|
||||
OnRoundEndMessageAmbientLoop(); //CP14
|
||||
// If scoreboard shows then just stop the music
|
||||
_ambientMusicStream = _audio.Stop(_ambientMusicStream);
|
||||
_nextAudio = TimeSpan.FromMinutes(3);
|
||||
|
||||
122
Content.Client/Audio/ContentAudioSystem.CP14AmbientLoop.cs
Normal file
122
Content.Client/Audio/ContentAudioSystem.CP14AmbientLoop.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Client.Audio;
|
||||
|
||||
public sealed partial class ContentAudioSystem
|
||||
{
|
||||
private const float AmbientLoopFadeInTime = 1f;
|
||||
private const float AmbientLoopFadeOutTime = 4f;
|
||||
|
||||
private Dictionary<CP14AmbientLoopPrototype, EntityUid> _loopStreams = new();
|
||||
|
||||
private TimeSpan _nextUpdateTime = TimeSpan.Zero;
|
||||
private readonly TimeSpan _updateFrequency = TimeSpan.FromSeconds(1f);
|
||||
|
||||
private void CP14InitializeAmbientLoops()
|
||||
{
|
||||
Subs.CVar(_configManager, CCVars.AmbientMusicVolume, AmbienceCVarChangedAmbientMusic, true);
|
||||
}
|
||||
|
||||
private void AmbienceCVarChangedAmbientMusic(float obj)
|
||||
{
|
||||
_volumeSlider = SharedAudioSystem.GainToVolume(obj);
|
||||
|
||||
foreach (var loop in _loopStreams)
|
||||
{
|
||||
_audio.SetVolume(loop.Value, loop.Key.Sound.Params.Volume + _volumeSlider);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoundEndMessageAmbientLoop()
|
||||
{
|
||||
foreach (var loop in _loopStreams)
|
||||
{
|
||||
StopAmbientLoop(loop.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private void CP14UpdateAmbientLoops()
|
||||
{
|
||||
if (_timing.CurTime <= _nextUpdateTime)
|
||||
return;
|
||||
|
||||
_nextUpdateTime = _timing.CurTime + _updateFrequency;
|
||||
|
||||
|
||||
if (_state.CurrentState is not GameplayState)
|
||||
return;
|
||||
|
||||
var requiredLoops = GetAmbientLoops();
|
||||
|
||||
foreach (var loop in _loopStreams)
|
||||
{
|
||||
if (!requiredLoops.Contains(loop.Key)) //If ambient is playing and it shouldn't, stop it.
|
||||
StopAmbientLoop(loop.Key);
|
||||
}
|
||||
|
||||
foreach (var loop in requiredLoops)
|
||||
{
|
||||
if (!_loopStreams.ContainsKey(loop)) //If it's not playing, but should, run it
|
||||
StartAmbientLoop(loop);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartAmbientLoop(CP14AmbientLoopPrototype proto)
|
||||
{
|
||||
if (_loopStreams.ContainsKey(proto))
|
||||
return;
|
||||
|
||||
var newLoop = _audio.PlayGlobal(
|
||||
proto.Sound,
|
||||
Filter.Local(),
|
||||
false,
|
||||
AudioParams.Default
|
||||
.WithLoop(true)
|
||||
.WithVolume(proto.Sound.Params.Volume + _volumeSlider)
|
||||
.WithPlayOffset(_random.NextFloat(0f, 100f)));
|
||||
_loopStreams.Add(proto, newLoop.Value.Entity);
|
||||
|
||||
FadeIn(newLoop.Value.Entity, newLoop.Value.Component, AmbientLoopFadeInTime);
|
||||
}
|
||||
|
||||
private void StopAmbientLoop(CP14AmbientLoopPrototype proto)
|
||||
{
|
||||
if (!_loopStreams.TryGetValue(proto, out var audioEntity))
|
||||
return;
|
||||
|
||||
FadeOut(audioEntity, duration: AmbientLoopFadeOutTime);
|
||||
_loopStreams.Remove(proto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the player's environment, and returns a list of all ambients that should currently be playing around the player
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<CP14AmbientLoopPrototype> GetAmbientLoops()
|
||||
{
|
||||
List<CP14AmbientLoopPrototype> list = new();
|
||||
|
||||
var player = _player.LocalEntity;
|
||||
|
||||
if (player == null)
|
||||
return list;
|
||||
|
||||
var ambientLoops = _proto.EnumeratePrototypes<CP14AmbientLoopPrototype>().ToList();
|
||||
|
||||
foreach (var loop in ambientLoops)
|
||||
{
|
||||
if (_rules.IsTrue(player.Value, _proto.Index(loop.Rules)))
|
||||
{
|
||||
list.Add(loop);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -29,13 +29,14 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
||||
public const float AmbientMusicMultiplier = 3f;
|
||||
public const float LobbyMultiplier = 3f;
|
||||
public const float InterfaceMultiplier = 2f;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
UpdatesOutsidePrediction = true;
|
||||
InitializeAmbientMusic();
|
||||
CP14InitializeAmbientLoops(); //CP14 ambient loops
|
||||
InitializeLobbyMusic();
|
||||
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||
}
|
||||
@@ -82,6 +83,7 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
|
||||
return;
|
||||
|
||||
UpdateAmbientMusic();
|
||||
CP14UpdateAmbientLoops(); //CP14
|
||||
UpdateLobbyMusic();
|
||||
UpdateFades(frameTime);
|
||||
}
|
||||
|
||||
20
Content.Shared/Audio/CP14AmbientLoopPrototype.cs
Normal file
20
Content.Shared/Audio/CP14AmbientLoopPrototype.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Content.Shared.Random.Rules;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Audio;
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a rules prototype to sound files to play ambience.
|
||||
/// </summary>
|
||||
[Prototype("ambientLoop")]
|
||||
public sealed partial class CP14AmbientLoopPrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = string.Empty;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("sound", required: true)]
|
||||
public SoundSpecifier Sound = default!;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("rules", required: true)]
|
||||
public ProtoId<RulesPrototype> Rules = string.Empty;
|
||||
}
|
||||
19
Content.Shared/_CP14/Random/Rules/IsDaylight.cs
Normal file
19
Content.Shared/_CP14/Random/Rules/IsDaylight.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Content.Shared._CP14.DayCycle;
|
||||
using Content.Shared.Random.Rules;
|
||||
|
||||
namespace Content.Shared._CP14.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the attached entity is in space.
|
||||
/// </summary>
|
||||
public sealed partial class IsDaylight : RulesRule
|
||||
{
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var dayCycle = entManager.System<CP14DayCycleSystem>();
|
||||
|
||||
//черт, нужны комиты из ветки фермерства
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
9
Resources/Audio/_CP14/Ambience/Loops/attributions.yml
Normal file
9
Resources/Audio/_CP14/Ambience/Loops/attributions.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
- files: ["grasslands.ogg"]
|
||||
license: "CC-BY-NC-4.0"
|
||||
copyright: 'by jgrzinich of Freesound.org.'
|
||||
source: "https://freesound.org/people/jgrzinich/sounds/329805/"
|
||||
|
||||
- files: ["water.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: 'by jackthemurray of Freesound.org.'
|
||||
source: "https://freesound.org/people/jackthemurray/sounds/433589/"
|
||||
BIN
Resources/Audio/_CP14/Ambience/Loops/grasslands.ogg
Normal file
BIN
Resources/Audio/_CP14/Ambience/Loops/grasslands.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Ambience/Loops/water.ogg
Normal file
BIN
Resources/Audio/_CP14/Ambience/Loops/water.ogg
Normal file
Binary file not shown.
@@ -65,4 +65,5 @@
|
||||
deleteSpawnerAfterSpawn: false
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
- HideContextMenu
|
||||
- CP14AmbientWater
|
||||
50
Resources/Prototypes/_CP14/audio_loops.yml
Normal file
50
Resources/Prototypes/_CP14/audio_loops.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
- type: ambientLoop
|
||||
id: Grasslands
|
||||
sound:
|
||||
params:
|
||||
volume: -3
|
||||
collection: CP14LoopGrassland
|
||||
rules: NearGrass
|
||||
|
||||
- type: ambientLoop
|
||||
id: Water
|
||||
sound:
|
||||
params:
|
||||
volume: 18
|
||||
collection: CP14LoopWater
|
||||
rules: NearWater
|
||||
|
||||
# Sound collections
|
||||
- type: soundCollection
|
||||
id: CP14LoopGrassland
|
||||
files:
|
||||
- /Audio/_CP14/Ambience/Loops/grasslands.ogg
|
||||
|
||||
- type: soundCollection
|
||||
id: CP14LoopWater
|
||||
files:
|
||||
- /Audio/_CP14/Ambience/Loops/water.ogg
|
||||
|
||||
# Rules
|
||||
- type: rules
|
||||
id: NearGrass
|
||||
rules:
|
||||
- !type:NearbyTilesPercentRule
|
||||
ignoreAnchored: true
|
||||
percent: 0.5
|
||||
tiles:
|
||||
- CP14FloorGrass
|
||||
- CP14FloorGrassLight
|
||||
- CP14FloorGrassTall
|
||||
range: 5
|
||||
|
||||
- type: rules
|
||||
id: NearWater
|
||||
rules:
|
||||
- !type:NearbyEntitiesRule
|
||||
count: 5
|
||||
whitelist:
|
||||
tags:
|
||||
- CP14AmbientWater
|
||||
range: 4
|
||||
35
Resources/Prototypes/_CP14/audio_music.yml
Normal file
35
Resources/Prototypes/_CP14/audio_music.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
# 4 Priority - Special
|
||||
|
||||
# 3 Priority - Departments
|
||||
|
||||
# 2 Priority - General areas
|
||||
|
||||
## Fallback if nothing else found
|
||||
- type: ambientMusic
|
||||
id: CP14Cave
|
||||
sound:
|
||||
params:
|
||||
volume: -12
|
||||
collection: CP14AmbienceCave
|
||||
rules: AlwaysTrue
|
||||
|
||||
# Sound collections
|
||||
- type: soundCollection
|
||||
id: CP14AmbienceCave
|
||||
files:
|
||||
- /Audio/Ambience/ambilava1.ogg
|
||||
- /Audio/Ambience/ambilava2.ogg
|
||||
- /Audio/Ambience/ambimystery.ogg
|
||||
- /Audio/Ambience/ambiruin.ogg
|
||||
- /Audio/Ambience/ambiruin4.ogg
|
||||
- /Audio/Ambience/maintambience.ogg
|
||||
- /Audio/_CP14/Ambience/ambicave1.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy1.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy2.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy3.ogg
|
||||
|
||||
# Rules
|
||||
- type: rules
|
||||
id: AlwaysTrue
|
||||
rules:
|
||||
- !type:AlwaysTrueRule
|
||||
@@ -24,3 +24,6 @@
|
||||
|
||||
- type: Tag
|
||||
id: CP14Bottles
|
||||
|
||||
- type: Tag
|
||||
id: CP14AmbientWater
|
||||
|
||||
@@ -1,35 +1 @@
|
||||
# 4 Priority - Special
|
||||
|
||||
# 3 Priority - Departments
|
||||
|
||||
# 2 Priority - General areas
|
||||
|
||||
## Fallback if nothing else found
|
||||
- type: ambientMusic
|
||||
id: CP14Cave
|
||||
sound:
|
||||
params:
|
||||
volume: -12
|
||||
collection: CP14AmbienceCave
|
||||
rules: AlwaysTrue
|
||||
|
||||
# Sound collections
|
||||
- type: soundCollection
|
||||
id: CP14AmbienceCave
|
||||
files:
|
||||
- /Audio/Ambience/ambilava1.ogg
|
||||
- /Audio/Ambience/ambilava2.ogg
|
||||
- /Audio/Ambience/ambimystery.ogg
|
||||
- /Audio/Ambience/ambiruin.ogg
|
||||
- /Audio/Ambience/ambiruin4.ogg
|
||||
- /Audio/Ambience/maintambience.ogg
|
||||
- /Audio/_CP14/Ambience/ambicave1.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy1.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy2.ogg
|
||||
- /Audio/_CP14/Ambience/ambicreepy3.ogg
|
||||
|
||||
# Rules
|
||||
- type: rules
|
||||
id: AlwaysTrue
|
||||
rules:
|
||||
- !type:AlwaysTrueRule
|
||||
# Not used in CP14
|
||||
Reference in New Issue
Block a user