mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-15 14:52:35 +02:00
SoundSystem Improvements (#1649)
This commit is contained in:
@@ -193,7 +193,7 @@ namespace Robust.Client.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream? Play(string filename, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream? Play(string filename, AudioParams? audioParams = null)
|
||||
{
|
||||
if (_resourceCache.TryGetResource<AudioResource>(new ResourcePath(filename), out var audio))
|
||||
{
|
||||
@@ -209,7 +209,7 @@ namespace Robust.Client.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="stream">The audio stream to play.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream Play(AudioStream stream, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream Play(AudioStream stream, AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
ApplyAudioParams(audioParams, source);
|
||||
@@ -231,7 +231,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="entity">The entity "emitting" the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream? Play(string filename, IEntity entity, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream? Play(string filename, IEntity entity, AudioParams? audioParams = null)
|
||||
{
|
||||
if (_resourceCache.TryGetResource<AudioResource>(new ResourcePath(filename), out var audio))
|
||||
{
|
||||
@@ -248,7 +248,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="stream">The audio stream to play.</param>
|
||||
/// <param name="entity">The entity "emitting" the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream? Play(AudioStream stream, IEntity entity, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream? Play(AudioStream stream, IEntity entity, AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
if (!source.SetPosition(entity.Transform.WorldPosition))
|
||||
@@ -277,7 +277,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="coordinates">The coordinates at which to play the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream? Play(string filename, EntityCoordinates coordinates, AudioParams? audioParams = null)
|
||||
private IPlayingAudioStream? Play(string filename, EntityCoordinates coordinates, AudioParams? audioParams = null)
|
||||
{
|
||||
if (_resourceCache.TryGetResource<AudioResource>(new ResourcePath(filename), out var audio))
|
||||
{
|
||||
@@ -294,7 +294,7 @@ namespace Robust.Client.GameObjects
|
||||
/// <param name="stream">The audio stream to play.</param>
|
||||
/// <param name="coordinates">The coordinates at which to play the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
public IPlayingAudioStream? Play(AudioStream stream, EntityCoordinates coordinates,
|
||||
private IPlayingAudioStream? Play(AudioStream stream, EntityCoordinates coordinates,
|
||||
AudioParams? audioParams = null)
|
||||
{
|
||||
var source = _clyde.CreateAudioSource(stream);
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Server.Player;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Players;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AudioSystem : EntitySystem, IAudioSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
private const int AudioDistanceRange = 25;
|
||||
|
||||
private uint _streamIndex;
|
||||
@@ -66,147 +63,6 @@ namespace Robust.Server.GameObjects
|
||||
return unchecked(_streamIndex++);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play an audio file globally, without position.
|
||||
/// </summary>
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
/// <param name="predicate">The predicate that will be used to send the audio to players, or null to send to everyone.</param>
|
||||
/// <param name="excludedSession">Session that won't receive the audio message.</param>
|
||||
/// <param name="recipients"></param>
|
||||
[Obsolete("Use the Play() overload.")]
|
||||
public IPlayingAudioStream PlayGlobal(string filename, AudioParams? audioParams = null, Func<IPlayerSession, bool>? predicate = null, IPlayerSession? excludedSession = null)
|
||||
{
|
||||
var id = CacheIdentifier();
|
||||
var msg = new PlayAudioGlobalMessage
|
||||
{
|
||||
FileName = filename,
|
||||
AudioParams = audioParams ?? AudioParams.Default,
|
||||
Identifier = id
|
||||
};
|
||||
|
||||
if (predicate == null && excludedSession == null)
|
||||
{
|
||||
RaiseNetworkEvent(msg);
|
||||
return new AudioSourceServer(this, id);
|
||||
}
|
||||
|
||||
IList<IPlayerSession> players = predicate != null ? _playerManager.GetPlayersBy(predicate) : _playerManager.GetAllPlayers();
|
||||
|
||||
for (var i = players.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var player = players[i];
|
||||
if (player == excludedSession)
|
||||
{
|
||||
players.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
RaiseNetworkEvent(msg, player.ConnectedClient);
|
||||
}
|
||||
|
||||
return new AudioSourceServer(this, id, players);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play an audio file following an entity.
|
||||
/// </summary>
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="entity">The entity "emitting" the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
/// <param name="range">The max range at which the audio will be heard. Less than or equal to 0 to send to every player.</param>
|
||||
/// <param name="excludedSession">Sessions that won't receive the audio message.</param>
|
||||
[Obsolete("Use the Play() overload.")]
|
||||
public IPlayingAudioStream PlayFromEntity(string filename, IEntity entity, AudioParams? audioParams = null, int range = AudioDistanceRange, IPlayerSession? excludedSession = null)
|
||||
{
|
||||
var id = CacheIdentifier();
|
||||
|
||||
var msg = new PlayAudioEntityMessage
|
||||
{
|
||||
FileName = filename,
|
||||
Coordinates = entity.Transform.Coordinates,
|
||||
EntityUid = entity.Uid,
|
||||
AudioParams = audioParams ?? AudioParams.Default,
|
||||
Identifier = id,
|
||||
};
|
||||
|
||||
// send to every player
|
||||
if (range <= 0 && excludedSession == null)
|
||||
{
|
||||
RaiseNetworkEvent(msg);
|
||||
return new AudioSourceServer(this, id);
|
||||
}
|
||||
|
||||
List<IPlayerSession> players;
|
||||
|
||||
if (range > 0.0f)
|
||||
players = _playerManager.GetPlayersInRange(entity.Transform.Coordinates, range);
|
||||
else
|
||||
players = _playerManager.GetAllPlayers();
|
||||
|
||||
for (var i = players.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var player = players[i];
|
||||
if (player == excludedSession)
|
||||
{
|
||||
players.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
RaiseNetworkEvent(msg, player.ConnectedClient);
|
||||
}
|
||||
|
||||
return new AudioSourceServer(this, id, players);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play an audio file at a static position.
|
||||
/// </summary>
|
||||
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
|
||||
/// <param name="coordinates">The coordinates at which to play the audio.</param>
|
||||
/// <param name="audioParams"></param>
|
||||
/// <param name="range">The max range at which the audio will be heard. Less than or equal to 0 to send to every player.</param>
|
||||
/// <param name="excludedSession">Session that won't receive the audio message.</param>
|
||||
[Obsolete("Use the Play() overload.")]
|
||||
public IPlayingAudioStream PlayAtCoords(string filename, EntityCoordinates coordinates, AudioParams? audioParams = null, int range = AudioDistanceRange, IPlayerSession? excludedSession = null)
|
||||
{
|
||||
var id = CacheIdentifier();
|
||||
var msg = new PlayAudioPositionalMessage
|
||||
{
|
||||
FileName = filename,
|
||||
Coordinates = coordinates,
|
||||
AudioParams = audioParams ?? AudioParams.Default,
|
||||
Identifier = id
|
||||
};
|
||||
|
||||
if (range <= 0 && excludedSession == null)
|
||||
{
|
||||
RaiseNetworkEvent(msg);
|
||||
return new AudioSourceServer(this, id);
|
||||
}
|
||||
|
||||
List<IPlayerSession> players;
|
||||
|
||||
if (range > 0.0f)
|
||||
players = _playerManager.GetPlayersInRange(coordinates, range);
|
||||
else
|
||||
players = _playerManager.GetAllPlayers();
|
||||
|
||||
for (var i = players.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var player = players[i];
|
||||
if (player == excludedSession)
|
||||
{
|
||||
players.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
RaiseNetworkEvent(msg, player.ConnectedClient);
|
||||
}
|
||||
|
||||
return new AudioSourceServer(this, id, players);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultSoundRange => AudioDistanceRange;
|
||||
|
||||
@@ -214,7 +70,7 @@ namespace Robust.Server.GameObjects
|
||||
public int OcclusionCollisionMask { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, AudioParams? audioParams = null)
|
||||
public IPlayingAudioStream Play(Filter playerFilter, string filename, AudioParams? audioParams = null)
|
||||
{
|
||||
var id = CacheIdentifier();
|
||||
var msg = new PlayAudioGlobalMessage
|
||||
@@ -234,7 +90,7 @@ namespace Robust.Server.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, IEntity entity, AudioParams? audioParams = null)
|
||||
public IPlayingAudioStream Play(Filter playerFilter, string filename, IEntity entity, AudioParams? audioParams = null)
|
||||
{
|
||||
//TODO: Calculate this from PAS
|
||||
var range = audioParams is null || audioParams.Value.MaxDistance <= 0 ? AudioDistanceRange : audioParams.Value.MaxDistance;
|
||||
@@ -254,7 +110,7 @@ namespace Robust.Server.GameObjects
|
||||
var recipients = (playerFilter as IFilter).Recipients;
|
||||
|
||||
if (range > 0.0f)
|
||||
players = PASInRange(recipients, entity.Transform.MapPosition, range);
|
||||
players = PasInRange(recipients, entity.Transform.MapPosition, range);
|
||||
else
|
||||
players = recipients;
|
||||
|
||||
@@ -267,7 +123,7 @@ namespace Robust.Server.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPlayingAudioStream? Play(Filter playerFilter, string filename, EntityCoordinates coordinates, AudioParams? audioParams = null)
|
||||
public IPlayingAudioStream Play(Filter playerFilter, string filename, EntityCoordinates coordinates, AudioParams? audioParams = null)
|
||||
{
|
||||
//TODO: Calculate this from PAS
|
||||
var range = audioParams is null || audioParams.Value.MaxDistance <= 0 ? AudioDistanceRange : audioParams.Value.MaxDistance;
|
||||
@@ -285,7 +141,7 @@ namespace Robust.Server.GameObjects
|
||||
var recipients = (playerFilter as IFilter).Recipients;
|
||||
|
||||
if (range > 0.0f)
|
||||
players = PASInRange(recipients, coordinates.ToMap(EntityManager), range);
|
||||
players = PasInRange(recipients, coordinates.ToMap(EntityManager), range);
|
||||
else
|
||||
players = recipients;
|
||||
|
||||
@@ -297,7 +153,7 @@ namespace Robust.Server.GameObjects
|
||||
return new AudioSourceServer(this, id, players);
|
||||
}
|
||||
|
||||
private static List<ICommonSession> PASInRange(IEnumerable<ICommonSession> players, MapCoordinates position, float range)
|
||||
private static List<ICommonSession> PasInRange(IEnumerable<ICommonSession> players, MapCoordinates position, float range)
|
||||
{
|
||||
return players.Where(x =>
|
||||
x.AttachedEntity != null &&
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -37,7 +39,7 @@ namespace Robust.Shared.Player
|
||||
[PublicAPI]
|
||||
public class Filter : IFilter
|
||||
{
|
||||
private bool _prediction;
|
||||
private bool _prediction = true;
|
||||
private List<ICommonSession> _recipients = new();
|
||||
private bool _reliable;
|
||||
|
||||
@@ -59,14 +61,51 @@ namespace Robust.Shared.Player
|
||||
/// <summary>
|
||||
/// Adds all players inside an entity's PVS.
|
||||
/// </summary>
|
||||
protected Filter AddPlayersByPvs(Vector2 origin)
|
||||
protected Filter AddPlayersByPvs(IEntity origin)
|
||||
{
|
||||
// Calculate this from the PVS system that does not exist.
|
||||
throw new NotImplementedException();
|
||||
|
||||
//return this;
|
||||
return AddPlayersByPvs(origin.Transform.MapPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all players inside an entity's PVS.
|
||||
/// </summary>
|
||||
protected Filter AddPlayersByPvs(ITransformComponent origin)
|
||||
{
|
||||
return AddPlayersByPvs(origin.MapPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all players inside an entity's PVS.
|
||||
/// </summary>
|
||||
protected Filter AddPlayersByPvs(EntityCoordinates origin)
|
||||
{
|
||||
var entityMan = IoCManager.Resolve<IEntityManager>();
|
||||
return AddPlayersByPvs(origin.ToMap(entityMan));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all players inside an entity's PVS.
|
||||
/// </summary>
|
||||
protected Filter AddPlayersByPvs(MapCoordinates origin)
|
||||
{
|
||||
//TODO: Calculate this from the PVS system that does not exist.
|
||||
var playerMan = IoCManager.Resolve<ISharedPlayerManager>();
|
||||
|
||||
const int range = 25;
|
||||
var players = playerMan.NetworkedSessions.Where(x =>
|
||||
x.AttachedEntity != null && origin.InRange(x.AttachedEntity.Transform.MapPosition, range));
|
||||
|
||||
foreach (var session in players)
|
||||
{
|
||||
AddPlayer(session);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a set of players to the filter.
|
||||
/// </summary>
|
||||
public Filter AddPlayers(IEnumerable<ICommonSession> players)
|
||||
{
|
||||
foreach (var player in players)
|
||||
@@ -98,6 +137,9 @@ namespace Robust.Shared.Player
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all players from the filter that match a predicate.
|
||||
/// </summary>
|
||||
public Filter RemoveWhere(Predicate<ICommonSession> predicate)
|
||||
{
|
||||
for (int i = 0; i < _recipients.Count; i++)
|
||||
@@ -114,6 +156,9 @@ namespace Robust.Shared.Player
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all players that match a predicate.
|
||||
/// </summary>
|
||||
public Filter AddWhere(Predicate<ICommonSession> predicate)
|
||||
{
|
||||
var playerMan = IoCManager.Resolve<ISharedPlayerManager>();
|
||||
@@ -129,11 +174,13 @@ namespace Robust.Shared.Player
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This filter will properly be handled by prediction.
|
||||
/// Normally a filter will properly handle client side prediction. Calling this
|
||||
/// function disables that, and the event will be spammed during every prediction
|
||||
/// tick.
|
||||
/// </summary>
|
||||
public Filter HandlePrediction()
|
||||
public Filter Unpredicted()
|
||||
{
|
||||
_prediction = true;
|
||||
_prediction = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -171,10 +218,35 @@ namespace Robust.Shared.Player
|
||||
return Empty().AddAllPlayers();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A filter with every player who's PVS overlaps this entity.
|
||||
/// </summary>
|
||||
public static Filter Pvs(IEntity origin)
|
||||
{
|
||||
return Empty().AddPlayersByPvs(origin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A filter with every player who's PVS overlaps this point.
|
||||
/// </summary>
|
||||
public static Filter Pvs(Vector2 origin)
|
||||
public static Filter Pvs(ITransformComponent origin)
|
||||
{
|
||||
return Empty().AddPlayersByPvs(origin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A filter with every player who's PVS overlaps this point.
|
||||
/// </summary>
|
||||
public static Filter Pvs(EntityCoordinates origin)
|
||||
{
|
||||
return Empty().AddPlayersByPvs(origin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A filter with every player who's PVS overlaps this point.
|
||||
/// </summary>
|
||||
public static Filter Pvs(MapCoordinates origin)
|
||||
{
|
||||
return Empty().AddPlayersByPvs(origin);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user