Decompiled source of Realism v3.3.0

Realism.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Realism;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(Mod), "Realism", "3.3.0", "Codex", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Realism
{
	public sealed class Mod : MelonMod
	{
		private enum MuzzleFlashStyle
		{
			Standard,
			CompactBurst,
			TaperedCone,
			SplitJet,
			Smoke
		}

		private sealed class TracerEffect
		{
			public object GameObject;

			public object OuterLineGameObject;

			public object CoreLineGameObject;

			public object Transform;

			public object OuterLine;

			public object CoreLine;

			public object Origin;

			public object Direction;

			public object Projectile;

			public object ProjectileTransform;

			public object ProjectileBody;

			public object LastPosition;

			public System.DateTime Started;

			public System.DateTime FinishedAt;

			public bool TrackingProjectile;

			public bool HasFinishedAt;

			public float Length;

			public float Speed;

			public float Life;

			public float HeadSize;

			public float OuterStartWidth;

			public float OuterEndWidth;

			public float CoreStartWidth;

			public float CoreEndWidth;
		}

		private sealed class ProjectileCandidate
		{
			public object Projectile;

			public object Transform;

			public object Rigidbody;

			public object Position;

			public object Direction;

			public float Speed;
		}

		private sealed class SparkEffect
		{
			public object GameObject;

			public object TailGameObject;

			public object Transform;

			public object TailTransform;

			public object Origin;

			public object Direction;

			public System.DateTime Started;

			public float Life;

			public float Length;

			public float Speed;

			public float HeadSize;

			public float TailWidth;
		}

		private sealed class SmokePuff
		{
			public object GameObject;

			public object Transform;

			public object Material;

			public object Origin;

			public object Velocity;

			public System.DateTime Started;

			public float Life;

			public float Size;

			public float Alpha;
		}

		private static bool earRingingEnabled = true;

		private static bool muzzleFlashEnabled = true;

		private static bool sparksEnabled = true;

		private static bool smokeEnabled = true;

		private static bool tracersEnabled = true;

		private static MuzzleFlashStyle muzzleFlashStyle = MuzzleFlashStyle.Standard;

		private static float ringingVolumeSetting = 100f;

		private const float RemoteRingingRange = 18f;

		private static System.Delegate fireHandler;

		private static System.Type boneMenu;

		private static System.Type pageType;

		private static System.Type unityObject;

		private static System.Type gameObjectType;

		private static System.Type vector3Type;

		private static object modPage;

		private static Mod instance;

		private static bool eventSubscribed;

		private static bool shotErrorLogged;

		private static bool shotHookObservedLogged;

		private static bool remoteShotObservedLogged;

		private static bool audioErrorLogged;

		private static bool visualErrorLogged;

		private static bool tracerSpawnLogged;

		private static bool tracerUpdateLogged;

		private static bool tracerShaderLogged;

		private static bool tracerProjectileLookupLogged;

		private static bool remoteVisualsLogged;

		private static bool remoteRingingLogged;

		private static bool remoteDistantRingingSuppressedLogged;

		private static bool? mobilePlatformCache;

		private static bool projectileTypesScanned;

		private static System.Type[] projectileTypes = System.Array.Empty<System.Type>();

		private static readonly object[] muzzleStyleMenuElements = new object[5];

		private static readonly HashSet<MuzzleFlashStyle> muzzleFlashStylesLogged = new HashSet<MuzzleFlashStyle>();

		private static readonly ConcurrentQueue<object> pendingGunFires = new ConcurrentQueue<object>();

		private static object ringingGameObject;

		private static object ringingSource;

		private static object ringingClip;

		private static float ringingLevel;

		private static float ringingVolume;

		private static System.DateTime ringingUpdated = System.DateTime.MinValue;

		private static readonly Random effectRandom = new Random();

		private static readonly Dictionary<string, object> materialCache = new Dictionary<string, object>();

		private static readonly Dictionary<string, object> tracerMaterialCache = new Dictionary<string, object>();

		private static readonly List<TracerEffect> tracers = new List<TracerEffect>();

		private static readonly List<SparkEffect> sparks = new List<SparkEffect>();

		private static readonly List<SmokePuff> smokePuffs = new List<SmokePuff>();

		public override void OnInitializeMelon()
		{
			instance = this;
			((MelonBase)this).LoggerInstance.Msg("Realism 3.3.0 loaded; BoneMenu setup will retry until BoneLib is ready.");
			if (FindType("LabFusion.Entities.NetworkPlayerManager") != (System.Type)null)
			{
				((MelonBase)this).LoggerInstance.Msg("LabFusion detected; Realism effects are generated locally from BoneLib gun-fire events, including replicated shots.");
			}
			TryBuildMenu();
			TrySubscribeToGunFire();
		}

		public override void OnUpdate()
		{
			if (modPage == null)
			{
				TryBuildMenu();
			}
			if (!eventSubscribed)
			{
				TrySubscribeToGunFire();
			}
			ProcessPendingGunFires();
			UpdateRinging();
			UpdateTracers();
			UpdateSparks();
			UpdateSmoke();
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			ClearSceneVisuals();
			object obj = default(object);
			while (pendingGunFires.TryDequeue(ref obj))
			{
			}
			((MelonBase)this).LoggerInstance.Msg("Scene unloading (" + sceneName + "); cleared transient Realism visuals and queued shots.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			gameObjectType = FindType("UnityEngine.GameObject");
			unityObject = FindType("UnityEngine.Object");
			vector3Type = FindType("UnityEngine.Vector3");
			shotHookObservedLogged = false;
			tracerSpawnLogged = false;
			tracerUpdateLogged = false;
			tracerShaderLogged = false;
			tracerProjectileLookupLogged = false;
			visualErrorLogged = false;
			RebindGunFireAfterSceneChange();
			((MelonBase)this).LoggerInstance.Msg("Scene loaded (" + sceneName + "); refreshed Realism visual references and gun-fire hook.");
		}

		private static void ClearSceneVisuals()
		{
			//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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TracerEffect> enumerator = tracers.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TracerEffect current = enumerator.Current;
					Destroy(current.GameObject, 0f);
					Destroy(current.OuterLineGameObject, 0f);
					Destroy(current.CoreLineGameObject, 0f);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			tracers.Clear();
			Enumerator<SparkEffect> enumerator2 = sparks.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					SparkEffect current2 = enumerator2.Current;
					Destroy(current2.GameObject, 0f);
					Destroy(current2.TailGameObject, 0f);
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			sparks.Clear();
			Enumerator<SmokePuff> enumerator3 = smokePuffs.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					SmokePuff current3 = enumerator3.Current;
					Destroy(current3.GameObject, 0f);
				}
			}
			finally
			{
				((System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
			smokePuffs.Clear();
			Enumerator<string, object> enumerator4 = tracerMaterialCache.Values.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					object current4 = enumerator4.Current;
					Destroy(current4, 0f);
				}
			}
			finally
			{
				((System.IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose();
			}
			tracerMaterialCache.Clear();
			Enumerator<string, object> enumerator5 = materialCache.Values.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					object current5 = enumerator5.Current;
					Destroy(current5, 0f);
				}
			}
			finally
			{
				((System.IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose();
			}
			materialCache.Clear();
		}

		private void RebindGunFireAfterSceneChange()
		{
			try
			{
				EventInfo val = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.Hooking", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null))?.GetEvent("OnPostFireGun", (BindingFlags)24);
				if (val != (EventInfo)null && fireHandler != null)
				{
					try
					{
						val.RemoveEventHandler((object)null, fireHandler);
					}
					catch
					{
					}
				}
				eventSubscribed = false;
				fireHandler = null;
				TrySubscribeToGunFire();
			}
			catch (System.Exception ex)
			{
				eventSubscribed = false;
				((MelonBase)this).LoggerInstance.Warning("Gun-fire hook refresh failed after scene change: " + ex.GetBaseException().Message);
			}
		}

		private void TryBuildMenu()
		{
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				boneMenu = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.BoneMenu.Menu", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
				pageType = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.BoneMenu.Page", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
				if (boneMenu == (System.Type)null || pageType == (System.Type)null)
				{
					return;
				}
				PropertyInfo property = pageType.GetProperty("Root", (BindingFlags)24);
				object obj = ((property != null) ? property.GetValue((object)null) : null);
				if (obj == null)
				{
					return;
				}
				MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreatePage" && ((MethodBase)m).GetParameters().Length != 0 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(string)));
				if (val == (MethodInfo)null)
				{
					return;
				}
				System.Type type = FindType("UnityEngine.Color");
				object obj2;
				if (type == null)
				{
					obj2 = null;
				}
				else
				{
					PropertyInfo property2 = type.GetProperty("white", (BindingFlags)24);
					obj2 = ((property2 != null) ? property2.GetValue((object)null) : null);
				}
				object color = obj2;
				object parent = CreateBoneMenuPage(val, obj, "Realism", type, color);
				object page = CreateBoneMenuPage(val, parent, "Ear Ringing", type, color);
				object page2 = CreateBoneMenuPage(val, parent, "Muzzle Flash", type, color);
				object page3 = CreateBoneMenuPage(val, parent, "Sparks", type, color);
				object page4 = CreateBoneMenuPage(val, parent, "Smoke", type, color);
				object page5 = CreateBoneMenuPage(val, parent, "Bullet Tracers", type, color);
				MethodInfo val2 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreateBool"));
				MethodInfo val3 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreateFloat" && Enumerable.Count<ParameterInfo>((System.Collections.Generic.IEnumerable<ParameterInfo>)((MethodBase)m).GetParameters(), (Func<ParameterInfo, bool>)((ParameterInfo p) => p.ParameterType == typeof(float))) == 4));
				if (val2 == (MethodInfo)null || val3 == (MethodInfo)null)
				{
					throw new MissingMethodException("BoneLib menu setting methods were unavailable.");
				}
				CreateBoneMenuBool(val2, page, "Enabled", type, color, earRingingEnabled, [CompilerGenerated] (bool value) =>
				{
					earRingingEnabled = value;
					((MelonBase)this).LoggerInstance.Msg("Ear ringing " + (value ? "enabled" : "disabled") + ".");
				});
				CreateBoneMenuFloat(val3, page, "Volume (%)", type, color, ringingVolumeSetting, 5f, 0f, 100f, [CompilerGenerated] (float value) =>
				{
					ringingVolumeSetting = value;
					((MelonBase)this).LoggerInstance.Msg($"Ear ringing volume set to {value:0}%.");
				});
				CreateBoneMenuBool(val2, page2, "Enabled", type, color, muzzleFlashEnabled, [CompilerGenerated] (bool value) =>
				{
					muzzleFlashEnabled = value;
					((MelonBase)this).LoggerInstance.Msg("Muzzle flash " + (value ? "enabled" : "disabled") + ".");
				});
				AddMuzzleFlashStyleToggles(val2, page2, type, color);
				CreateBoneMenuBool(val2, page3, "Enabled", type, color, sparksEnabled, [CompilerGenerated] (bool value) =>
				{
					sparksEnabled = value;
					((MelonBase)this).LoggerInstance.Msg("Sparks " + (value ? "enabled" : "disabled") + ".");
				});
				CreateBoneMenuBool(val2, page4, "Enabled", type, color, smokeEnabled, [CompilerGenerated] (bool value) =>
				{
					smokeEnabled = value;
					((MelonBase)this).LoggerInstance.Msg("Smoke " + (value ? "enabled" : "disabled") + ".");
				});
				CreateBoneMenuBool(val2, page5, "Enabled", type, color, tracersEnabled, [CompilerGenerated] (bool value) =>
				{
					tracersEnabled = value;
					((MelonBase)this).LoggerInstance.Msg("Bullet tracers " + (value ? "enabled" : "disabled") + ".");
				});
				modPage = parent;
				((MelonBase)this).LoggerInstance.Msg("Realism BoneMenu pages for ringing, selectable muzzle flash styles, sparks, smoke and tracers added. Choose one of the four style toggles; its check mark marks the active style.");
			}
			catch (System.Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("BoneMenu setup will retry: " + ex.GetBaseException().Message);
			}
		}

		private static object CreateBoneMenuPage(MethodInfo method, object parent, string name, System.Type colorType, object color)
		{
			ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
			object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
			for (int num = 0; num < parameters.Length; num++)
			{
				if (parameters[num].ParameterType == typeof(string))
				{
					array[num] = name;
				}
				else if (colorType != (System.Type)null && parameters[num].ParameterType == colorType && color != null)
				{
					array[num] = color;
				}
			}
			return ((MethodBase)method).Invoke(parent, array);
		}

		private static object CreateBoneMenuBool(MethodInfo method, object page, string name, System.Type colorType, object color, bool value, Action<bool> callback)
		{
			ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
			object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
			for (int num = 0; num < parameters.Length; num++)
			{
				if (parameters[num].ParameterType == typeof(string))
				{
					array[num] = name;
				}
				else if (parameters[num].ParameterType == typeof(bool))
				{
					array[num] = value;
				}
				else if (colorType != (System.Type)null && parameters[num].ParameterType == colorType && color != null)
				{
					array[num] = color;
				}
				else if (typeof(System.Delegate).IsAssignableFrom(parameters[num].ParameterType))
				{
					array[num] = callback;
				}
			}
			return ((MethodBase)method).Invoke(page, array);
		}

		private static void CreateBoneMenuFloat(MethodInfo method, object page, string name, System.Type colorType, object color, float value, float increment, float min, float max, Action<float> callback)
		{
			ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
			object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
			float[] array2 = new float[4] { value, increment, min, max };
			int num = 0;
			for (int num2 = 0; num2 < parameters.Length; num2++)
			{
				if (parameters[num2].ParameterType == typeof(string))
				{
					array[num2] = name;
				}
				else if (parameters[num2].ParameterType == typeof(float) && num < array2.Length)
				{
					array[num2] = array2[num++];
				}
				else if (colorType != (System.Type)null && parameters[num2].ParameterType == colorType && color != null)
				{
					array[num2] = color;
				}
				else if (typeof(System.Delegate).IsAssignableFrom(parameters[num2].ParameterType))
				{
					array[num2] = callback;
				}
			}
			((MethodBase)method).Invoke(page, array);
		}

		private static void AddMuzzleFlashStyleToggles(MethodInfo createBool, object page, System.Type colorType, object color)
		{
			MuzzleFlashStyle[] array = (MuzzleFlashStyle[])System.Enum.GetValues(typeof(MuzzleFlashStyle));
			for (int i = 0; i < array.Length; i++)
			{
				MuzzleFlashStyle style = array[i];
				int index = i;
				string name = style switch
				{
					MuzzleFlashStyle.Standard => "Standard", 
					MuzzleFlashStyle.CompactBurst => "Compact Burst", 
					MuzzleFlashStyle.TaperedCone => "Tapered Cone", 
					MuzzleFlashStyle.SplitJet => "Split Jet", 
					MuzzleFlashStyle.Smoke => "Smoke", 
					_ => "Smoke", 
				};
				muzzleStyleMenuElements[index] = CreateBoneMenuBool(createBool, page, name, colorType, color, muzzleFlashStyle == style, delegate(bool enabled)
				{
					if (enabled)
					{
						SelectMuzzleFlashStyle(style);
					}
					else if (muzzleFlashStyle == style && muzzleStyleMenuElements[index] != null)
					{
						Set(muzzleStyleMenuElements[index], "Value", true);
					}
				});
			}
		}

		private static void SelectMuzzleFlashStyle(MuzzleFlashStyle style)
		{
			muzzleFlashStyle = style;
			for (int i = 0; i < muzzleStyleMenuElements.Length; i++)
			{
				if (muzzleStyleMenuElements[i] != null)
				{
					Set(muzzleStyleMenuElements[i], "Value", i == (int)style);
				}
			}
			Mod mod = instance;
			if (mod != null)
			{
				((MelonBase)mod).LoggerInstance.Msg($"Selected muzzle flash style: {style}.");
			}
		}

		private void TrySubscribeToGunFire()
		{
			try
			{
				EventInfo val = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.Hooking", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null))?.GetEvent("OnPostFireGun", (BindingFlags)24);
				if (!(val == (EventInfo)null))
				{
					MethodInfo method = val.EventHandlerType.GetMethod("Invoke");
					ParameterExpression val2 = Expression.Parameter(((MethodBase)method).GetParameters()[0].ParameterType, "gun");
					MethodInfo method2 = typeof(Mod).GetMethod("OnGunFired", (BindingFlags)40);
					fireHandler = Expression.Lambda(val.EventHandlerType, (Expression)(object)Expression.Call(method2, (Expression)(object)Expression.Convert((Expression)(object)val2, typeof(object))), (ParameterExpression[])(object)new ParameterExpression[1] { val2 }).Compile();
					val.AddEventHandler((object)null, fireHandler);
					eventSubscribed = true;
					((MelonBase)this).LoggerInstance.Msg("Connected to BoneLib gun-fire events.");
				}
			}
			catch (System.Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Gun-fire hook unavailable: " + ex.GetBaseException().Message);
			}
		}

		private static void OnGunFired(object gun)
		{
			if (gun != null)
			{
				pendingGunFires.Enqueue(gun);
			}
		}

		private static void ProcessPendingGunFires()
		{
			int num = 0;
			object gun = default(object);
			while (num < 32 && pendingGunFires.TryDequeue(ref gun))
			{
				num++;
				HandleGunFired(gun);
			}
		}

		private static void HandleGunFired(object gun)
		{
			try
			{
				if (gun == null)
				{
					return;
				}
				if (!shotHookObservedLogged)
				{
					shotHookObservedLogged = true;
					Mod mod = instance;
					if (mod != null)
					{
						((MelonBase)mod).LoggerInstance.Msg("Received the first gun-fire event; processing enabled Realism effects.");
					}
				}
				bool flag = IsRemoteGunShot(gun);
				if (flag && !remoteShotObservedLogged)
				{
					remoteShotObservedLogged = true;
					Mod mod2 = instance;
					if (mod2 != null)
					{
						((MelonBase)mod2).LoggerInstance.Msg("Received a replicated Fusion gun shot; rendering local Realism effects for it.");
					}
				}
				gameObjectType = FindType("UnityEngine.GameObject");
				unityObject = FindType("UnityEngine.Object");
				vector3Type = FindType("UnityEngine.Vector3");
				bool fusionActive = FindType("LabFusion.Entities.NetworkPlayerManager") != (System.Type)null;
				if (muzzleFlashEnabled || sparksEnabled || smokeEnabled || tracersEnabled)
				{
					try
					{
						SpawnShotVisuals(gun, muzzleFlashEnabled, sparksEnabled, smokeEnabled, tracersEnabled, fusionActive);
						if (flag && !remoteVisualsLogged)
						{
							remoteVisualsLogged = true;
							Mod mod3 = instance;
							if (mod3 != null)
							{
								((MelonBase)mod3).LoggerInstance.Msg("Generated the enabled Realism visual effects for the first replicated Fusion shot.");
							}
						}
					}
					catch (System.Exception error)
					{
						LogEffectError(ref visualErrorLogged, "muzzle flash/sparks/smoke/tracer", error);
					}
				}
				if (!earRingingEnabled || !ShouldRingForShot(gun, flag))
				{
					return;
				}
				try
				{
					RaiseRinging();
					if (flag && !remoteRingingLogged)
					{
						remoteRingingLogged = true;
						Mod mod4 = instance;
						if (mod4 != null)
						{
							((MelonBase)mod4).LoggerInstance.Msg("Applied Realism ear ringing for the first replicated Fusion shot.");
						}
					}
				}
				catch (System.Exception error2)
				{
					LogEffectError(ref audioErrorLogged, "audio", error2);
				}
			}
			catch (System.Exception ex)
			{
				if (!shotErrorLogged)
				{
					shotErrorLogged = true;
					Mod mod5 = instance;
					if (mod5 != null)
					{
						((MelonBase)mod5).LoggerInstance.Warning("Realism shot effect failed: " + ex.GetBaseException().Message);
					}
				}
			}
		}

		private static System.Type FindType(string fullName)
		{
			return Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType(fullName, false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
		}

		private static bool IsUnityObjectAlive(object value)
		{
			if (value == null)
			{
				return false;
			}
			System.Type objectType = FindType("UnityEngine.Object");
			if (objectType == (System.Type)null || !objectType.IsInstanceOfType(value))
			{
				return true;
			}
			MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)objectType.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "op_Equality" && ((MethodBase)m).GetParameters().Length == 2 && Enumerable.All<ParameterInfo>((System.Collections.Generic.IEnumerable<ParameterInfo>)((MethodBase)m).GetParameters(), (Func<ParameterInfo, bool>)((ParameterInfo p) => p.ParameterType == objectType))));
			try
			{
				return val == (MethodInfo)null || !Convert.ToBoolean(((MethodBase)val).Invoke((object)null, new object[2] { value, null }));
			}
			catch
			{
				return false;
			}
		}

		private static void ResetRingingAudio()
		{
			if (IsUnityObjectAlive(ringingGameObject))
			{
				Destroy(ringingGameObject, 0f);
			}
			else if (IsUnityObjectAlive(ringingClip))
			{
				Destroy(ringingClip, 0f);
			}
			ringingGameObject = (ringingSource = (ringingClip = null));
			ringingLevel = (ringingVolume = 0f);
			ringingUpdated = System.DateTime.MinValue;
		}

		private static bool IsRemoteGunShot(object gun)
		{
			if (FindType("LabFusion.Entities.NetworkPlayerManager") == (System.Type)null)
			{
				return false;
			}
			try
			{
				return IsRemoteFiringHand(GetFiringHand(gun));
			}
			catch
			{
				return false;
			}
		}

		private static bool ShouldRingForShot(object gun, bool isRemoteShot)
		{
			if (!isRemoteShot)
			{
				return true;
			}
			try
			{
				System.Type type = FindType("BoneLib.Player");
				object obj;
				if (type == null)
				{
					obj = null;
				}
				else
				{
					PropertyInfo property = type.GetProperty("Head", (BindingFlags)24);
					obj = ((property != null) ? property.GetValue((object)null) : null);
				}
				object o = obj;
				object obj2 = Get(o, "position");
				if (obj2 == null)
				{
					object obj3;
					if (type == null)
					{
						obj3 = null;
					}
					else
					{
						PropertyInfo property2 = type.GetProperty("RigManager", (BindingFlags)24);
						obj3 = ((property2 != null) ? property2.GetValue((object)null) : null);
					}
					object o2 = obj3;
					obj2 = Get(Get(o2, "transform"), "position");
				}
				object obj4 = Get(GetFireTransform(gun), "position");
				vector3Type = vector3Type ?? FindType("UnityEngine.Vector3");
				if (obj2 == null || obj4 == null || vector3Type == (System.Type)null)
				{
					return false;
				}
				MethodInfo method = vector3Type.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
				if (method == (MethodInfo)null)
				{
					return false;
				}
				float num = Convert.ToSingle(((MethodBase)method).Invoke((object)null, new object[2] { obj2, obj4 }));
				if (num <= 18f)
				{
					return true;
				}
				if (!remoteDistantRingingSuppressedLogged)
				{
					remoteDistantRingingSuppressedLogged = true;
					Mod mod = instance;
					if (mod != null)
					{
						((MelonBase)mod).LoggerInstance.Msg($"Suppressed distant Fusion ear ringing ({num:0.0} units away; limit {18f:0} units).");
					}
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		private static void LogEffectError(ref bool alreadyLogged, string effect, System.Exception error)
		{
			if (!alreadyLogged)
			{
				alreadyLogged = true;
				Mod mod = instance;
				if (mod != null)
				{
					((MelonBase)mod).LoggerInstance.Warning("Realism " + effect + " failed: " + error.GetBaseException().Message);
				}
			}
		}

		private static object Get(object o, string name)
		{
			if (o == null)
			{
				return null;
			}
			PropertyInfo property = o.GetType().GetProperty(name, (BindingFlags)52);
			object obj = ((property != null) ? property.GetValue(o) : null);
			if (obj == null)
			{
				FieldInfo field = o.GetType().GetField(name, (BindingFlags)52);
				obj = ((field != null) ? field.GetValue(o) : null);
			}
			return obj;
		}

		private static object Call(object o, string name, params object[] args)
		{
			object result;
			if (o == null)
			{
				result = null;
			}
			else
			{
				MethodInfo obj = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)o.GetType().GetMethods((BindingFlags)20), (Func<MethodInfo, bool>)delegate(MethodInfo m)
				{
					if (((MemberInfo)m).Name != name || ((MethodBase)m).GetParameters().Length != args.Length)
					{
						return false;
					}
					ParameterInfo[] parameters = ((MethodBase)m).GetParameters();
					return Enumerable.All<bool>(Enumerable.Select<ParameterInfo, bool>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, int, bool>)((ParameterInfo p, int i) => args[i] == null || p.ParameterType.IsInstanceOfType(args[i]) || (args[i] is System.Type && p.ParameterType == typeof(System.Type)))), (Func<bool, bool>)((bool ok) => ok));
				});
				result = ((obj != null) ? ((MethodBase)obj).Invoke(o, args) : null);
			}
			return result;
		}

		private static object AddUnityComponent(object gameObject, System.Type componentType)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (gameObject == null || componentType == (System.Type)null)
			{
				return null;
			}
			MethodInfo[] methods = gameObject.GetType().GetMethods((BindingFlags)20);
			System.Exception ex = null;
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "AddComponent" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					MethodInfo current = enumerator.Current;
					try
					{
						return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { componentType })).Invoke(gameObject, (object[])null);
					}
					catch (System.Exception ex2)
					{
						ex = ex2.GetBaseException();
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "AddComponent" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator2).MoveNext())
				{
					MethodInfo current2 = enumerator2.Current;
					try
					{
						return ((MethodBase)current2).Invoke(gameObject, new object[1] { componentType });
					}
					catch (System.Exception ex3)
					{
						ex = ex3.GetBaseException();
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator2)?.Dispose();
			}
			throw new InvalidOperationException("Unity AddComponent could not create " + componentType.FullName + ".", (System.Exception)(((object)ex) ?? ((object)new MissingMethodException(gameObject.GetType().FullName, "AddComponent<T>()"))));
		}

		private static object GetUnityComponent(object gameObject, System.Type componentType)
		{
			if (gameObject == null || componentType == (System.Type)null)
			{
				return null;
			}
			MethodInfo[] methods = gameObject.GetType().GetMethods((BindingFlags)20);
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "GetComponent" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					MethodInfo current = enumerator.Current;
					try
					{
						return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { componentType })).Invoke(gameObject, (object[])null);
					}
					catch
					{
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "GetComponent" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator2).MoveNext())
				{
					MethodInfo current2 = enumerator2.Current;
					try
					{
						return ((MethodBase)current2).Invoke(gameObject, new object[1] { componentType });
					}
					catch
					{
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator2)?.Dispose();
			}
			return null;
		}

		private static object FindUnityObject(System.Type targetType)
		{
			System.Type type = FindType("UnityEngine.Object");
			if (type == (System.Type)null || targetType == (System.Type)null)
			{
				return null;
			}
			MethodInfo[] methods = type.GetMethods((BindingFlags)24);
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectOfType" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					MethodInfo current = enumerator.Current;
					try
					{
						return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { targetType })).Invoke((object)null, (object[])null);
					}
					catch
					{
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
			System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectOfType" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator2).MoveNext())
				{
					MethodInfo current2 = enumerator2.Current;
					try
					{
						return ((MethodBase)current2).Invoke((object)null, new object[1] { targetType });
					}
					catch
					{
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator2)?.Dispose();
			}
			return null;
		}

		private static object NewVector(float x, float y, float z)
		{
			return Activator.CreateInstance(vector3Type, new object[3] { x, y, z });
		}

		private static object GetFireTransform(object gun)
		{
			return Get(gun, "firePointTransform") ?? FindMuzzleTransform(Get(gun, "transform")) ?? Get(gun, "transform");
		}

		private static bool IsMobilePlatform()
		{
			if (mobilePlatformCache.HasValue)
			{
				return mobilePlatformCache.Value;
			}
			try
			{
				PropertyInfo val = FindType("UnityEngine.Application")?.GetProperty("isMobilePlatform", (BindingFlags)24);
				mobilePlatformCache = Convert.ToBoolean(((val != null) ? val.GetValue((object)null) : null) ?? ((object)false));
			}
			catch
			{
				mobilePlatformCache = false;
			}
			return mobilePlatformCache.Value;
		}

		private static void SpawnShotVisuals(object gun, bool spawnMuzzleFlash, bool spawnSparks, bool spawnSmoke, bool spawnTracer, bool fusionActive)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			object fireTransform = GetFireTransform(gun);
			object obj = Get(fireTransform, "position");
			object obj2 = Get(fireTransform, "forward");
			if (obj == null || obj2 == null)
			{
				throw new InvalidOperationException("Gun firePointTransform was unavailable.");
			}
			object obj3 = Get(fireTransform, "right");
			object obj4 = Get(fireTransform, "up");
			object obj5 = OffsetVector(obj, obj2, 0.025f);
			MuzzleFlashStyle muzzleFlashStyle = Mod.muzzleFlashStyle;
			if (spawnMuzzleFlash)
			{
				SpawnMuzzleFlash(obj5, obj2, obj3, obj4, muzzleFlashStyle);
				if (muzzleFlashStylesLogged.Add(muzzleFlashStyle))
				{
					Mod mod = instance;
					if (mod != null)
					{
						((MelonBase)mod).LoggerInstance.Msg($"Rendered muzzle flash profile: {muzzleFlashStyle}.");
					}
				}
			}
			bool flag = IsMobilePlatform();
			if (spawnSparks && (!spawnMuzzleFlash || muzzleFlashStyle != MuzzleFlashStyle.Smoke))
			{
				int num = (flag ? 3 : 8);
				for (int i = 0; i < num; i++)
				{
					float rightScale = (float)(effectRandom.NextDouble() * 1.6 - 0.8);
					float upScale = (float)(effectRandom.NextDouble() * 1.6 - 0.8);
					float forwardScale = 0.35f + (float)effectRandom.NextDouble() * 0.65f;
					object direction = CombineDirections(obj2, obj3, rightScale, obj4, upScale, forwardScale);
					SpawnSpark(obj5, direction, 0.21f + (float)effectRandom.NextDouble() * 0.19f);
				}
			}
			if (spawnSmoke && (!spawnMuzzleFlash || muzzleFlashStyle != MuzzleFlashStyle.Smoke))
			{
				int num2 = 3;
				float num3 = 1f;
				float num4 = 1f;
				float num5 = 0.038f;
				float num6 = 0.2f;
				switch (muzzleFlashStyle)
				{
				case MuzzleFlashStyle.CompactBurst:
					num2 = (flag ? 1 : 2);
					num3 = 0.72f;
					num4 = 0.78f;
					num5 = 0.022f;
					num6 = 0.12f;
					break;
				case MuzzleFlashStyle.TaperedCone:
					num2 = (flag ? 3 : 5);
					num3 = 1.2f;
					num4 = 1.25f;
					num5 = 0.034f;
					num6 = 0.2f;
					break;
				case MuzzleFlashStyle.SplitJet:
					num2 = (flag ? 2 : 4);
					num3 = 1.04f;
					num4 = 1.08f;
					num5 = 0.09f;
					num6 = 1.15f;
					break;
				}
				for (int j = 0; j < num2; j++)
				{
					float distance = ((num2 == 1) ? 0f : (((float)j - (float)(num2 - 1) * 0.5f) * num5));
					float distance2 = (float)(effectRandom.NextDouble() * 0.025 - 0.0125);
					object position = OffsetVector(OffsetVector(OffsetVector(obj5, obj3, distance), obj4, distance2), obj2, 0.025f * (float)j);
					float rightScale2 = (float)(effectRandom.NextDouble() * 0.07 - 0.035) * num6;
					object velocity = CombineDirections(obj2, obj3, rightScale2, obj4, 0.045f + (float)effectRandom.NextDouble() * 0.035f, 0.025f);
					SpawnSmoke(position, (0.055f + 0.008f * (float)j) * num3, (0.5f + 0.08f * (float)j) * num4, velocity);
				}
			}
			if (spawnTracer)
			{
				ProjectileCandidate projectileCandidate = FindFiredProjectile(obj5, obj2);
				object start = projectileCandidate?.Position ?? OffsetVector(obj5, obj2, flag ? 0.09f : 0.12f);
				SpawnTracer(start, projectileCandidate?.Direction ?? obj2, fusionActive, projectileCandidate);
			}
		}

		private static void SpawnMuzzleFlash(object position, object direction, object right, object up, MuzzleFlashStyle style)
		{
			switch (style)
			{
			case MuzzleFlashStyle.CompactBurst:
			{
				object obj = OffsetVector(position, direction, 0.045f);
				SpawnFlashOrb(obj, direction, 0.17f, 0.17f, 0.15f, 1f, 0.96f, 0.72f, 22f, 0.19f);
				SpawnFlashCapsule(OffsetVector(obj, right, -0.075f), CombineDirections(direction, right, -1.55f), 0.095f, 0.38f, 1f, 0.64f, 0.18f, 15f, 0.18f);
				SpawnFlashCapsule(OffsetVector(obj, right, 0.075f), CombineDirections(direction, right, 1.55f), 0.095f, 0.38f, 1f, 0.64f, 0.18f, 15f, 0.18f);
				SpawnFlashCapsule(OffsetVector(obj, up, -0.075f), CombineDirections(direction, up, -1.55f), 0.095f, 0.38f, 1f, 0.72f, 0.22f, 15f, 0.18f);
				SpawnFlashCapsule(OffsetVector(obj, up, 0.075f), CombineDirections(direction, up, 1.55f), 0.095f, 0.38f, 1f, 0.72f, 0.22f, 15f, 0.18f);
				AddMuzzleLight(position, 1f, 0.72f, 0.38f, 7f, 4.2f, 0.17f);
				break;
			}
			case MuzzleFlashStyle.TaperedCone:
				SpawnFlashOrb(OffsetVector(position, direction, 0.045f), direction, 0.105f, 0.105f, 0.14f, 1f, 0.98f, 0.78f, 24f, 0.19f);
				SpawnFlashCylinder(OffsetVector(position, direction, 0.16f), direction, 0.205f, 0.28f, 1f, 0.69f, 0.2f, 18f, 0.18f);
				SpawnFlashCylinder(OffsetVector(position, direction, 0.37f), direction, 0.145f, 0.3f, 1f, 0.52f, 0.11f, 14f, 0.18f);
				SpawnFlashCylinder(OffsetVector(position, direction, 0.59f), direction, 0.082f, 0.28f, 1f, 0.35f, 0.065f, 10f, 0.17f);
				AddMuzzleLight(position, 1f, 0.48f, 0.16f, 6.8f, 4.4f, 0.17f);
				break;
			case MuzzleFlashStyle.SplitJet:
				SpawnFlashOrb(OffsetVector(position, direction, 0.045f), direction, 0.11f, 0.11f, 0.13f, 1f, 0.98f, 0.78f, 22f, 0.19f);
				SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.13f), right, -0.09f), CombineDirections(direction, right, -1.85f), 0.135f, 0.64f, 1f, 0.43f, 0.075f, 16f, 0.18f);
				SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.13f), right, 0.09f), CombineDirections(direction, right, 1.85f), 0.135f, 0.64f, 1f, 0.43f, 0.075f, 16f, 0.18f);
				SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.34f), right, -0.24f), CombineDirections(direction, right, -2.65f), 0.075f, 0.34f, 1f, 0.43f, 0.075f, 12f, 0.17f);
				SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.34f), right, 0.24f), CombineDirections(direction, right, 2.65f), 0.075f, 0.34f, 1f, 0.43f, 0.075f, 12f, 0.17f);
				AddMuzzleLight(position, 1f, 0.55f, 0.22f, 7f, 4.2f, 0.17f);
				break;
			case MuzzleFlashStyle.Smoke:
				SpawnSmokeOnlyFlash(position, direction, right, up);
				break;
			default:
				SpawnGlow(position, direction, right, up);
				break;
			}
		}

		private static System.Type[] GetProjectileTypes()
		{
			//IL_0070: Expected O, but got Unknown
			if (projectileTypesScanned)
			{
				return projectileTypes;
			}
			projectileTypesScanned = true;
			System.Type type = FindType("UnityEngine.Component");
			if (type == (System.Type)null)
			{
				return projectileTypes;
			}
			List<System.Type> val = new List<System.Type>();
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly val2 in assemblies)
			{
				System.Type[] array;
				try
				{
					array = val2.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					ReflectionTypeLoadException ex2 = ex;
					array = Enumerable.ToArray<System.Type>(Enumerable.Where<System.Type>((System.Collections.Generic.IEnumerable<System.Type>)ex2.Types, (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null)));
				}
				catch
				{
					continue;
				}
				System.Type[] array2 = array;
				foreach (System.Type type2 in array2)
				{
					if (!(type2 == (System.Type)null) && !type2.IsAbstract && !type2.ContainsGenericParameters && type.IsAssignableFrom(type2) && ((MemberInfo)type2).Name.IndexOf("Projectile", (StringComparison)5) >= 0)
					{
						val.Add(type2);
					}
				}
			}
			projectileTypes = Enumerable.ToArray<System.Type>((System.Collections.Generic.IEnumerable<System.Type>)Enumerable.OrderBy<System.Type, int>((System.Collections.Generic.IEnumerable<System.Type>)val, (Func<System.Type, int>)((System.Type t) => (!((MemberInfo)t).Name.Equals("Projectile", (StringComparison)5)) ? 1 : 0)));
			return projectileTypes;
		}

		private static ProjectileCandidate FindFiredProjectile(object muzzle, object forward)
		{
			System.Type type = FindType("UnityEngine.Object");
			System.Type type2 = FindType("UnityEngine.Rigidbody");
			MethodInfo method = vector3Type.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
			MethodInfo method2 = vector3Type.GetMethod("Dot", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
			if (type == (System.Type)null || type2 == (System.Type)null || method == (MethodInfo)null || method2 == (MethodInfo)null)
			{
				return null;
			}
			MethodInfo[] array = Enumerable.ToArray<MethodInfo>(Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectsOfType" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length >= 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))));
			ProjectileCandidate projectileCandidate = null;
			float num = 3.4028235E+38f;
			System.Type[] array2 = GetProjectileTypes();
			foreach (System.Type type3 in array2)
			{
				object obj = null;
				MethodInfo[] array3 = array;
				foreach (MethodInfo val in array3)
				{
					try
					{
						ParameterInfo[] parameters = ((MethodBase)val).GetParameters();
						obj = ((MethodBase)val).Invoke((object)null, (parameters.Length != 1) ? new object[2] { type3, false } : new object[1] { type3 });
						if (obj != null)
						{
							break;
						}
					}
					catch
					{
					}
				}
				if (!(obj is System.Collections.IEnumerable enumerable))
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					if (item == null)
					{
						continue;
					}
					object obj3 = Get(item, "transform");
					object unityComponent = GetUnityComponent(item, type2);
					if (obj3 == null || unityComponent == null)
					{
						continue;
					}
					object obj4 = Get(obj3, "position");
					object o = Get(unityComponent, "velocity") ?? Get(unityComponent, "linearVelocity");
					float num4 = Convert.ToSingle(Get(o, "magnitude") ?? ((object)0f));
					if (obj4 == null || num4 < 5f)
					{
						continue;
					}
					float num5 = Convert.ToSingle(((MethodBase)method).Invoke((object)null, new object[2] { muzzle, obj4 }));
					if (num5 > 2.25f)
					{
						continue;
					}
					object obj5 = Get(o, "normalized") ?? Get(obj3, "forward");
					float num6 = Convert.ToSingle(((MethodBase)method2).Invoke((object)null, new object[2] { forward, obj5 }));
					if (!(num6 < 0.72f))
					{
						float num7 = num5 + (1f - num6) * 0.35f;
						if (!(num7 >= num))
						{
							num = num7;
							projectileCandidate = new ProjectileCandidate
							{
								Projectile = item,
								Transform = obj3,
								Rigidbody = unityComponent,
								Position = obj4,
								Direction = obj5,
								Speed = num4
							};
						}
					}
				}
				if (projectileCandidate != null)
				{
					break;
				}
			}
			if (projectileCandidate != null && !tracerProjectileLookupLogged)
			{
				tracerProjectileLookupLogged = true;
				Mod mod = instance;
				if (mod != null)
				{
					((MelonBase)mod).LoggerInstance.Msg($"Found the first live Marrow projectile ({projectileCandidate.Speed:0} units/s); its tracer will follow the projectile.");
				}
			}
			return projectileCandidate;
		}

		private static void SpawnTracer(object start, object direction, bool fusionActive, ProjectileCandidate projectile)
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			object obj = null;
			object obj2 = null;
			object obj3 = null;
			try
			{
				int num = (IsMobilePlatform() ? 3 : 10);
				while (tracers.Count >= num)
				{
					TracerEffect tracerEffect = tracers[0];
					Destroy(tracerEffect.GameObject, 0f);
					Destroy(tracerEffect.OuterLineGameObject, 0f);
					Destroy(tracerEffect.CoreLineGameObject, 0f);
					tracers.RemoveAt(0);
				}
				System.Type type = FindType("UnityEngine.PrimitiveType");
				object obj4 = System.Enum.Parse(type, "Sphere");
				MethodInfo method = gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24);
				obj = ((MethodBase)method).Invoke((object)null, new object[1] { obj4 });
				obj2 = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] tracer glow" });
				obj3 = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] tracer core" });
				object obj5 = Get(obj, "transform");
				RemovePrimitiveCollider(obj);
				System.Type type2 = FindType("UnityEngine.LineRenderer");
				if (type2 == (System.Type)null)
				{
					throw new InvalidOperationException("Unity LineRenderer was unavailable.");
				}
				object obj6 = AddUnityComponent(obj2, type2);
				object obj7 = AddUnityComponent(obj3, type2);
				float num2 = (fusionActive ? 1.15f : 1f);
				float num3 = 0.018f * num2;
				float num4 = 0.004f * num2;
				float num5 = 0.024f * num2;
				float num6 = 0.0015f * num2;
				float num7 = 0.005f * num2;
				object obj8 = Normalize(direction);
				Set(obj5, "position", start);
				Set(obj5, "localScale", NewVector(num3, num3, num3));
				DisableShadows(obj);
				ConfigureTracerLine(obj6, num4, num5, 1.6f, 0.72f, 0.04f, 3.5f, 0.48f);
				ConfigureTracerLine(obj7, num6, num7, 2.4f, 1.9f, 0.75f, 4.8f);
				SetTracerLinePoints(obj6, OffsetVector(start, obj8, -1.2f), start);
				SetTracerLinePoints(obj7, OffsetVector(start, obj8, -1.2f), start);
				ApplyTracerMaterial(obj, 2.4f, 1.95f, 0.85f, 5f);
				if (!IsMobilePlatform())
				{
					if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
					{
						return;
					}
					System.Type type3 = FindType("UnityEngine.Light");
					if (type3 != (System.Type)null)
					{
						object o = AddUnityComponent(obj, type3);
						Set(o, "intensity", 2.2f * num2);
						Set(o, "range", 1.4f * num2);
						Set(o, "color", Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { 1f, 0.72f, 0.32f, 1f }));
						System.Type type4 = FindType("UnityEngine.LightShadows");
						if (type4 != (System.Type)null)
						{
							Set(o, "shadows", System.Enum.Parse(type4, "None"));
						}
					}
				}
				bool flag = projectile != null;
				tracers.Add(new TracerEffect
				{
					GameObject = obj,
					OuterLineGameObject = obj2,
					CoreLineGameObject = obj3,
					Transform = obj5,
					OuterLine = obj6,
					CoreLine = obj7,
					Origin = start,
					Direction = (flag ? projectile.Direction : obj8),
					Started = System.DateTime.UtcNow,
					Length = 1.2f,
					Speed = (flag ? projectile.Speed : 85f),
					Life = (flag ? 1.5f : 0.26f),
					HeadSize = num3,
					OuterStartWidth = num4,
					OuterEndWidth = num5,
					CoreStartWidth = num6,
					CoreEndWidth = num7,
					Projectile = (flag ? projectile.Projectile : null),
					ProjectileTransform = (flag ? projectile.Transform : null),
					ProjectileBody = (flag ? projectile.Rigidbody : null),
					LastPosition = start,
					TrackingProjectile = flag
				});
				if (!tracerSpawnLogged)
				{
					tracerSpawnLogged = true;
					Mod mod = instance;
					if (mod != null)
					{
						((MelonBase)mod).LoggerInstance.Msg("Spawned a gold tracer with a bright core and tapered 3D glow.");
					}
				}
			}
			catch
			{
				Destroy(obj, 0f);
				Destroy(obj2, 0f);
				Destroy(obj3, 0f);
				throw;
			}
		}

		private static void ConfigureTracerLine(object line, float startWidth, float endWidth, float r, float g, float b, float emission, float alpha = 1f)
		{
			Set(line, "useWorldSpace", true);
			Set(line, "positionCount", 2);
			Set(line, "startWidth", startWidth);
			Set(line, "endWidth", endWidth);
			Set(line, "numCapVertices", 4);
			Set(line, "numCornerVertices", 2);
			System.Type type = FindType("UnityEngine.LineAlignment");
			if (type != (System.Type)null)
			{
				try
				{
					Set(line, "alignment", System.Enum.Parse(type, "View"));
				}
				catch
				{
				}
			}
			ApplyTracerMaterial(line, r, g, b, emission, alpha);
		}

		private static void SetTracerLinePoints(object line, object tail, object head)
		{
			Call(line, "SetPosition", 0, tail);
			Call(line, "SetPosition", 1, head);
		}

		private static void ApplyTracerMaterial(object obj, float r, float g, float b, float emission, float alpha = 1f)
		{
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			string text = $"{r:R}|{g:R}|{b:R}|{emission:R}|{alpha:R}";
			System.Type type = FindType("UnityEngine.Renderer");
			object value = default(object);
			if (tracerMaterialCache.TryGetValue(text, ref value))
			{
				object obj2 = ((type != (System.Type)null && type.IsInstanceOfType(obj)) ? obj : GetUnityComponent(obj, type));
				if (obj2 == null)
				{
					throw new InvalidOperationException("Tracer primitive has no MeshRenderer.");
				}
				Set(obj2, "enabled", true);
				Set(obj2, "material", value);
				return;
			}
			System.Type type2 = FindType("UnityEngine.Shader");
			MethodInfo method = type2.GetMethod("Find", (BindingFlags)24);
			object obj3 = null;
			string text2 = null;
			string[] array = new string[6] { "Particles/Additive", "Legacy Shaders/Particles/Additive", "Unlit/Color", "Universal Render Pipeline/Unlit", "Sprites/Default", "Standard" };
			foreach (string text3 in array)
			{
				obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { text3 }) : null);
				if (obj3 != null)
				{
					text2 = text3;
					break;
				}
			}
			if (obj3 == null)
			{
				throw new InvalidOperationException("Unity could not find a tracer shader.");
			}
			object obj4 = Activator.CreateInstance(FindType("UnityEngine.Material"), new object[1] { obj3 });
			System.Type type3 = FindType("UnityEngine.Color");
			object obj5 = Activator.CreateInstance(type3, new object[4] { r, g, b, alpha });
			Set(obj4, "color", obj5);
			Call(obj4, "SetColor", "_TintColor", obj5);
			Call(obj4, "EnableKeyword", "_EMISSION");
			Call(obj4, "SetColor", "_EmissionColor", Activator.CreateInstance(type3, new object[4]
			{
				r * emission,
				g * emission,
				b * emission,
				alpha
			}));
			Call(obj4, "SetFloat", "_Metallic", 0.05f);
			Call(obj4, "SetFloat", "_Glossiness", 0.45f);
			object obj6 = ((type != (System.Type)null && type.IsInstanceOfType(obj)) ? obj : GetUnityComponent(obj, type));
			if (obj6 == null)
			{
				throw new InvalidOperationException("Tracer effect has no renderer.");
			}
			Set(obj6, "enabled", true);
			Set(obj6, "material", obj4);
			tracerMaterialCache[text] = obj4;
			if (!tracerShaderLogged)
			{
				tracerShaderLogged = true;
				Mod mod = instance;
				if (mod != null)
				{
					((MelonBase)mod).LoggerInstance.Msg("Tracer material shader selected: " + text2 + ".");
				}
			}
		}

		private static void SpawnSpark(object start, object direction, float length)
		{
			int num = (IsMobilePlatform() ? 12 : 36);
			while (sparks.Count >= num)
			{
				SparkEffect sparkEffect = sparks[0];
				Destroy(sparkEffect.GameObject, 0f);
				Destroy(sparkEffect.TailGameObject, 0f);
				sparks.RemoveAt(0);
			}
			object obj = null;
			object obj2 = null;
			try
			{
				System.Type type = FindType("UnityEngine.PrimitiveType");
				object obj3 = System.Enum.Parse(type, "Sphere");
				MethodInfo method = gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24);
				obj = ((MethodBase)method).Invoke((object)null, new object[1] { obj3 });
				obj2 = ((MethodBase)method).Invoke((object)null, new object[1] { obj3 });
				object obj4 = Get(obj, "transform");
				object obj5 = Get(obj2, "transform");
				RemovePrimitiveCollider(obj);
				RemovePrimitiveCollider(obj2);
				DisableShadows(obj);
				DisableShadows(obj2);
				Set(obj4, "position", start);
				Set(obj5, "position", OffsetVector(start, direction, (0f - length) * 0.2f));
				float num2 = 0.028f + (float)effectRandom.NextDouble() * 0.01f;
				float num3 = 0.014f + (float)effectRandom.NextDouble() * 0.004f;
				Set(obj4, "localScale", NewVector(num2, num2, num2));
				Set(obj5, "localScale", NewVector(num3, num3, length * 0.66f));
				System.Type type2 = FindType("UnityEngine.Quaternion");
				MethodInfo method2 = type2.GetMethod("LookRotation", (BindingFlags)24, (Binder)null, new System.Type[1] { vector3Type }, (ParameterModifier[])null);
				object obj6 = ((method2 != null) ? ((MethodBase)method2).Invoke((object)null, new object[1] { direction }) : null);
				if (obj6 != null)
				{
					Set(obj4, "rotation", obj6);
					Set(obj5, "rotation", obj6);
				}
				ApplyMaterial(obj, 1f, 0.97f, 0.78f, 1f, 9f, transparent: false);
				ApplyMaterial(obj2, 1f, 0.56f, 0.16f, 1f, 6f, transparent: false);
				sparks.Add(new SparkEffect
				{
					GameObject = obj,
					TailGameObject = obj2,
					Transform = obj4,
					TailTransform = obj5,
					Origin = start,
					Direction = direction,
					Started = System.DateTime.UtcNow,
					Life = 0.2f,
					Length = length,
					Speed = 2.5f + (float)effectRandom.NextDouble() * 2.5f,
					HeadSize = num2,
					TailWidth = num3
				});
			}
			catch
			{
				Destroy(obj, 0f);
				Destroy(obj2, 0f);
				throw;
			}
		}

		private static object Normalize(object vector)
		{
			return Get(vector, "normalized") ?? vector;
		}

		private static object CombineDirections(object forward, object right, float rightScale, object up, float upScale, float forwardScale = 1f)
		{
			MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			object obj = ((MethodBase)method).Invoke((object)null, new object[2]
			{
				((MethodBase)method2).Invoke((object)null, new object[2] { forward, forwardScale }),
				((MethodBase)method2).Invoke((object)null, new object[2] { right, rightScale })
			});
			return Normalize(((MethodBase)method).Invoke((object)null, new object[2]
			{
				obj,
				((MethodBase)method2).Invoke((object)null, new object[2] { up, upScale })
			}));
		}

		private static object CombineDirections(object forward, object side, float sideScale)
		{
			MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			return Normalize(((MethodBase)method).Invoke((object)null, new object[2]
			{
				forward,
				((MethodBase)method2).Invoke((object)null, new object[2] { side, sideScale })
			}));
		}

		private static object OffsetVector(object origin, object axis, float distance)
		{
			MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			return ((MethodBase)method).Invoke((object)null, new object[2]
			{
				origin,
				((MethodBase)method2).Invoke((object)null, new object[2] { axis, distance })
			});
		}

		private static void SpawnGlow(object position, object direction, object right, object up)
		{
			MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			object position2 = ((MethodBase)method).Invoke((object)null, new object[2]
			{
				position,
				((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.035f })
			});
			SpawnFlashOrb(position2, direction, 0.105f, 0.105f, 0.12f, 1f, 0.88f, 0.58f, 6.5f, 0.065f);
			object position3 = ((MethodBase)method).Invoke((object)null, new object[2]
			{
				position,
				((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.11f })
			});
			SpawnFlashOrb(position3, direction, 0.075f, 0.075f, 0.28f, 1f, 0.48f, 0.16f, 4.8f, 0.06f);
			float[] array = new float[3];
			RuntimeHelpers.InitializeArray((System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			float[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				object obj = ((i == 2) ? up : right);
				object direction2 = Normalize(((MethodBase)method).Invoke((object)null, new object[2]
				{
					direction,
					((MethodBase)method2).Invoke((object)null, new object[2]
					{
						obj,
						array2[i]
					})
				}));
				object position4 = ((MethodBase)method).Invoke((object)null, new object[2]
				{
					position,
					((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.025f })
				});
				SpawnFlashOrb(position4, direction2, 0.032f, 0.032f, 0.12f + 0.025f * (float)i, 1f, 0.62f, 0.24f, 3.6f, 0.05f);
			}
			AddMuzzleLight(position);
		}

		private static void SpawnFlashOrb(object position, object direction, float sx, float sy, float sz, float r, float g, float b, float emission, float life)
		{
			System.Type type = FindType("UnityEngine.PrimitiveType");
			object obj = System.Enum.Parse(type, "Sphere");
			object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
			try
			{
				object o = Get(obj2, "transform");
				RemovePrimitiveCollider(obj2);
				if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
				{
					DisableShadows(obj2);
				}
				Set(o, "position", position);
				Set(o, "localScale", NewVector(sx, sy, sz));
				System.Type type2 = FindType("UnityEngine.Quaternion");
				MethodInfo method = type2.GetMethod("LookRotation", (BindingFlags)24, (Binder)null, new System.Type[1] { vector3Type }, (ParameterModifier[])null);
				object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { direction }) : null);
				if (obj3 != null)
				{
					Set(o, "rotation", obj3);
				}
				ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
			}
			finally
			{
				Destroy(obj2, life);
			}
		}

		private static void SpawnFlashCylinder(object position, object direction, float diameter, float length, float r, float g, float b, float emission, float life)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			System.Type type = FindType("UnityEngine.PrimitiveType");
			object obj = System.Enum.Parse(type, "Cylinder");
			object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
			try
			{
				object o = Get(obj2, "transform");
				RemovePrimitiveCollider(obj2);
				if (IsMobilePlatform())
				{
					DisableShadows(obj2);
				}
				Set(o, "position", position);
				Set(o, "localScale", NewVector(diameter, length * 0.5f, diameter));
				System.Type type2 = FindType("UnityEngine.Quaternion");
				MethodInfo method = type2.GetMethod("FromToRotation", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
				object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[2]
				{
					NewVector(0f, 1f, 0f),
					direction
				}) : null);
				if (obj3 == null)
				{
					throw new MissingMethodException("Unity Quaternion.FromToRotation was unavailable.");
				}
				Set(o, "rotation", obj3);
				ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
			}
			finally
			{
				Destroy(obj2, life);
			}
		}

		private static void SpawnFlashCapsule(object position, object direction, float width, float length, float r, float g, float b, float emission, float life)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			System.Type type = FindType("UnityEngine.PrimitiveType");
			object obj = System.Enum.Parse(type, "Capsule");
			object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
			try
			{
				object o = Get(obj2, "transform");
				RemovePrimitiveCollider(obj2);
				if (IsMobilePlatform())
				{
					DisableShadows(obj2);
				}
				Set(o, "position", position);
				Set(o, "localScale", NewVector(width, length * 0.5f, width));
				System.Type type2 = FindType("UnityEngine.Quaternion");
				MethodInfo method = type2.GetMethod("FromToRotation", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
				object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[2]
				{
					NewVector(0f, 1f, 0f),
					direction
				}) : null);
				if (obj3 == null)
				{
					throw new MissingMethodException("Unity Quaternion.FromToRotation was unavailable.");
				}
				Set(o, "rotation", obj3);
				ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
			}
			finally
			{
				Destroy(obj2, life);
			}
		}

		private static void SpawnSmokeOnlyFlash(object position, object direction, object right, object up)
		{
			MethodInfo method = vector3Type.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			MethodInfo method2 = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
			bool flag = IsMobilePlatform();
			int num = (flag ? 5 : 8);
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)(effectRandom.NextDouble() * 0.09 - 0.045);
				object origin = OffsetVector(position, direction, 0.02f + 0.048f * (float)i);
				origin = OffsetVector(origin, right, num2);
				origin = OffsetVector(origin, up, (float)(effectRandom.NextDouble() * 0.035 - 0.0175));
				object velocity = ((MethodBase)method2).Invoke((object)null, new object[2]
				{
					((MethodBase)method).Invoke((object)null, new object[2]
					{
						right,
						num2 * 0.55f
					}),
					((MethodBase)method2).Invoke((object)null, new object[2]
					{
						((MethodBase)method).Invoke((object)null, new object[2]
						{
							up,
							0.045f + 0.018f * (float)i
						}),
						((MethodBase)method).Invoke((object)null, new object[2]
						{
							direction,
							0.035f + 0.012f * (float)i
						})
					})
				});
				float life = (flag ? (0.72f + 0.07f * (float)i) : (1.05f + 0.09f * (float)i));
				float size = 0.095f + 0.014f * (float)i;
				SpawnSmoke(origin, size, life, velocity, 0.29f);
			}
		}

		private static void SpawnSmoke(object position, float size, float life, object velocity, float alpha = 0.22f)
		{
			int num = (IsMobilePlatform() ? 18 : 64);
			while (smokePuffs.Count >= num)
			{
				SmokePuff smokePuff = smokePuffs[0];
				Destroy(smokePuff.GameObject, 0f);
				smokePuffs.RemoveAt(0);
			}
			System.Type type = FindType("UnityEngine.PrimitiveType");
			object obj = System.Enum.Parse(type, "Sphere");
			object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
			try
			{
				RemovePrimitiveCollider(obj2);
				object obj3 = Get(obj2, "transform");
				Set(obj3, "position", position);
				Set(obj3, "localScale", NewVector(size, size, size));
				ApplyMaterial(obj2, 0.4f, 0.4f, 0.4f, alpha, 0f, transparent: true);
				object unityComponent = GetUnityComponent(obj2, FindType("UnityEngine.Renderer"));
				Set(unityComponent, "shadowCastingMode", System.Enum.Parse(FindType("UnityEngine.Rendering.ShadowCastingMode"), "Off"));
				Set(unityComponent, "receiveShadows", !IsMobilePlatform());
				object material = Get(unityComponent, "material");
				smokePuffs.Add(new SmokePuff
				{
					GameObject = obj2,
					Transform = obj3,
					Material = material,
					Origin = position,
					Velocity = velocity,
					Started = System.DateTime.UtcNow,
					Life = life,
					Size = size,
					Alpha = alpha
				});
			}
			catch
			{
				Destroy(obj2, 0f);
				throw;
			}
		}

		private static void AddMuzzleLight(object position)
		{
			AddMuzzleLight(position, 1f, 0.66f, 0.32f, 3.1f, 2.6f, 0.065f);
		}

		private static void AddMuzzleLight(object position, float r, float g, float b, float intensity, float range, float life)
		{
			if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
			{
				return;
			}
			System.Type componentType = FindType("UnityEngine.Light");
			object obj = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] muzzle flash light" });
			try
			{
				object o = AddUnityComponent(obj, componentType);
				Set(Get(obj, "transform"), "position", position);
				Set(o, "intensity", intensity);
				Set(o, "range", range);
				Set(o, "shadows", System.Enum.Parse(FindType("UnityEngine.LightShadows"), "None"));
				object value = Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { r, g, b, 1f });
				Set(o, "color", value);
			}
			finally
			{
				Destroy(obj, life);
			}
		}

		private static object MakeMaterial(float r, float g, float b, float alpha, float emission, bool transparent)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			string text = $"{r:R}|{g:R}|{b:R}|{alpha:R}|{emission:R}|{transparent}";
			object result = default(object);
			if (materialCache.TryGetValue(text, ref result))
			{
				return result;
			}
			System.Type type = FindType("UnityEngine.Shader");
			MethodInfo method = type.GetMethod("Find", (BindingFlags)24);
			string[] array = ((!transparent) ? new string[3] { "Standard", "Unlit/Color", "Sprites/Default" } : new string[6] { "Standard", "Legacy Shaders/Transparent/Diffuse", "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Transparent", "Sprites/Default" });
			object obj = null;
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				obj = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { text2 }) : null);
				if (obj != null)
				{
					break;
				}
			}
			if (obj == null)
			{
				throw new InvalidOperationException("Unity could not find a supported Realism effect shader.");
			}
			System.Type type2 = FindType("UnityEngine.Material");
			object obj2 = Activator.CreateInstance(type2, new object[1] { obj });
			System.Type type3 = FindType("UnityEngine.Color");
			object value = Activator.CreateInstance(type3, new object[4] { r, g, b, alpha });
			Set(obj2, "color", value);
			if (emission > 0f)
			{
				Call(obj2, "EnableKeyword", "_EMISSION");
				object obj3 = Activator.CreateInstance(type3, new object[4]
				{
					r * emission,
					g * emission,
					b * emission,
					1f
				});
				Call(obj2, "SetColor", "_EmissionColor", obj3);
			}
			if (transparent)
			{
				Call(obj2, "SetFloat", "_Mode", 2f);
				Call(obj2, "SetFloat", "_Metallic", 0f);
				Call(obj2, "SetFloat", "_Glossiness", 0.05f);
				Call(obj2, "SetInt", "_SrcBlend", 5);
				Call(obj2, "SetInt", "_DstBlend", 10);
				Call(obj2, "SetInt", "_ZWrite", 0);
				Call(obj2, "EnableKeyword", "_ALPHABLEND_ON");
				Set(obj2, "renderQueue", 3000);
			}
			materialCache[text] = obj2;
			return obj2;
		}

		private static void ApplyMaterial(object obj, float r, float g, float b, float alpha, float emission, bool transparent)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Renderer"));
			if (unityComponent == null)
			{
				throw new InvalidOperationException("Realism effect primitive has no MeshRenderer.");
			}
			Set(unityComponent, "enabled", true);
			Set(unityComponent, "material", MakeMaterial(r, g, b, alpha, emission, transparent));
		}

		private static void Set(object o, string name, object value)
		{
			if (o == null)
			{
				return;
			}
			PropertyInfo property = o.GetType().GetProperty(name, (BindingFlags)52);
			if (property != (PropertyInfo)null && property.CanWrite)
			{
				property.SetValue(o, value);
				return;
			}
			FieldInfo field = o.GetType().GetField(name, (BindingFlags)52);
			if (field != null)
			{
				field.SetValue(o, value);
			}
		}

		private static void Destroy(object obj, float delay)
		{
			if (obj == null || unityObject == (System.Type)null)
			{
				return;
			}
			try
			{
				MethodInfo method = unityObject.GetMethod("Destroy", new System.Type[2]
				{
					unityObject,
					typeof(float)
				});
				if (method != (MethodInfo)null)
				{
					((MethodBase)method).Invoke((object)null, new object[2] { obj, delay });
					return;
				}
				MethodInfo method2 = unityObject.GetMethod("Destroy", new System.Type[1] { unityObject });
				if (method2 != null)
				{
					((MethodBase)method2).Invoke((object)null, new object[1] { obj });
				}
			}
			catch
			{
				try
				{
					MethodInfo method3 = unityObject.GetMethod("Destroy", new System.Type[1] { unityObject });
					if (method3 != null)
					{
						((MethodBase)method3).Invoke((object)null, new object[1] { obj });
					}
				}
				catch
				{
				}
			}
		}

		private static void RemovePrimitiveCollider(object obj)
		{
			object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Collider"));
			if (unityComponent != null)
			{
				Set(unityComponent, "enabled", false);
				Destroy(unityComponent, 0f);
			}
		}

		private static void DisableShadows(object obj)
		{
			object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Renderer"));
			System.Type type = FindType("UnityEngine.Rendering.ShadowCastingMode");
			if (unityComponent != null && !(type == (System.Type)null))
			{
				Set(unityComponent, "shadowCastingMode", System.Enum.Parse(type, "Off"));
				Set(unityComponent, "receiveShadows", false);
			}
		}

		private static object FindMuzzleTransform(object root)
		{
			if (root == null)
			{
				return null;
			}
			int num = Convert.ToInt32(Get(root, "childCount") ?? ((object)0));
			for (int i = 0; i < num; i++)
			{
				object obj = Call(root, "GetChild", i);
				string text = Convert.ToString(Get(obj, "name")) ?? "";
				if (text.IndexOf("muzzle", (StringComparison)5) >= 0 || text.IndexOf("barrel", (StringComparison)5) >= 0 || text.IndexOf("muzzlepoint", (StringComparison)5) >= 0)
				{
					return obj;
				}
				object obj2 = FindMuzzleTransform(obj);
				if (obj2 != null)
				{
					return obj2;
				}
			}
			return null;
		}

		private static void UpdateTracers()
		{
			//IL_00c9: 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_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo val2 = vector3Type?.GetMethod("op_Subtraction", (BindingFlags)24);
			MethodInfo val3 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			MethodInfo val4 = vector3Type?.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
			for (int num = tracers.Count - 1; num >= 0; num--)
			{
				TracerEffect tracerEffect = tracers[num];
				try
				{
					System.DateTime utcNow = System.DateTime.UtcNow;
					TimeSpan val5 = utcNow - tracerEffect.Started;
					float num2 = (float)((TimeSpan)(ref val5)).TotalSeconds;
					object obj;
					float num3;
					float num4;
					if (tracerEffect.TrackingProjectile)
					{
						bool flag = IsUnityObjectAlive(tracerEffect.ProjectileTransform) && IsUnityObjectAlive(tracerEffect.ProjectileBody);
						object o = Get(tracerEffect.ProjectileTransform, "gameObject");
						if (flag && Convert.ToBoolean(Get(o, "activeInHierarchy") ?? ((object)true)))
						{
							obj = Get(tracerEffect.ProjectileTransform, "position") ?? tracerEffect.LastPosition;
							object o2 = Get(tracerEffect.ProjectileBody, "velocity");
							object obj2 = Get(o2, "normalized");
							if (obj2 == null || Convert.ToSingle(Get(o2, "magnitude") ?? ((object)0f)) < 0.01f)
							{
								object o3 = ((MethodBase)val2).Invoke((object)null, new object[2] { obj, tracerEffect.LastPosition });
								obj2 = Get(o3, "normalized") ?? tracerEffect.Direction;
							}
							tracerEffect.Direction = obj2;
							tracerEffect.LastPosition = obj;
							num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
							if (Convert.ToBoolean(Get(tracerEffect.Projectile, "isFinished") ?? ((object)false)))
							{
								tracerEffect.TrackingProjectile = false;
								tracerEffect.HasFinishedAt = true;
								tracerEffect.FinishedAt = utcNow;
							}
							num4 = 0f;
						}
						else
						{
							tracerEffect.TrackingProjectile = false;
							tracerEffect.HasFinishedAt = true;
							tracerEffect.FinishedAt = utcNow;
							obj = tracerEffect.LastPosition;
							num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
							num4 = 0f;
						}
						goto IL_048d;
					}
					if (tracerEffect.HasFinishedAt)
					{
						val5 = utcNow - tracerEffect.FinishedAt;
						float num5 = (float)((TimeSpan)(ref val5)).TotalSeconds;
						if (!(num5 >= 0.12f))
						{
							obj = tracerEffect.LastPosition;
							num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
							num4 = num5 / 0.12f;
							goto IL_048d;
						}
						Destroy(tracerEffect.GameObject, 0f);
						Destroy(tracerEffect.OuterLineGameObject, 0f);
						Destroy(tracerEffect.CoreLineGameObject, 0f);
						tracers.RemoveAt(num);
					}
					else
					{
						if (!(num2 >= tracerEffect.Life))
						{
							obj = ((MethodBase)val).Invoke((object)null, new object[2]
							{
								tracerEffect.Origin,
								((MethodBase)val3).Invoke((object)null, new object[2]
								{
									tracerEffect.Direction,
									tracerEffect.Speed * num2
								})
							});
							num3 = tracerEffect.Speed * num2;
							num4 = num2 / tracerEffect.Life;
							goto IL_048d;
						}
						Destroy(tracerEffect.GameObject, 0f);
						Destroy(tracerEffect.OuterLineGameObject, 0f);
						Destroy(tracerEffect.CoreLineGameObject, 0f);
						tracers.RemoveAt(num);
					}
					goto end_IL_00b8;
					IL_048d:
					float num6 = Math.Min(tracerEffect.Length, num3) * (1f - 0.2f * num4);
					object tail = ((MethodBase)val).Invoke((object)null, new object[2]
					{
						obj,
						((MethodBase)val3).Invoke((object)null, new object[2]
						{
							tracerEffect.Direction,
							0f - num6
						})
					});
					float num7 = 1f - 0.35f * num4;
					Set(tracerEffect.Transform, "position", obj);
					Set(tracerEffect.Transform, "localScale", NewVector(tracerEffect.HeadSize * num7, tracerEffect.HeadSize * num7, tracerEffect.HeadSize * num7));
					SetTracerLinePoints(tracerEffect.OuterLine, tail, obj);
					SetTracerLinePoints(tracerEffect.CoreLine, tail, obj);
					Set(tracerEffect.OuterLine, "startWidth", tracerEffect.OuterStartWidth * num7);
					Set(tracerEffect.OuterLine, "endWidth", tracerEffect.OuterEndWidth * num7);
					Set(tracerEffect.CoreLine, "startWidth", tracerEffect.CoreStartWidth * num7);
					Set(tracerEffect.CoreLine, "endWidth", tracerEffect.CoreEndWidth * num7);
					if (!tracerUpdateLogged)
					{
						tracerUpdateLogged = true;
						Mod mod = instance;
						if (mod != null)
						{
							((MelonBase)mod).LoggerInstance.Msg("Updated the first tapered additive tracer streak in the scene.");
						}
					}
					end_IL_00b8:;
				}
				catch (System.Exception error)
				{
					Destroy(tracerEffect.GameObject, 0f);
					Destroy(tracerEffect.OuterLineGameObject, 0f);
					Destroy(tracerEffect.CoreLineGameObject, 0f);
					tracers.RemoveAt(num);
					LogEffectError(ref visualErrorLogged, "tracer animation", error);
				}
			}
		}

		private static void UpdateSparks()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo val2 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			for (int num = sparks.Count - 1; num >= 0; num--)
			{
				SparkEffect sparkEffect = sparks[num];
				TimeSpan val3 = System.DateTime.UtcNow - sparkEffect.Started;
				float num2 = (float)((TimeSpan)(ref val3)).TotalSeconds;
				if (num2 >= sparkEffect.Life)
				{
					Destroy(sparkEffect.GameObject, 0f);
					Destroy(sparkEffect.TailGameObject, 0f);
					sparks.RemoveAt(num);
				}
				else
				{
					try
					{
						object obj = ((MethodBase)val2).Invoke((object)null, new object[2]
						{
							sparkEffect.Direction,
							sparkEffect.Speed * num2
						});
						object obj2 = NewVector(0f, -4.9f * num2 * num2, 0f);
						object obj3 = ((MethodBase)val).Invoke((object)null, new object[2]
						{
							sparkEffect.Origin,
							((MethodBase)val).Invoke((object)null, new object[2] { obj, obj2 })
						});
						float num3 = num2 / sparkEffect.Life;
						object value = ((MethodBase)val).Invoke((object)null, new object[2]
						{
							obj3,
							((MethodBase)val2).Invoke((object)null, new object[2]
							{
								sparkEffect.Direction,
								(0f - sparkEffect.Length) * 0.22f
							})
						});
						Set(sparkEffect.Transform, "position", obj3);
						Set(sparkEffect.TailTransform, "position", value);
						float num4 = sparkEffect.HeadSize * (1f - 0.52f * num3);
						float z = sparkEffect.Length * 0.66f * (1f - 0.4f * num3);
						Set(sparkEffect.Transform, "localScale", NewVector(num4, num4, num4));
						Set(sparkEffect.TailTransform, "localScale", NewVector(sparkEffect.TailWidth, sparkEffect.TailWidth, z));
					}
					catch (System.Exception error)
					{
						Destroy(sparkEffect.GameObject, 0f);
						Destroy(sparkEffect.TailGameObject, 0f);
						sparks.RemoveAt(num);
						LogEffectError(ref visualErrorLogged, "spark animation", error);
					}
				}
			}
		}

		private static void UpdateSmoke()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
			MethodInfo val2 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
			{
				vector3Type,
				typeof(float)
			});
			for (int num = smokePuffs.Count - 1; num >= 0; num--)
			{
				SmokePuff smokePuff = smokePuffs[num];
				TimeSpan val3 = System.DateTime.UtcNow - smokePuff.Started;
				float num2 = (float)((TimeSpan)(ref val3)).TotalSeconds;
				if (num2 >= smokePuff.Life)
				{
					Destroy(smokePuff.GameObject, 0f);
					smokePuffs.RemoveAt(num);
				}
				else
				{
					try
					{
						float num3 = num2 / smokePuff.Life;
						object value = ((MethodBase)val).Invoke((object)null, new object[2]
						{
							smokePuff.Origin,
							((MethodBase)val2).Invoke((object)null, new object[2] { smokePuff.Velocity, num2 })
						});
						Set(smokePuff.Transform, "position", value);
						float num4 = smokePuff.Size * (1f + 0.9f * num3);
						Set(smokePuff.Transform, "localScale", NewVector(num4, num4, num4));
						float alpha = smokePuff.Alpha * (float)Math.Pow((double)(1f - num3), 1.3);
						SetMaterialColor(smokePuff.Material, 0.4f, 0.4f, 0.4f, alpha);
					}
					catch (System.Exception error)
					{
						Destroy(smokePuff.GameObject, 0f);
						smokePuffs.RemoveAt(num);
						LogEffectError(ref visualErrorLogged, "smoke animation", error);
					}
				}
			}
		}

		private static void SetMaterialColor(object material, float r, float g, float b, float alpha)
		{
			if (material != null)
			{
				object value = Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { r, g, b, alpha });
				Set(material, "color", value);
			}
		}

		private static void RaiseRinging()
		{
			EnsureRingingAudio();
			ringingLevel = Math.Min(0.6f, ringingLevel + 0.1f);
			if (ringingUpdated == System.DateTime.MinValue)
			{
				ringingUpdated = System.DateTime.UtcNow;
			}
			System.Type type = FindType("UnityEngine.AudioSource");
			if (!Convert.ToBoolean(Get(ringingSource, "isPlaying") ?? ((object)false)))
			{
				Call(ringingSource, "Play");
			}
		}

		private static void EnsureRingingAudio()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			if (!IsUnityObjectAlive(ringingSource) || !IsUnityObjectAlive(ringingClip))
			{
				ResetRingingAudio();
				gameObjectType = FindType("UnityEngine.GameObject");
				unityObject = FindType("UnityEngine.Object");
				System.Type type = FindType("UnityEngine.AudioSource");
				System.Type type2 = FindType("UnityEngine.AudioClip");
				if (gameObjectType == (System.Type)null || type == (System.Type)null || type2 == (System.Type)null)
				{
					throw new InvalidOperationException("Unity audio types were unavailable.");
				}
				ringingGameObject = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] ear ring" });
				MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)unityObject.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "DontDestroyOnLoad" && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType.IsInstanceOfType(ringingGameObject)));
				if (val != null)
				{
					((MethodBase)val).Invoke((object)null, new object[1] { ringingGameObject });
				}
				ringingSource = AddUnityComponent(ringingGameObject, type);
				if (ringingSource == null)
				{
					throw new InvalidOperationException("Unity could not create the tinnitus AudioSource.");
				}
				MethodInfo val2 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type2.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "Create" && ((MethodBase)m).GetParameters().Length == 5));
				ringingClip = ((val2 != null) ? ((MethodBase)val2).Invoke((object)null, new object[5] { "Realism continuous 900 Hz ring", 44100, 1, 88200, false }) : null);
				if (ringingClip == null)
				{
					throw new InvalidOperationException("Unity did not create the 900 Hz audio clip.");
				}
				float[] array = new float[88200];
				for (int num = 0; num < array.Length; num++)
				{
					array[num] = 0.46f * (float)Math.Sin(Math.PI * 1800.0 * (double)num / 44100.0);
				}
				MethodInfo val3 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type2.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "SetData" && ((MethodBase)m).GetParameters().Length == 2));
				if (val3 == (MethodInfo)null)
				{
					throw new InvalidOperationException("Unity AudioClip.SetData was unavailable.");
				}
				((MethodBase)val3).Invoke(ringingClip, new object[2]
				{
					ConvertArrayForRuntime(((MethodBase)val3).GetParameters()[0].ParameterType, array),
					0
				});
				PropertyInfo property = type.GetProperty("spatialBlend");
				if (property != null)
				{
					property.SetValue(ringingSource, (object)0f);
				}
				PropertyInfo property2 = type.GetProperty("loop");
				if (property2 != null)
				{
					property2.SetValue(ringingSource, (object)true);
				}
				PropertyInfo property3 = type.GetProperty("playOnAwake");
				if (property3 != null)
				{
					property3.SetValue(ringingSource, (object)false);
				}
				PropertyInfo property4 = type.GetProperty("priority");
				if (property4 != null)
				{
					property4.SetValue(ringingSource, (object)0);
				}
				PropertyInfo property5 = type.GetProperty("clip");
				if (property5 != null)
				{
					property5.SetValue(ringingSource, ringingClip);
				}
				PropertyInfo property6 = type.GetProperty("volume");
				if (property6 != null)
				{
					property6.SetValue(ringingSource, (object)0f);
				}
			}
		}

		private static void UpdateRinging()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (ringingSource == null)
			{
				return;
			}
			if (!IsUnityObjectAlive(ringingSource) || !IsUnityObjectAlive(ringingClip))
			{
				ResetRingingAudio();
				return;
			}
			System.DateTime utcNow = System.DateTime.UtcNow;
			float num;
			if (!(ringingUpdated == System.DateTime.MinValue))
			{
				TimeSpan val = utcNow - ringingUpdated;
				num = Math.Max(0f, (float)((TimeSpan)(ref val)).TotalSeconds);
			}
			else
			{
				num = 0f;
			}
			float num2 = num;
			if (ringingUpdated != System.DateTime.MinValue)
			{
				ringingLevel *= (float)Math.Exp((double)((0f - num2) / 8f));
			}
			ringingUpdated = utcNow;
			if (!earRingingEnabled)
			{
				ringingLevel = 0f;
			}
			try
			{
				float num3 = ((ringingLevel > ringingVolume) ? 0.06f : 0.32f);
				float num4 = ((num2 <= 0f) ? 0f : (1f - (float)Math.Exp((double)((0f - num2) / num3))));
				ringingVolume += (ringingLevel - ringingVolume) * num4;
				if (ringingLevel < 0.0005f && ringingVolume < 0.0005f)
				{
					ringingLevel = (ringingVolume = 0f);
				}
				System.Type type = FindType("UnityEngine.AudioSource");
				if (type != null)
				{
					PropertyInfo property = type.GetProperty("volume");
					if (property != null)
					{
						property.SetValue(ringingSource, (object)(ringingVolume * (ringingVolumeSetting / 100f)));
					}
				}
				if (!Convert.ToBoolean(Get(ringingSource, "isPlaying") ?? ((object)false)) && (ringingLevel > 0.001f || ringingVolume > 0.001f))
				{
					Call(ringingSource, "Play");
				}
			}
			catch (System.Exception error)
			{
				LogEffectError(ref audioErrorLogged, "ringing update", error);
			}
		}

		private static object GetFiringHand(object gun)
		{
			object o = Get(gun, "triggerGrip");
			return Call(o, "GetHand");
		}

		private static bool IsRemoteFiringHand(object hand)
		{
			if (hand == null)
			{
				return false;
			}
			object manager = Get(hand, "manager");
			System.Type type = FindType("LabFusion.Entities.NetworkPlayerManager");
			if (manager == null || type == (System.Type)null)
			{
				return false;
			}
			MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type.GetMethods((BindingFlags)56), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "HasExternalPlayer" && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType.IsInstanceOfType(manager)));
			if (val == (MethodInfo)null)
			{
				return false;
			}
			try
			{
				return Convert.ToBoolean(((MethodBase)val).Invoke((object)null, new object[1] { manager }));
			}
			catch
			{
				return false;
			}
		}

		private static object ConvertArrayForRuntime(System.Type expectedType, float[] values)
		{
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			if (expectedType.IsInstanceOfType((object)values))
			{
				return values;
			}
			if (expectedType.IsGenericType && expectedType.GetGenericArguments().Length == 1 && expectedType.GetGenericArguments()[0] == typeof(float))
			{
				ConstructorInfo constructor = expectedType.GetConstructor(new System.Type[1] { typeof(float[]) });
				if (constructor != (ConstructorInfo)null)
				{
					return constructor.Invoke(new object[1] { values });
				}
				ConstructorInfo constructor2 = expectedType.GetConstructor(new System.Type[1] { typeof(int) });
				if (constructor2 != (ConstructorInfo)null)
				{
					object obj = constructor2.Invoke(new object[1] { values.Length });
					PropertyInfo property = expectedType.GetProperty("Item");
					if (property != (PropertyInfo)null)
					{
						for (int i = 0; i < values.Length; i++)
						{
							property.SetValue(obj, (object)values[i], new object[1] { i });
						}
					}
					return obj;
				}
			}
			throw new InvalidOperationException("Can't pass audio samples to " + expectedType.FullName + ".");
		}
	}
}