Allow content to override ProcessStream and GetOcclusion in AudioSystem (#6268)

* Add optional override methods for ProcessStream and GetOcclusion

* Mark override events as static

* Change audio actions to non-static
This commit is contained in:
Nemanja
2025-11-30 11:32:26 -05:00
committed by GitHub
parent c41d63be27
commit 465a1fb5bd

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using JetBrains.Annotations;
using OpenTK.Audio.OpenAL;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
@@ -45,6 +46,26 @@ public sealed partial class AudioSystem : SharedAudioSystem
[Dependency] private readonly SharedTransformSystem _xformSys = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
/// <summary>
/// An optional method that, if provided, will override the behavior of <see cref="ProcessStream"/>.
/// Contains the same parameters in the same order as the method it overrides.
/// </summary>
/// <remarks>
/// This event only supports a single invocation target.
/// </remarks>
[PublicAPI]
public event Action<EntityUid, AudioComponent, TransformComponent, MapCoordinates>? ProcessStreamOverride;
/// <summary>
/// An optional method that, if provided, will override the behavior of <see cref="GetOcclusion"/>.
/// Contains the same parameters in the same order as the method it overrides.
/// </summary>
/// <remarks>
/// This event only supports a single invocation target.
/// </remarks>
[PublicAPI]
public event Func<MapCoordinates, Vector2, float, EntityUid?, float>? GetOcclusionOverride;
/// <summary>
/// Per-tick cache of relevant streams.
/// </summary>
@@ -341,6 +362,15 @@ public sealed partial class AudioSystem : SharedAudioSystem
private void ProcessStream(EntityUid entity, AudioComponent component, TransformComponent xform, MapCoordinates listener)
{
// If content wants to process the stream in their own special way, we simply let them handle that.
if (ProcessStreamOverride is not null)
{
// Assert that we are not processing audio multiple times.
DebugTools.Assert(ProcessStreamOverride.HasSingleTarget, $"Event {nameof(ProcessStreamOverride)} has multiple invocation targets. This is not permitted.");
ProcessStreamOverride.Invoke(entity, component, xform, listener);
return; // Exit and do not perform remaining function behavior
}
// TODO:
// I Originally tried to be fancier here but it caused audio issues so just trying
// to replicate the old behaviour for now.
@@ -434,6 +464,14 @@ public sealed partial class AudioSystem : SharedAudioSystem
/// </summary>
public float GetOcclusion(MapCoordinates listener, Vector2 delta, float distance, EntityUid? ignoredEnt = null)
{
// If content has defined a custom occlusion method, use that instead.
if (GetOcclusionOverride is not null)
{
// There can only be one occlusion override defined.
DebugTools.Assert(GetOcclusionOverride.HasSingleTarget, $"Event {nameof(GetOcclusionOverride)} has multiple invocation targets. This is not permitted.");
return GetOcclusionOverride.Invoke(listener, delta, distance, ignoredEnt);
}
float occlusion = 0;
if (distance > 0.1)