diff --git a/NitroxClient/Communication/Packets/Processors/PlayFMODAssetProcessor.cs b/NitroxClient/Communication/Packets/Processors/PlayFMODAssetProcessor.cs index eb0f4c2df6..4c565a84e2 100644 --- a/NitroxClient/Communication/Packets/Processors/PlayFMODAssetProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/PlayFMODAssetProcessor.cs @@ -3,6 +3,8 @@ using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxModel.Packets; using NitroxModel_Subnautica.DataStructures; +using UnityEngine; + #pragma warning disable 618 namespace NitroxClient.Communication.Packets.Processors @@ -14,7 +16,9 @@ public override void Process(PlayFMODAsset packet) EventInstance instance = FMODUWE.GetEvent(packet.AssetPath); instance.setProperty(EVENT_PROPERTY.MINIMUM_DISTANCE, 1f); instance.setProperty(EVENT_PROPERTY.MAXIMUM_DISTANCE, packet.Radius); - instance.setVolume(packet.Volume); + // Volume is a scalar, is should be limited to 0 and we don't need more than 100% volume (i.e. 1.0). + // See docs: https://fmod.com/resources/documentation-api?version=2.00&page=studio-api-eventinstance.html#studio_eventinstance_setvolume + instance.setVolume(Mathf.Clamp01(packet.Volume)); instance.set3DAttributes(packet.Position.ToUnity().To3DAttributes()); instance.start(); instance.release(); diff --git a/NitroxClient/Debuggers/SoundDebugger.cs b/NitroxClient/Debuggers/SoundDebugger.cs index 095f7a3bd0..27fd32b2d9 100644 --- a/NitroxClient/Debuggers/SoundDebugger.cs +++ b/NitroxClient/Debuggers/SoundDebugger.cs @@ -25,7 +25,7 @@ public class SoundDebugger : BaseDebugger public SoundDebugger(FMODSystem fmodSystem) : base(700, null, KeyCode.S, true, false, true, GUISkinCreationOptions.DERIVEDCOPY) { - assetList = fmodSystem.GetSoundDataList(); + assetList = fmodSystem.SoundDataList; ActiveTab = AddTab("Sounds", RenderTabAllSounds); } diff --git a/NitroxClient/GameLogic/FMOD/FMODSystem.cs b/NitroxClient/GameLogic/FMOD/FMODSystem.cs index d699f1845f..64784faeff 100644 --- a/NitroxClient/GameLogic/FMOD/FMODSystem.cs +++ b/NitroxClient/GameLogic/FMOD/FMODSystem.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using NitroxClient.Communication.Abstract; +using NitroxClient.Properties; using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic; using NitroxModel.Logger; @@ -11,19 +12,16 @@ namespace NitroxClient.GameLogic.FMOD { public class FMODSystem { - private readonly Dictionary assetWhitelist = new Dictionary(); - + private readonly Dictionary assetWhitelist = new(); private readonly IPacketSender packetSender; public FMODSystem(IPacketSender packetSender) { this.packetSender = packetSender; - - string soundsWhitelist = Properties.Resources.soundsWhitelist; - + string soundsWhitelist = Resources.soundsWhitelist; if (string.IsNullOrWhiteSpace(soundsWhitelist)) { - Log.Error(new NullReferenceException(), "[FMODSystem]: soundsWhitelist.csv is null or whitespace"); + Log.Error("[FMODSystem]: soundsWhitelist.csv is null or whitespace"); } foreach (string entry in soundsWhitelist.Split('\n')) @@ -47,6 +45,11 @@ public FMODSystem(IPacketSender packetSender) } } + public static FMODSuppressor SuppressSounds() + { + return new(); + } + public bool IsWhitelisted(string path) { return assetWhitelist.TryGetValue(path, out SoundData soundData) && soundData.IsWhitelisted; @@ -66,7 +69,6 @@ public bool IsWhitelisted(string path, out bool isGlobal, out float radius) return false; } - public void PlayAsset(string path, NitroxVector3 position, float volume, float radius, bool isGlobal) { packetSender.Send(new PlayFMODAsset(path, position, volume, radius, isGlobal)); @@ -87,11 +89,6 @@ public void PlayStudioEmitter(NitroxId id, string assetPath, bool play, bool all packetSender.Send(new PlayFMODStudioEmitter(id, assetPath, play, allowFadeout)); } - public Dictionary GetSoundDataList() => assetWhitelist; - - public static FMODSuppressor SuppressSounds() - { - return new FMODSuppressor(); - } + public Dictionary SoundDataList => assetWhitelist; } } diff --git a/NitroxClient/MonoBehaviours/MultiplayerSeaMoth.cs b/NitroxClient/MonoBehaviours/MultiplayerSeaMoth.cs index 28f0e683bb..58b0a896fd 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerSeaMoth.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerSeaMoth.cs @@ -24,9 +24,10 @@ protected override void Awake() protected void Update() { + // Clamp volume between 0 and 1 (nothing or max). Going below 0 turns up volume to max. float distance = Vector3.Distance(Player.main.transform.position, transform.position); - rpmSound.GetEventInstance().setVolume(1 - distance / radiusRpmSound); - revSound.GetEventInstance().setVolume(1 - distance / radiusRevSound); + rpmSound.GetEventInstance().setVolume(Mathf.Clamp01(1 - distance / radiusRpmSound)); + revSound.GetEventInstance().setVolume(Mathf.Clamp01(1 - distance / radiusRevSound)); if (lastThrottle) { diff --git a/NitroxModel/Helper/Mathf.cs b/NitroxModel/Helper/Mathf.cs index 0fd9f517a8..ac2a681b26 100644 --- a/NitroxModel/Helper/Mathf.cs +++ b/NitroxModel/Helper/Mathf.cs @@ -28,6 +28,38 @@ public static float Pow(float p1, float p2) return (float)Math.Pow(p1, p2); } + /// + /// Clamps the given value between 0 and 1. + /// + /// + /// + public static float Clamp01(float value) + { + // Not using Clamp as an optimization. + if (value < 0) + { + return 0; + } + if (value > 1) + { + return 1; + } + return value; + } + + public static T Clamp(T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) + { + return min; + } + if (val.CompareTo(max) > 0) + { + return max; + } + return val; + } + /// is less than 0 or greater than 15. public static float Round(float value, int digits = 0) { diff --git a/NitroxServer/Communication/Packets/Processors/DefaultServerPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/DefaultServerPacketProcessor.cs index 1538d45786..34c4f74e1f 100644 --- a/NitroxServer/Communication/Packets/Processors/DefaultServerPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/DefaultServerPacketProcessor.cs @@ -11,7 +11,8 @@ public class DefaultServerPacketProcessor : AuthenticatedPacketProcessor { private readonly PlayerManager playerManager; - private readonly HashSet loggingPacketBlackList = new HashSet { + private readonly HashSet loggingPacketBlackList = new() + { typeof(AnimationChangeEvent), typeof(Movement), typeof(VehicleMovement),