Decompiled source of SnappyCinematics v0.1.2

plugins/com.github.Snappychaff290.NicsCinematics.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.Snappychaff290.NicsCinematics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+b625e99653d296fd8548553a22e625507130f8d0")]
[assembly: AssemblyProduct("com.github.Snappychaff290.NicsCinematics")]
[assembly: AssemblyTitle("SnappyCinematics")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace NicsCinematics
{
	[BepInPlugin("com.github.Snappychaff290.NicsCinematics", "SnappyCinematics", "0.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		public class SlowMotionVisualEffect : MonoBehaviour
		{
			private float timeScale = 1f;

			private Vector3 lastPosition;

			private Quaternion lastRotation;

			private float interpolationTimer;

			private void Start()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				lastPosition = ((Component)this).transform.position;
				lastRotation = ((Component)this).transform.rotation;
			}

			public void SetTimeScale(float scale)
			{
				timeScale = scale;
			}

			private void Update()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				interpolationTimer += Time.deltaTime * timeScale;
				if (interpolationTimer >= Time.deltaTime)
				{
					lastPosition = ((Component)this).transform.position;
					lastRotation = ((Component)this).transform.rotation;
					interpolationTimer = 0f;
				}
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedFindLocalPlayer>d__51 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedFindLocalPlayer>d__51(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					plugin.FindLocalPlayer();
					plugin.findPlayerCoroutine = null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PreloadAudio>d__62 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private UnityWebRequest <www>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PreloadAudio>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<www>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Invalid comparison between Unknown and I4
				try
				{
					int num = <>1__state;
					Plugin plugin = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						string text = Path.Combine(Path.GetTempPath(), "nics_cinematics_audio.mp3");
						bool flag = false;
						try
						{
							Assembly executingAssembly = Assembly.GetExecutingAssembly();
							string text2 = "NicsCinematics.audio.mp3";
							using Stream stream = executingAssembly.GetManifestResourceStream(text2);
							if (stream == null)
							{
								Log.LogError((object)("Could not find embedded resource: " + text2));
								Log.LogError((object)("Available resources: " + string.Join(", ", executingAssembly.GetManifestResourceNames())));
							}
							else
							{
								using FileStream destination = new FileStream(text, FileMode.Create, FileAccess.Write);
								stream.CopyTo(destination);
								flag = true;
							}
						}
						catch (Exception ex)
						{
							Log.LogError((object)("Error loading embedded audio: " + ex.Message));
						}
						if (!flag)
						{
							return false;
						}
						<www>5__2 = UnityWebRequestMultimedia.GetAudioClip("file:///" + text, (AudioType)13);
						<>1__state = -3;
						<>2__current = <www>5__2.SendWebRequest();
						<>1__state = 1;
						return true;
					}
					case 1:
						<>1__state = -3;
						if ((int)<www>5__2.result == 1)
						{
							plugin.loadedClip = DownloadHandlerAudioClip.GetContent(<www>5__2);
							Log.LogInfo((object)"MP3 preloaded successfully");
						}
						else
						{
							Log.LogError((object)("Failed to load audio file: " + <www>5__2.error));
						}
						<>m__Finally1();
						<www>5__2 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<www>5__2 != null)
				{
					((IDisposable)<www>5__2).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PreloadHurtSounds>d__61 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private string[] <soundNames>5__2;

			private int <i>5__3;

			private string <tempPath>5__4;

			private UnityWebRequest <www>5__5;

			private UnityWebRequest <wwwMpeg>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PreloadHurtSounds>d__61(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 1u)
				{
					try
					{
						if (num == -4 || num == 2)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<soundNames>5__2 = null;
				<tempPath>5__4 = null;
				<www>5__5 = null;
				<wwwMpeg>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0207: Unknown result type (might be due to invalid IL or missing references)
				//IL_020d: Invalid comparison between Unknown and I4
				//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ba: Invalid comparison between Unknown and I4
				try
				{
					int num = <>1__state;
					Plugin plugin = <>4__this;
					int num2;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<soundNames>5__2 = new string[3] { "hurt1.mp3", "hurt2.mp3", "hurt3.mp3" };
						<i>5__3 = 0;
						goto IL_0476;
					case 1:
						<>1__state = -3;
						if ((int)<www>5__5.result == 1)
						{
							plugin.hurtClips[<i>5__3] = DownloadHandlerAudioClip.GetContent(<www>5__5);
							if ((Object)(object)plugin.hurtClips[<i>5__3] != (Object)null)
							{
								((Object)plugin.hurtClips[<i>5__3]).name = <soundNames>5__2[<i>5__3];
								Log.LogInfo((object)("[SOUND LOAD] ✓ Hurt sound " + <soundNames>5__2[<i>5__3] + " loaded successfully"));
								Log.LogInfo((object)$"[SOUND LOAD]   - Length: {plugin.hurtClips[<i>5__3].length}s, Channels: {plugin.hurtClips[<i>5__3].channels}, Freq: {plugin.hurtClips[<i>5__3].frequency}Hz");
							}
							else
							{
								Log.LogError((object)("[SOUND LOAD ERROR] Clip was null after loading " + <soundNames>5__2[<i>5__3]));
							}
							goto IL_0450;
						}
						Log.LogError((object)("[SOUND LOAD ERROR] Failed to load hurt sound " + <soundNames>5__2[<i>5__3] + ": " + <www>5__5.error));
						Log.LogInfo((object)("[SOUND LOAD] Trying MPEG format as fallback for " + <soundNames>5__2[<i>5__3] + "..."));
						<wwwMpeg>5__6 = UnityWebRequestMultimedia.GetAudioClip("file:///" + <tempPath>5__4, (AudioType)13);
						<>1__state = -4;
						<>2__current = <wwwMpeg>5__6.SendWebRequest();
						<>1__state = 2;
						return true;
					case 2:
						{
							<>1__state = -4;
							if ((int)<wwwMpeg>5__6.result == 1)
							{
								plugin.hurtClips[<i>5__3] = DownloadHandlerAudioClip.GetContent(<wwwMpeg>5__6);
								if ((Object)(object)plugin.hurtClips[<i>5__3] != (Object)null)
								{
									((Object)plugin.hurtClips[<i>5__3]).name = <soundNames>5__2[<i>5__3];
									Log.LogInfo((object)$"[SOUND LOAD] ✓ Loaded {<soundNames>5__2[<i>5__3]} as MPEG (length: {plugin.hurtClips[<i>5__3].length}s)");
								}
							}
							<>m__Finally2();
							<wwwMpeg>5__6 = null;
							goto IL_0450;
						}
						IL_0450:
						<>m__Finally1();
						<www>5__5 = null;
						goto IL_045d;
						IL_0476:
						if (<i>5__3 < <soundNames>5__2.Length)
						{
							<tempPath>5__4 = Path.Combine(Path.GetTempPath(), "nics_cinematics_" + <soundNames>5__2[<i>5__3]);
							bool flag = false;
							try
							{
								Assembly executingAssembly = Assembly.GetExecutingAssembly();
								string text = "NicsCinematics." + <soundNames>5__2[<i>5__3];
								using Stream stream = executingAssembly.GetManifestResourceStream(text);
								if (stream == null)
								{
									Log.LogError((object)("[SOUND LOAD ERROR] Could not find embedded resource: " + text));
									Log.LogError((object)("[SOUND LOAD] Make sure " + <soundNames>5__2[<i>5__3] + " exists in src/NicsCinematics/ folder!"));
									string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
									Log.LogInfo((object)("[SOUND LOAD] Available embedded resources: " + string.Join(", ", manifestResourceNames)));
								}
								else
								{
									using FileStream destination = new FileStream(<tempPath>5__4, FileMode.Create, FileAccess.Write);
									stream.CopyTo(destination);
									flag = true;
									Log.LogInfo((object)("[SOUND LOAD] Successfully extracted " + <soundNames>5__2[<i>5__3] + " to temp file"));
								}
							}
							catch (Exception ex)
							{
								Log.LogError((object)("Error loading embedded hurt sound " + <soundNames>5__2[<i>5__3] + ": " + ex.Message));
							}
							if (flag)
							{
								<www>5__5 = UnityWebRequestMultimedia.GetAudioClip("file:///" + <tempPath>5__4, (AudioType)20);
								<>1__state = -3;
								<>2__current = <www>5__5.SendWebRequest();
								<>1__state = 1;
								return true;
							}
							goto IL_045d;
						}
						num2 = plugin.hurtClips.Count((AudioClip c) => (Object)(object)c != (Object)null);
						Log.LogInfo((object)$"[SOUND LOAD] === FINAL: Loaded {num2} of {<soundNames>5__2.Length} hurt/fart sounds ===");
						if (num2 == 0)
						{
							Log.LogError((object)"[SOUND LOAD ERROR] NO HURT SOUNDS LOADED! Add hurt1.mp3, hurt2.mp3, hurt3.mp3 to src/NicsCinematics/");
						}
						return false;
						IL_045d:
						<tempPath>5__4 = null;
						<i>5__3++;
						goto IL_0476;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<www>5__5 != null)
				{
					((IDisposable)<www>5__5).Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<wwwMpeg>5__6 != null)
				{
					((IDisposable)<wwwMpeg>5__6).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static Dictionary<string, GameObject> remoteAudioSources = new Dictionary<string, GameObject>();

		private static Dictionary<string, AudioSource> remoteSlowMotionSources = new Dictionary<string, AudioSource>();

		private static Dictionary<string, AudioSource> remoteHurtSources = new Dictionary<string, AudioSource>();

		private static HashSet<int> activeSlowMotionPlayers = new HashSet<int>();

		private bool isSlowMotionActive;

		private GameObject? localPlayer;

		private Rigidbody? playerRigidbody;

		private PhotonView? playerPhotonView;

		private GameObject? audioSourceObject;

		private AudioSource? playerAudioSource;

		private AudioClip? loadedClip;

		private Coroutine? findPlayerCoroutine;

		private float originalTimeScale = 1f;

		private float originalFixedDeltaTime = 0.02f;

		private float lastYVelocity;

		private bool wasInAir;

		private float fallStartHeight;

		private float maxHeightDuringJump;

		private float timeInAir;

		private const float FALL_DAMAGE_THRESHOLD = 8f;

		private const float MIN_FALL_HEIGHT = 0.1f;

		private float debugLogTimer;

		private bool wasGroundedLastFrame = true;

		private AudioClip?[] hurtClips = (AudioClip?[])(object)new AudioClip[3];

		private AudioSource? hurtAudioSource;

		private GameObject? hurtAudioObject;

		public const string Id = "com.github.Snappychaff290.NicsCinematics";

		internal static ManualLogSource Log { get; private set; } = null;


		internal static Plugin Instance { get; private set; } = null;


		public static ConfigEntry<bool> EnableCinematics { get; private set; } = null;


		public static ConfigEntry<float> SlowMotionScale { get; private set; } = null;


		public static ConfigEntry<float> AudioDistance { get; private set; } = null;


		public static string Name => "SnappyCinematics";

		public static string Version => "0.1.2";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			SetupConfiguration();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((MonoBehaviour)this).StartCoroutine(PreloadAudio());
			((MonoBehaviour)this).StartCoroutine(PreloadHurtSounds());
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			Log.LogInfo((object)"Controls:");
			Log.LogInfo((object)"  Press '9' to toggle slow-motion for YOURSELF");
			Log.LogInfo((object)"  Press '0' to manually test hurt/fart sound (for debugging)");
			Log.LogInfo((object)"Features:");
			Log.LogInfo((object)"  Personal slow-motion: YOU experience time slowing, YOU appear slow to others");
			Log.LogInfo((object)"  Visual sync: Other players with the mod see you moving in slow-motion");
			Log.LogInfo((object)"  Networked audio: Your slow-mo music plays from your 3D position for others");
			Log.LogInfo((object)"  Fall damage sounds play automatically when you take fall damage");
			Log.LogInfo((object)$"  Fall velocity threshold: {8f} (height check basically disabled)");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (findPlayerCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(findPlayerCoroutine);
				findPlayerCoroutine = null;
			}
			if ((Object)(object)audioSourceObject != (Object)null)
			{
				Object.Destroy((Object)(object)audioSourceObject);
				audioSourceObject = null;
			}
			if ((Object)(object)hurtAudioObject != (Object)null)
			{
				Object.Destroy((Object)(object)hurtAudioObject);
				hurtAudioObject = null;
			}
			localPlayer = null;
			playerRigidbody = null;
			playerPhotonView = null;
			playerAudioSource = null;
			hurtAudioSource = null;
			lastYVelocity = 0f;
			wasInAir = false;
			fallStartHeight = 0f;
			wasGroundedLastFrame = true;
			timeInAir = 0f;
			if (isSlowMotionActive)
			{
				Time.timeScale = originalTimeScale;
				Time.fixedDeltaTime = originalFixedDeltaTime;
				isSlowMotionActive = false;
			}
			activeSlowMotionPlayers.Clear();
			Log.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name + ", resetting player references and clearing network state"));
		}

		private void Update()
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayer == (Object)null && findPlayerCoroutine == null && PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null)
			{
				findPlayerCoroutine = ((MonoBehaviour)this).StartCoroutine(DelayedFindLocalPlayer());
			}
			if ((Object)(object)localPlayer != (Object)null && ((Object)(object)localPlayer == (Object)null || !localPlayer.activeInHierarchy))
			{
				Log.LogInfo((object)"Lost player reference, clearing...");
				localPlayer = null;
				playerRigidbody = null;
				playerPhotonView = null;
			}
			if (Input.GetKeyDown((KeyCode)57))
			{
				ToggleSlowMotion();
			}
			if (Input.GetKeyDown((KeyCode)48))
			{
				Log.LogInfo((object)"[DEBUG] Manual hurt sound trigger pressed (key 0)");
				PlayRandomHurtSound();
			}
			if ((Object)(object)audioSourceObject != (Object)null && (Object)(object)localPlayer != (Object)null)
			{
				audioSourceObject.transform.position = localPlayer.transform.position;
			}
			UpdateRemoteAudioPositions();
			CheckFallDamage();
		}

		private void FixedUpdate()
		{
			if (isSlowMotionActive && (Object)(object)playerRigidbody != (Object)null && (Object)(object)playerPhotonView != (Object)null && playerPhotonView.IsMine)
			{
				playerRigidbody.interpolation = (RigidbodyInterpolation)1;
			}
		}

		private void SetupConfiguration()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			EnableCinematics = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableCinematics", true, "Enable cinematic effects and camera control");
			SlowMotionScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SlowMotionScale", 0.2f, new ConfigDescription("Visual slow-motion effect scale (0.1 = 10% speed, 1.0 = normal speed)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			AudioDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "AudioDistance", 50f, new ConfigDescription("Maximum distance the slow-motion music can be heard from", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>()));
		}

		[IteratorStateMachine(typeof(<DelayedFindLocalPlayer>d__51))]
		private IEnumerator DelayedFindLocalPlayer()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedFindLocalPlayer>d__51(0)
			{
				<>4__this = this
			};
		}

		private void UpdateRemoteAudioPositions()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsConnected)
			{
				return;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				if (val.IsLocal)
				{
					continue;
				}
				string text = $"Player_{val.ActorNumber}";
				PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
				PhotonView[] array2 = array;
				foreach (PhotonView val2 in array2)
				{
					if (!((Object)(object)val2 != (Object)null) || val2.Owner == null || val2.Owner.ActorNumber != val.ActorNumber)
					{
						continue;
					}
					if (remoteAudioSources.ContainsKey(text))
					{
						GameObject val3 = remoteAudioSources[text];
						if ((Object)(object)val3 != (Object)null)
						{
							val3.transform.position = ((Component)val2).transform.position;
						}
					}
					string key = text + "_hurt";
					if (remoteAudioSources.ContainsKey(key))
					{
						GameObject val4 = remoteAudioSources[key];
						if ((Object)(object)val4 != (Object)null)
						{
							val4.transform.position = ((Component)val2).transform.position;
						}
					}
					break;
				}
			}
		}

		private void FindLocalPlayer()
		{
			if ((Object)(object)localPlayer != (Object)null)
			{
				return;
			}
			try
			{
				PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
				PhotonView[] array2 = array;
				foreach (PhotonView val in array2)
				{
					if (!((Object)(object)val == (Object)null) && val.IsMine)
					{
						GameObject gameObject = ((Component)val).gameObject;
						Rigidbody val2 = gameObject.GetComponent<Rigidbody>();
						if ((Object)(object)val2 == (Object)null)
						{
							val2 = gameObject.GetComponentInParent<Rigidbody>();
						}
						if ((Object)(object)val2 == (Object)null)
						{
							val2 = gameObject.GetComponentInChildren<Rigidbody>();
						}
						if ((Object)(object)val2 != (Object)null)
						{
							localPlayer = ((Component)val2).gameObject;
							playerPhotonView = val;
							playerRigidbody = val2;
							OptimizeNetworkSettings(val);
							Log.LogInfo((object)$"Found local player: {((Object)gameObject).name} -> RB: {((Object)localPlayer).name} (PhotonView ID: {val.ViewID})");
							break;
						}
					}
				}
				if ((Object)(object)localPlayer == (Object)null)
				{
					Log.LogDebug((object)"Local player not found in this search attempt");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error finding local player: " + ex.Message));
			}
		}

		private void OptimizeNetworkSettings(PhotonView pv)
		{
			try
			{
				PhotonTransformViewClassic component = ((Component)pv).GetComponent<PhotonTransformViewClassic>();
				if ((Object)(object)component != (Object)null)
				{
					FieldInfo field = ((object)component).GetType().GetField("m_SynchronizePosition");
					FieldInfo field2 = ((object)component).GetType().GetField("m_SynchronizeRotation");
					FieldInfo field3 = ((object)component).GetType().GetField("m_SynchronizeScale");
					if (field != null)
					{
						field.SetValue(component, true);
					}
					if (field2 != null)
					{
						field2.SetValue(component, true);
					}
					if (field3 != null)
					{
						field3.SetValue(component, false);
					}
					Log.LogInfo((object)"Optimized PhotonTransformViewClassic settings for smooth movement");
				}
				Component component2 = ((Component)pv).GetComponent("PhotonTransformView");
				if ((Object)(object)component2 != (Object)null)
				{
					Log.LogInfo((object)"Found PhotonTransformView component, network sync should be smooth");
				}
				PhotonRigidbodyView component3 = ((Component)pv).GetComponent<PhotonRigidbodyView>();
				if ((Object)(object)component3 != (Object)null)
				{
					FieldInfo field4 = ((object)component3).GetType().GetField("m_SynchronizeVelocity");
					FieldInfo field5 = ((object)component3).GetType().GetField("m_SynchronizeAngularVelocity");
					if (field4 != null)
					{
						field4.SetValue(component3, true);
					}
					if (field5 != null)
					{
						field5.SetValue(component3, true);
					}
					Log.LogInfo((object)"Optimized PhotonRigidbodyView settings for smooth physics");
				}
				if (PhotonNetwork.SendRate < 30)
				{
					PhotonNetwork.SendRate = 30;
					PhotonNetwork.SerializationRate = 15;
					Log.LogInfo((object)$"Adjusted network rates - SendRate: {PhotonNetwork.SendRate}, SerializationRate: {PhotonNetwork.SerializationRate}");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not optimize network settings: " + ex.Message));
			}
		}

		private void ToggleSlowMotion()
		{
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (!EnableCinematics.Value)
			{
				Log.LogInfo((object)"Cinematics disabled in config");
				return;
			}
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)playerRigidbody == (Object)null)
			{
				Log.LogWarning((object)"Local player not found yet");
				return;
			}
			isSlowMotionActive = !isSlowMotionActive;
			if (isSlowMotionActive)
			{
				originalTimeScale = Time.timeScale;
				originalFixedDeltaTime = Time.fixedDeltaTime;
				Time.timeScale = SlowMotionScale.Value;
				Time.fixedDeltaTime = originalFixedDeltaTime * SlowMotionScale.Value;
				PlayMp3FromPlayer();
				if ((Object)(object)playerPhotonView != (Object)null && PhotonNetwork.LocalPlayer != null)
				{
					playerPhotonView.RPC("OnPlayerAudioTriggered", (RpcTarget)1, new object[3]
					{
						PhotonNetwork.LocalPlayer.ActorNumber,
						localPlayer.transform.position,
						true
					});
				}
				Log.LogInfo((object)$"Slow-motion activated (scale: {SlowMotionScale.Value})");
				Log.LogInfo((object)"YOU experience slow-motion, others see YOU moving slowly");
			}
			else
			{
				Time.timeScale = originalTimeScale;
				Time.fixedDeltaTime = originalFixedDeltaTime;
				StopMp3();
				if ((Object)(object)playerPhotonView != (Object)null && PhotonNetwork.LocalPlayer != null)
				{
					playerPhotonView.RPC("OnPlayerAudioTriggered", (RpcTarget)1, new object[3]
					{
						PhotonNetwork.LocalPlayer.ActorNumber,
						localPlayer.transform.position,
						false
					});
				}
				Log.LogInfo((object)"Slow-motion deactivated (your time returns to normal)");
			}
		}

		private void PlayMp3FromPlayer()
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)loadedClip == (Object)null)
			{
				Log.LogError((object)$"Cannot play MP3: player={(Object)(object)localPlayer != (Object)null}, clip={(Object)(object)loadedClip != (Object)null}");
				return;
			}
			if ((Object)(object)audioSourceObject == (Object)null)
			{
				audioSourceObject = new GameObject("SlowMotionAudioSource");
				Object.DontDestroyOnLoad((Object)(object)audioSourceObject);
				playerAudioSource = audioSourceObject.AddComponent<AudioSource>();
				playerAudioSource.spatialBlend = 1f;
				playerAudioSource.minDistance = 5f;
				playerAudioSource.maxDistance = AudioDistance.Value;
				playerAudioSource.rolloffMode = (AudioRolloffMode)1;
				playerAudioSource.playOnAwake = false;
				playerAudioSource.loop = true;
				playerAudioSource.priority = 128;
				playerAudioSource.dopplerLevel = 0.5f;
			}
			audioSourceObject.transform.position = localPlayer.transform.position;
			playerAudioSource.clip = loadedClip;
			playerAudioSource.volume = 0.7f;
			playerAudioSource.pitch = 1f;
			playerAudioSource.Play();
			Log.LogInfo((object)"Playing MP3 from player position (3D audio)");
		}

		private void StopMp3()
		{
			if ((Object)(object)playerAudioSource != (Object)null && playerAudioSource.isPlaying)
			{
				playerAudioSource.Stop();
				playerAudioSource.clip = null;
				Log.LogInfo((object)"Stopped MP3 playback");
			}
		}

		private void CheckFallDamage()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)playerRigidbody == (Object)null)
			{
				return;
			}
			float y = playerRigidbody.velocity.y;
			bool flag = IsGrounded();
			float y2 = localPlayer.transform.position.y;
			debugLogTimer += Time.deltaTime;
			if (debugLogTimer > 2f)
			{
				debugLogTimer = 0f;
				Log.LogDebug((object)$"[FALL DEBUG] Y-Vel: {y:F2}, Grounded: {flag}, WasInAir: {wasInAir}, Height: {y2:F2}, MaxHeight: {maxHeightDuringJump:F2}");
			}
			if (wasGroundedLastFrame && !flag)
			{
				maxHeightDuringJump = y2;
				fallStartHeight = y2;
				Log.LogInfo((object)$"[FALL] Left ground at height: {y2:F2}");
			}
			if (!flag)
			{
				wasInAir = true;
				timeInAir += Time.deltaTime;
				if (y2 > maxHeightDuringJump)
				{
					maxHeightDuringJump = y2;
					fallStartHeight = y2;
				}
				if (y < -1f && Time.frameCount % 30 == 0)
				{
					Log.LogDebug((object)$"[FALL] Falling... Height: {y2:F2}, Max: {maxHeightDuringJump:F2}, Vel: {y:F2}, AirTime: {timeInAir:F2}s");
				}
			}
			if (!wasGroundedLastFrame && flag && wasInAir)
			{
				float num = maxHeightDuringJump - y2;
				float num2 = Mathf.Abs(lastYVelocity);
				Log.LogInfo((object)"[FALL] === LANDED ===");
				Log.LogInfo((object)$"[FALL] Impact velocity: {num2:F2} (threshold: {8f})");
				Log.LogInfo((object)$"[FALL] Time in air: {timeInAir:F2}s");
				Log.LogInfo((object)$"[FALL] Fall distance: {num:F2} (mostly ignored, using velocity)");
				if (num2 >= 8f)
				{
					Log.LogInfo((object)$"[FALL DAMAGE] \ud83d\udca8\ud83d\udca8\ud83d\udca8 FART TRIGGERED! Impact velocity {num2:F2} >= {8f} \ud83d\udca8\ud83d\udca8\ud83d\udca8");
					PlayRandomHurtSound();
				}
				else
				{
					Log.LogInfo((object)$"[FALL] No fart: Velocity {num2:F2} < {8f} (need harder landing)");
				}
				wasInAir = false;
				maxHeightDuringJump = 0f;
				timeInAir = 0f;
			}
			wasGroundedLastFrame = flag;
			lastYVelocity = y;
		}

		private bool IsGrounded()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			float num = 1.5f;
			Vector3 val = localPlayer.transform.position + Vector3.up * 0.1f;
			bool flag = Physics.Raycast(val, Vector3.down, num);
			bool flag2 = Physics.Raycast(val + localPlayer.transform.forward * 0.3f, Vector3.down, num);
			bool flag3 = Physics.Raycast(val - localPlayer.transform.forward * 0.3f, Vector3.down, num);
			bool flag4 = Physics.Raycast(val + localPlayer.transform.right * 0.3f, Vector3.down, num);
			bool flag5 = Physics.Raycast(val - localPlayer.transform.right * 0.3f, Vector3.down, num);
			bool flag6 = flag || flag2 || flag3 || flag4 || flag5;
			if (Time.frameCount % 60 == 0)
			{
				Log.LogDebug((object)$"[GROUND CHECK] Center:{flag} F:{flag2} B:{flag3} R:{flag4} L:{flag5} => Grounded:{flag6}");
			}
			return flag6;
		}

		private void PlayRandomHurtSound()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo((object)"[SOUND] PlayRandomHurtSound called");
			for (int i = 0; i < hurtClips.Length; i++)
			{
				Log.LogInfo((object)string.Format("[SOUND] Hurt clip {0}: {1}", i + 1, ((Object)(object)hurtClips[i] != (Object)null) ? "Loaded" : "NULL"));
			}
			AudioClip[] array = hurtClips.Where((AudioClip clip) => (Object)(object)clip != (Object)null).ToArray();
			if (array.Length == 0)
			{
				Log.LogError((object)"[SOUND ERROR] No hurt sounds loaded! Make sure hurt1.mp3, hurt2.mp3, hurt3.mp3 are in the src/NicsCinematics folder!");
				return;
			}
			Log.LogInfo((object)$"[SOUND] Found {array.Length} valid clips");
			if ((Object)(object)hurtAudioObject == (Object)null)
			{
				hurtAudioObject = new GameObject("HurtAudioSource");
				Object.DontDestroyOnLoad((Object)(object)hurtAudioObject);
				hurtAudioSource = hurtAudioObject.AddComponent<AudioSource>();
				hurtAudioSource.spatialBlend = 1f;
				hurtAudioSource.minDistance = 5f;
				hurtAudioSource.maxDistance = 50f;
				hurtAudioSource.rolloffMode = (AudioRolloffMode)1;
				hurtAudioSource.playOnAwake = false;
				hurtAudioSource.loop = false;
				hurtAudioSource.priority = 64;
			}
			if ((Object)(object)localPlayer != (Object)null)
			{
				hurtAudioObject.transform.position = localPlayer.transform.position;
			}
			int num = Random.Range(0, array.Length);
			AudioClip val = array[num];
			Log.LogInfo((object)$"[SOUND] Selected clip index {num}, clip name: {((Object)val).name}, length: {val.length}s, samples: {val.samples}");
			hurtAudioSource.clip = val;
			hurtAudioSource.volume = 1f;
			hurtAudioSource.pitch = 1f;
			hurtAudioSource.Play();
			if (!hurtAudioSource.isPlaying)
			{
				Log.LogWarning((object)"[SOUND] Audio not playing after Play() call, trying PlayOneShot...");
				hurtAudioSource.PlayOneShot(val, 1f);
			}
			if ((Object)(object)playerPhotonView != (Object)null && (Object)(object)localPlayer != (Object)null)
			{
				playerPhotonView.RPC("PlayHurtSoundNetwork", (RpcTarget)1, new object[3]
				{
					PhotonNetwork.LocalPlayer.ActorNumber,
					num,
					localPlayer.transform.position
				});
			}
			Log.LogInfo((object)$"[SOUND] ✓ Playing hurt/fart sound {num + 1} of {array.Length} (networked)");
			Log.LogInfo((object)$"[SOUND]   Volume: {hurtAudioSource.volume}, Pitch: {hurtAudioSource.pitch}, IsPlaying: {hurtAudioSource.isPlaying}");
			Log.LogInfo((object)$"[SOUND]   AudioSource enabled: {((Behaviour)hurtAudioSource).enabled}, GameObject active: {hurtAudioObject.activeInHierarchy}");
		}

		[IteratorStateMachine(typeof(<PreloadHurtSounds>d__61))]
		private IEnumerator PreloadHurtSounds()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PreloadHurtSounds>d__61(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<PreloadAudio>d__62))]
		private IEnumerator PreloadAudio()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PreloadAudio>d__62(0)
			{
				<>4__this = this
			};
		}

		private void ApplyVisualSlowMotionToPlayer(int actorNumber, float timeScale)
		{
			PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
			PhotonView[] array2 = array;
			foreach (PhotonView val in array2)
			{
				if ((Object)(object)val != (Object)null && val.Owner != null && val.Owner.ActorNumber == actorNumber)
				{
					Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.speed = timeScale;
						Log.LogInfo((object)$"[VISUAL] Set animation speed to {timeScale} for player {actorNumber}");
					}
					string key = $"SlowMoPlayer_{actorNumber}";
					if (!remoteAudioSources.ContainsKey(key))
					{
						remoteAudioSources[key] = ((Component)val).gameObject;
					}
					SlowMotionVisualEffect slowMotionVisualEffect = ((Component)val).gameObject.GetComponent<SlowMotionVisualEffect>();
					if ((Object)(object)slowMotionVisualEffect == (Object)null)
					{
						slowMotionVisualEffect = ((Component)val).gameObject.AddComponent<SlowMotionVisualEffect>();
					}
					slowMotionVisualEffect.SetTimeScale(timeScale);
					break;
				}
			}
		}

		private void RemoveVisualSlowMotionFromPlayer(int actorNumber)
		{
			PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
			PhotonView[] array2 = array;
			foreach (PhotonView val in array2)
			{
				if ((Object)(object)val != (Object)null && val.Owner != null && val.Owner.ActorNumber == actorNumber)
				{
					Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.speed = 1f;
						Log.LogInfo((object)$"[VISUAL] Restored normal animation speed for player {actorNumber}");
					}
					SlowMotionVisualEffect component = ((Component)val).gameObject.GetComponent<SlowMotionVisualEffect>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
					break;
				}
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (isSlowMotionActive)
			{
				Time.timeScale = 1f;
				Time.fixedDeltaTime = 0.02f;
			}
			if (findPlayerCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(findPlayerCoroutine);
			}
			if ((Object)(object)audioSourceObject != (Object)null)
			{
				Object.Destroy((Object)(object)audioSourceObject);
			}
			if ((Object)(object)hurtAudioObject != (Object)null)
			{
				Object.Destroy((Object)(object)hurtAudioObject);
			}
			foreach (KeyValuePair<string, GameObject> remoteAudioSource in remoteAudioSources)
			{
				if ((Object)(object)remoteAudioSource.Value != (Object)null)
				{
					Object.Destroy((Object)(object)remoteAudioSource.Value);
				}
			}
			remoteAudioSources.Clear();
			remoteSlowMotionSources.Clear();
			remoteHurtSources.Clear();
			if (isSlowMotionActive)
			{
				StopMp3();
			}
		}

		[PunRPC]
		public void OnPlayerAudioTriggered(int actorNumber, Vector3 position, bool isActive)
		{
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo((object)$"[NETWORK] Player {actorNumber} slow-motion state changed - Active: {isActive}");
			string text = $"Player_{actorNumber}";
			if (isActive)
			{
				activeSlowMotionPlayers.Add(actorNumber);
				ApplyVisualSlowMotionToPlayer(actorNumber, SlowMotionScale.Value);
				if (!remoteAudioSources.ContainsKey(text))
				{
					GameObject val = new GameObject("RemoteAudio_" + text);
					Object.DontDestroyOnLoad((Object)(object)val);
					AudioSource val2 = val.AddComponent<AudioSource>();
					val2.spatialBlend = 1f;
					val2.minDistance = 5f;
					val2.maxDistance = AudioDistance.Value;
					val2.rolloffMode = (AudioRolloffMode)1;
					val2.playOnAwake = false;
					val2.loop = true;
					val2.priority = 128;
					val2.dopplerLevel = 0.5f;
					remoteAudioSources[text] = val;
					remoteSlowMotionSources[text] = val2;
				}
				GameObject val3 = remoteAudioSources[text];
				AudioSource val4 = remoteSlowMotionSources[text];
				val3.transform.position = position;
				if ((Object)(object)loadedClip != (Object)null && !val4.isPlaying)
				{
					val4.clip = loadedClip;
					val4.volume = 0.7f;
					val4.pitch = 1f;
					val4.Play();
					Log.LogInfo((object)$"[NETWORK] Playing slow-motion audio from player {actorNumber} at position {position}");
					Log.LogInfo((object)$"[NETWORK] Player {actorNumber} now appears in slow-motion to you");
				}
				else if ((Object)(object)loadedClip == (Object)null)
				{
					Log.LogWarning((object)"[NETWORK] Audio clip not loaded for remote playback");
				}
				return;
			}
			activeSlowMotionPlayers.Remove(actorNumber);
			RemoveVisualSlowMotionFromPlayer(actorNumber);
			if (remoteSlowMotionSources.ContainsKey(text))
			{
				AudioSource val5 = remoteSlowMotionSources[text];
				if ((Object)(object)val5 != (Object)null && val5.isPlaying)
				{
					val5.Stop();
					Log.LogInfo((object)$"[NETWORK] Stopped slow-motion audio from player {actorNumber}");
					Log.LogInfo((object)$"[NETWORK] Player {actorNumber} returned to normal speed");
				}
			}
		}

		[PunRPC]
		public void PlaySlowMotionAudioNetwork(int actorNumber, Vector3 position, bool play)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			string text = $"Player_{actorNumber}";
			if (play)
			{
				if (!remoteAudioSources.ContainsKey(text))
				{
					GameObject val = new GameObject("RemoteAudio_" + text);
					Object.DontDestroyOnLoad((Object)(object)val);
					AudioSource val2 = val.AddComponent<AudioSource>();
					val2.spatialBlend = 1f;
					val2.minDistance = 5f;
					val2.maxDistance = AudioDistance.Value;
					val2.rolloffMode = (AudioRolloffMode)1;
					val2.playOnAwake = false;
					val2.loop = true;
					val2.priority = 128;
					val2.dopplerLevel = 0.5f;
					remoteAudioSources[text] = val;
					remoteSlowMotionSources[text] = val2;
				}
				GameObject val3 = remoteAudioSources[text];
				AudioSource val4 = remoteSlowMotionSources[text];
				val3.transform.position = position;
				if ((Object)(object)loadedClip != (Object)null)
				{
					val4.clip = loadedClip;
					val4.volume = 0.7f;
					val4.pitch = 1f;
					val4.Play();
					Log.LogInfo((object)$"[NETWORK] Playing slow-motion audio from player {actorNumber} at position {position}");
				}
				else
				{
					Log.LogWarning((object)"[NETWORK] Slow-motion audio clip not loaded for remote playback");
				}
			}
			else if (remoteSlowMotionSources.ContainsKey(text))
			{
				AudioSource val5 = remoteSlowMotionSources[text];
				if ((Object)(object)val5 != (Object)null && val5.isPlaying)
				{
					val5.Stop();
					Log.LogInfo((object)$"[NETWORK] Stopped slow-motion audio from player {actorNumber}");
				}
			}
		}

		[PunRPC]
		public void OnPlayerSlowMotionState(int actorNumber, bool isActive, float timeScale)
		{
			string text = $"Player_{actorNumber}";
			if (isActive)
			{
				Log.LogInfo((object)$"[NETWORK] Player {actorNumber} entered slow-motion (scale: {timeScale})");
				PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
				PhotonView[] array2 = array;
				foreach (PhotonView val in array2)
				{
					if ((Object)(object)val != (Object)null && val.Owner != null && val.Owner.ActorNumber == actorNumber)
					{
						Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>();
						if ((Object)(object)componentInChildren != (Object)null)
						{
							componentInChildren.speed = timeScale;
							Log.LogInfo((object)$"[NETWORK] Slowed animations for player {actorNumber}");
						}
						break;
					}
				}
				return;
			}
			Log.LogInfo((object)$"[NETWORK] Player {actorNumber} exited slow-motion");
			PhotonView[] array3 = Object.FindObjectsOfType<PhotonView>();
			PhotonView[] array4 = array3;
			foreach (PhotonView val2 in array4)
			{
				if ((Object)(object)val2 != (Object)null && val2.Owner != null && val2.Owner.ActorNumber == actorNumber)
				{
					Animator componentInChildren2 = ((Component)val2).GetComponentInChildren<Animator>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						componentInChildren2.speed = 1f;
						Log.LogInfo((object)$"[NETWORK] Restored normal animations for player {actorNumber}");
					}
					break;
				}
			}
		}

		[PunRPC]
		public void PlayHurtSoundNetwork(int actorNumber, int soundIndex, Vector3 position)
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			string text = $"Player_{actorNumber}";
			if (soundIndex < 0 || soundIndex >= hurtClips.Length || (Object)(object)hurtClips[soundIndex] == (Object)null)
			{
				Log.LogWarning((object)$"[NETWORK] Invalid hurt sound index {soundIndex} from player {actorNumber}");
				return;
			}
			string key = text + "_hurt";
			if (!remoteAudioSources.ContainsKey(key))
			{
				GameObject val = new GameObject("RemoteHurt_" + text);
				Object.DontDestroyOnLoad((Object)(object)val);
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.spatialBlend = 1f;
				val2.minDistance = 5f;
				val2.maxDistance = 50f;
				val2.rolloffMode = (AudioRolloffMode)1;
				val2.playOnAwake = false;
				val2.loop = false;
				val2.priority = 64;
				remoteAudioSources[key] = val;
				remoteHurtSources[key] = val2;
			}
			GameObject val3 = remoteAudioSources[key];
			AudioSource val4 = remoteHurtSources[key];
			val3.transform.position = position;
			val4.clip = hurtClips[soundIndex];
			val4.volume = 1f;
			val4.pitch = 1f;
			val4.Play();
			Log.LogInfo((object)$"[NETWORK] Playing hurt sound {soundIndex + 1} from player {actorNumber} at position {position}");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}