diff --git a/project/Aki.SinglePlayer/Aki.SinglePlayer.csproj b/project/Aki.SinglePlayer/Aki.SinglePlayer.csproj
index a272721..d1c4584 100644
--- a/project/Aki.SinglePlayer/Aki.SinglePlayer.csproj
+++ b/project/Aki.SinglePlayer/Aki.SinglePlayer.csproj
@@ -7,7 +7,7 @@
Aki
- Copyright @ Aki 2022
+ Copyright @ Aki 2023
@@ -17,6 +17,9 @@
+
+ ..\Shared\Managed\UnityEngine.AudioModule.dll
+
diff --git a/project/Aki.SinglePlayer/AkiSingleplayerPlugin.cs b/project/Aki.SinglePlayer/AkiSingleplayerPlugin.cs
index 96f8c3f..89d152c 100644
--- a/project/Aki.SinglePlayer/AkiSingleplayerPlugin.cs
+++ b/project/Aki.SinglePlayer/AkiSingleplayerPlugin.cs
@@ -47,6 +47,8 @@ namespace Aki.SinglePlayer
new LighthouseBridgePatch().Enable();
new LighthouseTransmitterPatch().Enable();
new EmptyInfilFixPatch().Enable();
+ new SmokeGrenadeFuseSoundFixPatch().Enable();
+ new PlayerToggleSoundFixPatch().Enable();
}
catch (Exception ex)
{
diff --git a/project/Aki.SinglePlayer/Patches/RaidFix/PlayerToggleSoundFixPatch.cs b/project/Aki.SinglePlayer/Patches/RaidFix/PlayerToggleSoundFixPatch.cs
new file mode 100644
index 0000000..26e8b09
--- /dev/null
+++ b/project/Aki.SinglePlayer/Patches/RaidFix/PlayerToggleSoundFixPatch.cs
@@ -0,0 +1,37 @@
+using System.Reflection;
+using Aki.Reflection.Patching;
+using Comfort.Common;
+using EFT;
+using UnityEngine;
+
+namespace Aki.SinglePlayer.Patches.RaidFix
+{
+ ///
+ /// Fixes an issue with the visor toggle sound not following the player in offline raids
+ ///
+ public class PlayerToggleSoundFixPatch : ModulePatch
+ {
+ protected override MethodBase GetTargetMethod()
+ {
+ return typeof(Player).GetMethod("PlayToggleSound", BindingFlags.Instance | BindingFlags.NonPublic);
+ }
+
+ [PatchPrefix]
+ private static bool PatchPrefix(ref bool previousState, bool isOn, AudioClip toggleOn, AudioClip toggleOff, Player __instance)
+ {
+ // Don't change anything and execute original method if it's not the player that triggers the method
+ if (!__instance.IsYourPlayer)
+ {
+ return true;
+ }
+
+ if (previousState != isOn)
+ {
+ Singleton.Instance.PlayNonspatial(isOn ? toggleOn : toggleOff, BetterAudio.AudioSourceGroupType.Character);
+ }
+
+ previousState = isOn;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/project/Aki.SinglePlayer/Patches/RaidFix/SmokeGrenadeFuseSoundFixPatch.cs b/project/Aki.SinglePlayer/Patches/RaidFix/SmokeGrenadeFuseSoundFixPatch.cs
new file mode 100644
index 0000000..ad95d89
--- /dev/null
+++ b/project/Aki.SinglePlayer/Patches/RaidFix/SmokeGrenadeFuseSoundFixPatch.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using Aki.Reflection.CodeWrapper;
+using Aki.Reflection.Patching;
+using HarmonyLib;
+using UnityEngine;
+
+namespace Aki.SinglePlayer.Patches.RaidFix
+{
+ ///
+ /// Fixes an issue with smoke grenades not playing the fuse popping sound when thrown
+ ///
+ public class SmokeGrenadeFuseSoundFixPatch : ModulePatch
+ {
+ protected override MethodBase GetTargetMethod()
+ {
+ return typeof(GrenadeEmission).GetMethod(nameof(GrenadeEmission.StartEmission));
+ }
+
+ [PatchTranspiler]
+ private static IEnumerable PatchTranspile(IEnumerable instructions)
+ {
+ var codes = new List(instructions);
+ var searchCode = new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(AudioClip), "get_length"));
+ var searchIndex = -1;
+
+ for (var i = 0; i < codes.Count; i++)
+ {
+ if (codes[i].opcode == searchCode.opcode && codes[i].operand == searchCode.operand)
+ {
+ searchIndex = i;
+ break;
+ }
+ }
+
+ if (searchIndex == -1)
+ {
+ Logger.LogError($"{nameof(SmokeGrenadeFuseSoundFixPatch)} failed: Could not find reference code.");
+ return instructions;
+ }
+
+ var newCodes = CodeGenerator.GenerateInstructions(new List
+ {
+ new Code(OpCodes.Ldarg_0),
+ new Code(OpCodes.Ldfld, typeof(GrenadeEmission), "betterSource_0"),
+ new Code(OpCodes.Ldfld, typeof(BetterSource), "source1"),
+ new Code(OpCodes.Callvirt, typeof(AudioSource), "Play")
+ });
+
+ searchIndex -= 4;
+
+ codes.InsertRange(searchIndex, newCodes);
+ return codes.AsEnumerable();
+ }
+ }
+}
\ No newline at end of file