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:
Ed
2024-07-15 23:18:14 +03:00
committed by GitHub
parent c69fff0bb9
commit 2de26baebd
13 changed files with 265 additions and 37 deletions

View File

@@ -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);

View 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;
}
}

View File

@@ -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);
}

View 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;
}

View 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;
}
}

View 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/"

Binary file not shown.

Binary file not shown.

View File

@@ -65,4 +65,5 @@
deleteSpawnerAfterSpawn: false
- type: Tag
tags:
- HideContextMenu
- HideContextMenu
- CP14AmbientWater

View 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

View 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

View File

@@ -24,3 +24,6 @@
- type: Tag
id: CP14Bottles
- type: Tag
id: CP14AmbientWater

View File

@@ -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