SoundSystem Improvements (#1649)

This commit is contained in:
Acruid
2021-03-21 16:35:52 +01:00
committed by GitHub
parent 65a42f9209
commit 92f44b390e
3 changed files with 97 additions and 169 deletions
@@ -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 &&
+83 -11
View File
@@ -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);
}