mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Make PVS overrides less bad and fix audio (#4656)
This commit is contained in:
@@ -37,6 +37,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IParallelManager _parMan = default!;
|
||||
[Dependency] private readonly IRuntimeLog _runtimeLog = default!;
|
||||
[Dependency] private readonly IAudioInternal _audio = default!;
|
||||
@@ -112,20 +113,6 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
}
|
||||
}
|
||||
|
||||
internal bool TryGetGlobalAudioMap([NotNullWhen(true)] out EntityUid? uid)
|
||||
{
|
||||
var query = EntityQueryEnumerator<GlobalAudioMapComponent>();
|
||||
|
||||
while (query.MoveNext(out var vUid, out _))
|
||||
{
|
||||
uid = vUid;
|
||||
return true;
|
||||
}
|
||||
|
||||
uid = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume for the entire game.
|
||||
/// </summary>
|
||||
@@ -233,14 +220,12 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
_streams.Add((uid, comp, xform));
|
||||
}
|
||||
|
||||
MapManager.TryFindGridAt(ourPos, out var gridUid, out _);
|
||||
_mapManager.TryFindGridAt(ourPos, out var gridUid, out _);
|
||||
_listenerGrid = gridUid == EntityUid.Invalid ? null : gridUid;
|
||||
TryGetGlobalAudioMap(out var globalUid);
|
||||
|
||||
try
|
||||
{
|
||||
_updateAudioJob.OurPosition = ourPos;
|
||||
_updateAudioJob.GlobalAudioMap = globalUid;
|
||||
_parMan.ProcessNow(_updateAudioJob, _streams.Count);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -255,7 +240,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
return _eyeManager.CurrentEye.Position;
|
||||
}
|
||||
|
||||
private void ProcessStream(EntityUid entity, AudioComponent component, TransformComponent xform, MapCoordinates listener, EntityUid? globalAudioMap)
|
||||
private void ProcessStream(EntityUid entity, AudioComponent component, TransformComponent xform, MapCoordinates listener)
|
||||
{
|
||||
// TODO:
|
||||
// I Originally tried to be fancier here but it caused audio issues so just trying
|
||||
@@ -269,7 +254,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
// If it's global but on another map (that isn't nullspace) then stop playing it.
|
||||
if (component.Global)
|
||||
{
|
||||
if (xform.MapUid != globalAudioMap && listener.MapId != xform.MapID)
|
||||
if (xform.MapID != MapId.Nullspace && listener.MapId != xform.MapID)
|
||||
{
|
||||
component.Gain = 0f;
|
||||
return;
|
||||
@@ -466,15 +451,11 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
/// <param name="audioParams"></param>
|
||||
private (EntityUid Entity, AudioComponent Component)? PlayGlobal(AudioStream stream, AudioParams? audioParams = null)
|
||||
{
|
||||
var audio = CreateAndStartPlayingStream(audioParams, stream);
|
||||
|
||||
if (audio == null)
|
||||
return null;
|
||||
|
||||
audio.Value.Component.Global = true;
|
||||
audio.Value.Component.Source.Global = true;
|
||||
Dirty(audio.Value.Entity, audio.Value.Component);
|
||||
return (audio.Value.Entity, audio.Value.Component);
|
||||
var (entity, component) = CreateAndStartPlayingStream(audioParams, stream);
|
||||
component.Global = true;
|
||||
component.Source.Global = true;
|
||||
Dirty(entity, component);
|
||||
return (entity, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -506,11 +487,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
private (EntityUid Entity, AudioComponent Component)? PlayEntity(AudioStream stream, EntityUid entity, AudioParams? audioParams = null)
|
||||
{
|
||||
var playing = CreateAndStartPlayingStream(audioParams, stream);
|
||||
|
||||
if (playing == null)
|
||||
return null;
|
||||
|
||||
_xformSys.SetCoordinates(playing.Value.Entity, new EntityCoordinates(entity, Vector2.Zero));
|
||||
_xformSys.SetCoordinates(playing.Entity, new EntityCoordinates(entity, Vector2.Zero));
|
||||
|
||||
return playing;
|
||||
}
|
||||
@@ -545,11 +522,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
private (EntityUid Entity, AudioComponent Component)? PlayStatic(AudioStream stream, EntityCoordinates coordinates, AudioParams? audioParams = null)
|
||||
{
|
||||
var playing = CreateAndStartPlayingStream(audioParams, stream);
|
||||
|
||||
if (playing == null)
|
||||
return null;
|
||||
|
||||
_xformSys.SetCoordinates(playing.Value.Entity, coordinates);
|
||||
_xformSys.SetCoordinates(playing.Entity, coordinates);
|
||||
return playing;
|
||||
}
|
||||
|
||||
@@ -607,13 +580,10 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
return PlayStatic(filename, coordinates, audioParams);
|
||||
}
|
||||
|
||||
private (EntityUid Entity, AudioComponent Component)? CreateAndStartPlayingStream(AudioParams? audioParams, AudioStream stream)
|
||||
private (EntityUid Entity, AudioComponent Component) CreateAndStartPlayingStream(AudioParams? audioParams, AudioStream stream)
|
||||
{
|
||||
if (!TryGetGlobalAudioMap(out var globalUid))
|
||||
return null;
|
||||
|
||||
var audioP = audioParams ?? AudioParams.Default;
|
||||
var entity = EntityManager.CreateEntityUninitialized("Audio", new EntityCoordinates(globalUid.Value, Vector2.Zero));
|
||||
var entity = EntityManager.CreateEntityUninitialized("Audio", MapCoordinates.Nullspace);
|
||||
var comp = SetupAudio(entity, stream.Name!, audioP);
|
||||
EntityManager.InitializeAndStartEntity(entity);
|
||||
var source = comp.Source;
|
||||
@@ -671,14 +641,13 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
public AudioSystem System;
|
||||
|
||||
public MapCoordinates OurPosition;
|
||||
public EntityUid? GlobalAudioMap;
|
||||
public List<(EntityUid Entity, AudioComponent Component, TransformComponent Xform)> Streams;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
var comp = Streams[index];
|
||||
|
||||
System.ProcessStream(comp.Entity, comp.Component, comp.Xform, OurPosition, GlobalAudioMap);
|
||||
System.ProcessStream(comp.Entity, comp.Component, comp.Xform, OurPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.AudioLoading;
|
||||
@@ -19,7 +20,6 @@ namespace Robust.Server.Audio;
|
||||
|
||||
public sealed partial class AudioSystem : SharedAudioSystem
|
||||
{
|
||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||
[Dependency] private readonly PvsOverrideSystem _pvs = default!;
|
||||
[Dependency] private readonly IResourceManager _resourceManager = default!;
|
||||
|
||||
@@ -42,30 +42,6 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
component.Source = new DummyAudioSource();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates the global audio entity map.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal EntityUid EnsureAudioMap()
|
||||
{
|
||||
if (Count<GlobalAudioMapComponent>() == 0)
|
||||
{
|
||||
var mapId = MapManager.CreateMap();
|
||||
var mapUid = MapManager.GetMapEntityId(mapId);
|
||||
AddComp<GlobalAudioMapComponent>(mapUid);
|
||||
_metadata.SetEntityName(mapUid, "Audio map");
|
||||
}
|
||||
|
||||
var query = EntityQueryEnumerator<GlobalAudioMapComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
return EntityUid.Invalid;
|
||||
}
|
||||
|
||||
private void AddAudioFilter(EntityUid uid, AudioComponent component, Filter filter)
|
||||
{
|
||||
var count = filter.Count;
|
||||
@@ -95,10 +71,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
/// <inheritdoc />
|
||||
public override (EntityUid Entity, AudioComponent Component)? PlayGlobal(string filename, Filter playerFilter, bool recordReplay, AudioParams? audioParams = null)
|
||||
{
|
||||
var globalMapUid = EnsureAudioMap();
|
||||
var coordinates = new EntityCoordinates(globalMapUid, Vector2.Zero);
|
||||
|
||||
var entity = Spawn("Audio", coordinates);
|
||||
var entity = Spawn("Audio", MapCoordinates.Nullspace);
|
||||
var audio = SetupAudio(entity, filename, audioParams);
|
||||
AddAudioFilter(entity, audio, playerFilter);
|
||||
audio.Global = true;
|
||||
|
||||
@@ -226,10 +226,15 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
gridLoc.Add(index);
|
||||
dirtyChunks.Add(gridChunkLocation);
|
||||
break;
|
||||
case SessionOverride sessionOverride:
|
||||
if (!_sessionOverrides.TryGetValue(sessionOverride.Session, out var set))
|
||||
return;
|
||||
set.Add(index);
|
||||
case SessionsOverride sessionOverride:
|
||||
foreach (var sesh in sessionOverride.Sessions)
|
||||
{
|
||||
if (!_sessionOverrides.TryGetValue(sesh, out var set))
|
||||
continue;
|
||||
|
||||
set.Add(index);
|
||||
}
|
||||
|
||||
break;
|
||||
case MapChunkLocation mapChunkLocation:
|
||||
// might be gone due to map-deletions
|
||||
@@ -259,8 +264,11 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
case GridChunkLocation gridChunkLocation:
|
||||
_gridChunkContents[gridChunkLocation.GridId][gridChunkLocation.ChunkIndices].Remove(index);
|
||||
break;
|
||||
case SessionOverride sessionOverride:
|
||||
_sessionOverrides.GetValueOrDefault(sessionOverride.Session)?.Remove(index);
|
||||
case SessionsOverride sessionOverride:
|
||||
foreach (var sesh in sessionOverride.Sessions)
|
||||
{
|
||||
_sessionOverrides.GetValueOrDefault(sesh)?.Remove(index);
|
||||
}
|
||||
break;
|
||||
case MapChunkLocation mapChunkLocation:
|
||||
_mapChunkContents[mapChunkLocation.MapId][mapChunkLocation.ChunkIndices].Remove(index);
|
||||
@@ -410,7 +418,7 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeFromOverride && oldLocation is SessionOverride)
|
||||
if (!removeFromOverride && oldLocation is SessionsOverride)
|
||||
return;
|
||||
|
||||
if (oldLocation is GlobalOverride global &&
|
||||
@@ -433,20 +441,29 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
{
|
||||
if (!TryGetLocation(index, out var oldLocation))
|
||||
{
|
||||
RegisterUpdate(index, new SessionOverride(session));
|
||||
RegisterUpdate(index, new SessionsOverride(new HashSet<ICommonSession>()
|
||||
{
|
||||
session
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeFromOverride && oldLocation is GlobalOverride)
|
||||
return;
|
||||
|
||||
if (oldLocation is SessionOverride local &&
|
||||
(!removeFromOverride || local.Session == session))
|
||||
if (oldLocation is SessionsOverride local)
|
||||
{
|
||||
if (!removeFromOverride || local.Sessions.Contains(session))
|
||||
return;
|
||||
|
||||
local.Sessions.Add(session);
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterUpdate(index, new SessionOverride(session));
|
||||
RegisterUpdate(index, new SessionsOverride(new HashSet<ICommonSession>()
|
||||
{
|
||||
session
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -459,7 +476,7 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
{
|
||||
if (!removeFromOverride
|
||||
&& TryGetLocation(index, out var oldLocation)
|
||||
&& oldLocation is GlobalOverride or SessionOverride)
|
||||
&& oldLocation is GlobalOverride or SessionsOverride)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -509,7 +526,7 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
_indexLocations.TryGetValue(index, out var oldLocation);
|
||||
|
||||
//removeFromOverride is false 99% of the time.
|
||||
if ((bufferedLocation ?? oldLocation) is GlobalOverride or SessionOverride && !removeFromOverride)
|
||||
if ((bufferedLocation ?? oldLocation) is GlobalOverride or SessionsOverride && !removeFromOverride)
|
||||
return;
|
||||
|
||||
if (oldLocation is GridChunkLocation oldGrid &&
|
||||
@@ -540,7 +557,7 @@ public sealed class PVSCollection<TIndex> : IPVSCollection where TIndex : ICompa
|
||||
_indexLocations.TryGetValue(index, out var oldLocation);
|
||||
|
||||
//removeFromOverride is false 99% of the time.
|
||||
if ((bufferedLocation ?? oldLocation) is GlobalOverride or SessionOverride && !removeFromOverride)
|
||||
if ((bufferedLocation ?? oldLocation) is GlobalOverride or SessionsOverride && !removeFromOverride)
|
||||
return;
|
||||
|
||||
// Is this entity just returning to its old location?
|
||||
@@ -640,14 +657,17 @@ public struct GlobalOverride : IIndexLocation
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionOverride : IIndexLocation
|
||||
/// <summary>
|
||||
/// Adds overrides for the specified sessions for this entity.
|
||||
/// </summary>
|
||||
public struct SessionsOverride : IIndexLocation
|
||||
{
|
||||
public SessionOverride(ICommonSession session)
|
||||
public SessionsOverride(HashSet<ICommonSession> sessions)
|
||||
{
|
||||
Session = session;
|
||||
Sessions = sessions;
|
||||
}
|
||||
|
||||
public readonly ICommonSession Session;
|
||||
public readonly HashSet<ICommonSession> Sessions;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Robust.Shared.Audio.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Flags a map as storing global audio entities.
|
||||
/// This is to avoid leaving them in nullspace.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class GlobalAudioMapComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
@@ -29,7 +29,6 @@ public abstract partial class SharedAudioSystem : EntitySystem
|
||||
{
|
||||
[Dependency] protected readonly IConfigurationManager CfgManager = default!;
|
||||
[Dependency] protected readonly IGameTiming Timing = default!;
|
||||
[Dependency] protected readonly IMapManager MapManager = default!;
|
||||
[Dependency] private readonly INetManager _netManager = default!;
|
||||
[Dependency] protected readonly IPrototypeManager ProtoMan = default!;
|
||||
[Dependency] protected readonly IRobustRandom RandMan = default!;
|
||||
|
||||
Reference in New Issue
Block a user