Decompiled source of Minigun v1.0.3

plugins/MinigunMod.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FishNet;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MinigunMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MinigunMod")]
[assembly: AssemblyTitle("MinigunMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MinigunMod
{
	public static class LoaderHelper
	{
		public static void RegisterAudioClip(AudioClip clip, string nameOverride)
		{
			Traverse.Create(typeof(AudioManager)).Field("_realClips").GetValue<Dictionary<string, AudioClip>>()[nameOverride] = clip;
			Plugin.Log.LogInfo((object)("Registered clip '" + ((Object)clip).name + "' as '" + nameOverride + "'"));
		}
	}
	[HarmonyPatch]
	public class Minigun
	{
		private class MinigunController
		{
			public bool IsMinigun;

			public float Spin;

			private float _heat;

			private bool _overheated;

			private Transform _barrel;

			private AudioSource _spinSrc;

			private AudioSource _fireSrc;

			private AudioSource _overheatSrc;

			private ParticleSystem _smoke;

			private const float HeatPerSecondFiring = 0.15f;

			private const float CoolPerSecond = 0.4f;

			private const float OverheatCooldownTo = 0.2f;

			private static readonly MethodInfo _localReload = AccessTools.Method(typeof(Weapon), "LocalReload", (Type[])null, (Type[])null);

			public static MinigunController Create(Weapon w)
			{
				MinigunController minigunController = new MinigunController
				{
					IsMinigun = (((Item)w).ID == 86)
				};
				if (minigunController.IsMinigun)
				{
					minigunController._barrel = ((Component)w).transform.Find("MinigunAnimated/Rig/Gun/barrels");
					Transform obj = ((Component)w).transform.Find("MinigunAnimated/Rig/Gun/Attachments/BarrelAttachments/DefaultBarrel/Smoke");
					minigunController._smoke = ((obj != null) ? ((Component)obj).GetComponent<ParticleSystem>() : null);
				}
				return minigunController;
			}

			public void Tick(Weapon w, bool wantSpin)
			{
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				if (wantSpin && Spin >= 0.9f && !_overheated)
				{
					_heat += 0.15f * Time.deltaTime;
				}
				else
				{
					_heat -= 0.4f * Time.deltaTime;
				}
				_heat = Mathf.Clamp01(_heat);
				if (!_overheated && _heat >= 1f)
				{
					_overheated = true;
					_localReload.Invoke(w, null);
					if (Object.op_Implicit((Object)(object)_overheatSrc))
					{
						_overheatSrc.Play();
					}
					if (Object.op_Implicit((Object)(object)_smoke))
					{
						_smoke.Play();
					}
				}
				if (_overheated && _heat <= 0.2f)
				{
					_overheated = false;
					if (Object.op_Implicit((Object)(object)_smoke) && _smoke.isPlaying)
					{
						_smoke.Stop(true, (ParticleSystemStopBehavior)1);
					}
				}
				if (_overheated)
				{
					wantSpin = false;
				}
				float num = (wantSpin ? 1f : 0f);
				float num2 = ((num > Spin) ? (5f / 12f) : 0.5f);
				Spin = Mathf.MoveTowards(Spin, num, num2 * Time.deltaTime);
				float num3 = 2500f * Spin * Spin;
				Transform barrel = _barrel;
				if (barrel != null)
				{
					barrel.Rotate(SpinAxis, num3 * Time.deltaTime, (Space)1);
				}
				if (wantSpin && Spin >= 0.9f)
				{
					float num4 = num3 / 360f * 6f;
					if (num4 > 0f)
					{
						_timeBetweenShots.Invoke(w) = 1f / num4;
					}
				}
				UpdateSpinAudio();
				UpdateFireAudio(wantSpin);
			}

			public void OnDrop()
			{
			}

			private void UpdateSpinAudio()
			{
				if (!Object.op_Implicit((Object)(object)MinigunLoader.SpinUpAudioClip) || !Object.op_Implicit((Object)(object)_barrel))
				{
					return;
				}
				if ((Object)(object)_spinSrc == (Object)null)
				{
					_spinSrc = ((Component)_barrel).gameObject.AddComponent<AudioSource>();
					_spinSrc.clip = MinigunLoader.SpinUpAudioClip;
					_spinSrc.loop = true;
					_spinSrc.spatialBlend = 1f;
					_spinSrc.playOnAwake = false;
					_spinSrc.volume = 0f;
					_spinSrc.rolloffMode = (AudioRolloffMode)1;
					_spinSrc.minDistance = 0.5f;
					_spinSrc.maxDistance = 15f;
				}
				if (Spin > 0.01f)
				{
					if (!_spinSrc.isPlaying)
					{
						_spinSrc.Play();
					}
					_spinSrc.volume = Spin * 0.1f;
					_spinSrc.pitch = Mathf.Lerp(0.4f, 1.6f, Spin);
				}
				else if (_spinSrc.isPlaying)
				{
					_spinSrc.Stop();
				}
			}

			private void UpdateFireAudio(bool wantSpin)
			{
				if (!Object.op_Implicit((Object)(object)MinigunLoader.FireLoopClip) || !Object.op_Implicit((Object)(object)_barrel))
				{
					return;
				}
				if ((Object)(object)_fireSrc == (Object)null)
				{
					_fireSrc = ((Component)_barrel).gameObject.AddComponent<AudioSource>();
					_fireSrc.clip = MinigunLoader.FireLoopClip;
					_fireSrc.loop = true;
					_fireSrc.spatialBlend = 1f;
					_fireSrc.playOnAwake = false;
					_fireSrc.volume = 0f;
					_fireSrc.minDistance = 8f;
					_fireSrc.maxDistance = 40f;
				}
				if ((Object)(object)_overheatSrc == (Object)null)
				{
					_overheatSrc = ((Component)_barrel).gameObject.AddComponent<AudioSource>();
					_overheatSrc.clip = MinigunLoader.OverheatClip;
					_overheatSrc.loop = false;
					_overheatSrc.spatialBlend = 1f;
					_overheatSrc.playOnAwake = false;
					_overheatSrc.volume = 1f;
					_overheatSrc.minDistance = 4f;
					_overheatSrc.maxDistance = 20f;
				}
				if (wantSpin && Spin >= 0.9f)
				{
					if (!_fireSrc.isPlaying)
					{
						_fireSrc.Play();
					}
					float num = Mathf.Clamp(Spin * Spin, 0.35f, 1f);
					float num2 = Mathf.Lerp(1f, 1.15f, _heat * _heat);
					_fireSrc.pitch = num * num2;
					_fireSrc.volume = 1f * Spin;
				}
				else if (_fireSrc.isPlaying)
				{
					_fireSrc.Stop();
				}
			}
		}

		private const float SpinUpTime = 2.4f;

		private const float SpinDownTime = 2f;

		private const float MaxSpinSpeed = 2500f;

		private const float FireThreshold = 0.9f;

		private const int BarrelCount = 6;

		private static readonly Vector3 SpinAxis = Vector3.up;

		private const float SpinMinPitch = 0.4f;

		private const float SpinMaxPitch = 1.6f;

		private const float SpinMaxVol = 0.1f;

		private const float FireLoopVol = 1f;

		private static readonly FieldRef<Weapon, bool> _holdingFire = AccessTools.FieldRefAccess<Weapon, bool>("_holdingFireInput");

		private static readonly FieldRef<Weapon, float> _timeBetweenShots = AccessTools.FieldRefAccess<Weapon, float>("_timeBetweenShots");

		private static readonly FieldRef<Weapon, Player> _holderRef = AccessTools.FieldRefAccess<Weapon, Player>("_holder");

		private static readonly ConditionalWeakTable<Weapon, MinigunController> _controllers = new ConditionalWeakTable<Weapon, MinigunController>();

		private static MinigunController Get(Weapon w)
		{
			if (_controllers.TryGetValue(w, out var value))
			{
				if (!value.IsMinigun)
				{
					return null;
				}
				return value;
			}
			value = MinigunController.Create(w);
			_controllers.Add(w, value);
			if (!value.IsMinigun)
			{
				return null;
			}
			return value;
		}

		private static bool IsLocalHeld(Weapon w)
		{
			Player val = _holderRef.Invoke(w);
			if ((Object)(object)val != (Object)null)
			{
				return ((NetworkBehaviour)val).Owner.IsLocalClient;
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Weapon), "Update")]
		private static void Update_Postfix(Weapon __instance)
		{
			MinigunController minigunController = Get(__instance);
			if (minigunController != null)
			{
				bool wantSpin = IsLocalHeld(__instance) && _holdingFire.Invoke(__instance);
				minigunController.Tick(__instance, wantSpin);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Weapon), "Shoot")]
		private static bool Shoot_Prefix(Weapon __instance)
		{
			MinigunController minigunController = Get(__instance);
			if (minigunController == null)
			{
				return true;
			}
			return minigunController.Spin >= 0.9f;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Weapon), "OnDrop")]
		private static void OnDrop_Postfix(Weapon __instance)
		{
			Get(__instance)?.OnDrop();
		}
	}
	[HarmonyPatch]
	public static class MinigunLoader
	{
		public static class MinigunAudioGen
		{
			private class Biquad
			{
				private double b0;

				private double b2;

				private double a1;

				private double a2;

				private double x1;

				private double x2;

				private double y1;

				private double y2;

				public void SetBandpass(double lo, double hi, double sr)
				{
					double num = Math.Sqrt(lo * hi);
					double num2 = Math.Log(hi / lo, 2.0);
					double num3 = Math.PI * 2.0 * num / sr;
					double num4 = Math.Cos(num3);
					double num5 = Math.Sin(num3);
					double num6 = num5 * Math.Sinh(Math.Log(2.0) / 2.0 * num2 * num3 / num5);
					double num7 = 1.0 + num6;
					b0 = num6 / num7;
					b2 = (0.0 - num6) / num7;
					a1 = -2.0 * num4 / num7;
					a2 = (1.0 - num6) / num7;
					x1 = (x2 = (y1 = (y2 = 0.0)));
				}

				public void ProcessInPlace(double[] x)
				{
					for (int i = 0; i < x.Length; i++)
					{
						double num = x[i];
						double num2 = b0 * num + b2 * x2 - a1 * y1 - a2 * y2;
						x2 = x1;
						x1 = num;
						y2 = y1;
						y1 = num2;
						x[i] = num2;
					}
				}
			}

			private const int SR = 44100;

			private const float MaxSpinSpeed = 2500f;

			private const int Barrels = 6;

			private const int NShots = 42;

			private const float Drive = 4f;

			public static AudioClip GenerateOverheatHiss()
			{
				double num = -0.45 * Math.Log(0.001);
				double num2 = 0.04 + num + 0.05;
				int num3 = (int)(44100.0 * num2);
				double[] array = new double[num3];
				Random random = new Random();
				for (int i = 0; i < num3; i++)
				{
					array[i] = random.NextDouble() * 2.0 - 1.0;
				}
				Biquad biquad = new Biquad();
				biquad.SetBandpass(2000.0, 7000.0, 44100.0);
				biquad.ProcessInPlace(array);
				for (int j = 0; j < num3; j++)
				{
					double num4 = (double)j / 44100.0;
					double num5 = ((j >= 1764) ? Math.Exp((0.0 - (num4 - 0.04)) / 0.45) : ((double)j / 1764.0));
					array[j] *= num5;
				}
				for (int k = 0; k < 2205; k++)
				{
					int num6 = num3 - 2205 + k;
					array[num6] *= 1.0 - (double)k / 2205.0;
				}
				double num7 = 0.0;
				for (int l = 0; l < num3; l++)
				{
					num7 = Math.Max(num7, Math.Abs(array[l]));
				}
				if (num7 > 0.0)
				{
					double num8 = 0.85 / num7;
					for (int m = 0; m < num3; m++)
					{
						array[m] = Math.Tanh(array[m] * num8);
					}
				}
				float[] array2 = new float[num3];
				for (int n = 0; n < num3; n++)
				{
					array2[n] = (float)array[n];
				}
				AudioClip obj = AudioClip.Create("overheat_hiss", num3, 1, 44100, false);
				obj.SetData(array2, 0);
				return obj;
			}

			public static AudioClip GenerateFireLoop()
			{
				int num = Mathf.RoundToInt(44452.797f);
				float num2 = (float)num / 42f;
				double[] array = new double[num];
				for (int i = 0; i < 42; i++)
				{
					Random r = new Random(1000 + i);
					float num3 = (float)(NextGaussian(r) * (double)num2 * 0.03);
					int center = Mathf.RoundToInt((float)i * num2 + num3);
					AddShot(array, num, center, r);
				}
				for (int j = 0; j < num; j++)
				{
					double t = (double)j / 44100.0;
					double num4 = 0.25 * LoopedSine(140.0, 1.0079998970031738, t) + 0.15 * LoopedSine(210.0, 1.0079998970031738, t) + 0.1 * LoopedSine(280.0, 1.0079998970031738, t);
					array[j] += num4 * 0.22;
				}
				double num5 = 0.0;
				for (int k = 0; k < num; k++)
				{
					num5 = Math.Max(num5, Math.Abs(array[k]));
				}
				if (num5 > 0.0)
				{
					for (int l = 0; l < num; l++)
					{
						array[l] /= num5;
					}
				}
				for (int m = 0; m < num; m++)
				{
					array[m] = Math.Tanh(array[m] * 4.0);
				}
				num5 = 0.0;
				for (int n = 0; n < num; n++)
				{
					num5 = Math.Max(num5, Math.Abs(array[n]));
				}
				float[] array2 = new float[num];
				for (int num6 = 0; num6 < num; num6++)
				{
					array2[num6] = (float)(array[num6] / num5 * 0.97);
				}
				AudioClip obj = AudioClip.Create("minigun_fire_loop", num, 1, 44100, false);
				obj.SetData(array2, 0);
				return obj;
			}

			private static void AddShot(double[] buf, int n, int center, Random r)
			{
				center = (center % n + n) % n;
				double[] array = new double[1323];
				for (int i = 0; i < 1323; i++)
				{
					array[i] = NextGaussian(r);
				}
				Biquad biquad = new Biquad();
				biquad.SetBandpass(250.0, 6500.0, 44100.0);
				biquad.ProcessInPlace(array);
				for (int j = 0; j < 1323; j++)
				{
					double num = (double)j / 44100.0;
					double num2 = Math.Exp((0.0 - num) * 130.0);
					if (j < 26)
					{
						num2 *= (double)j / 26.0;
					}
					double num3 = array[j] * num2;
					double num4 = Math.Sin(Math.PI * 190.0 * num) * Math.Exp((0.0 - num) * 50.0) * 0.75;
					int num5 = (j + center) % n;
					if (num5 < 0)
					{
						num5 += n;
					}
					buf[num5] += num3 * 0.9 + num4;
				}
			}

			private static double LoopedSine(double freq, double loopLen, double t)
			{
				double num = Math.Round(freq * loopLen);
				return Math.Sin(Math.PI * 2.0 * (num / loopLen) * t);
			}

			private static double NextGaussian(Random r)
			{
				double d = 1.0 - r.NextDouble();
				double num = 1.0 - r.NextDouble();
				return Math.Sqrt(-2.0 * Math.Log(d)) * Math.Sin(Math.PI * 2.0 * num);
			}
		}

		public const byte MINIGUN_ID = 86;

		private static bool _loadAttempted;

		private static AssetBundle _bundle;

		private static GameObject _prefab;

		private static Item _itemPrefab;

		private static AudioClip _spinClip;

		private static AudioClip _fireLoopClip;

		private static AudioClip _overheatClip;

		private static GameObject _purchasablePrefab;

		private static readonly Dictionary<string, (Vector3 pos, float yRot, Vector3 normal)> StandPositions = new Dictionary<string, (Vector3, float, Vector3)>
		{
			{
				"Island5",
				(new Vector3(-674f, 3.06f, -594.33f), 59.3f, new Vector3(0.007f, 0.994f, -0.113f))
			},
			{
				"Island4",
				(new Vector3(-163.24f, 1f, -784.65f), 305.5f, new Vector3(-0.002f, 1f, 0.001f))
			},
			{
				"Island3",
				(new Vector3(301.14f, -0.71f, -566.18f), 207.9f, new Vector3(-0.16f, 0.982f, 0.097f))
			}
		};

		public static AssetBundle Bundle
		{
			get
			{
				if ((Object)(object)_bundle == (Object)null && !_loadAttempted)
				{
					_bundle = LoadBundle();
				}
				return _bundle;
			}
		}

		public static GameObject Prefab
		{
			get
			{
				if ((Object)(object)_prefab != (Object)null)
				{
					return _prefab;
				}
				_prefab = LoadPrefab();
				return _prefab;
			}
		}

		public static Item ItemPrefab
		{
			get
			{
				if ((Object)(object)_itemPrefab != (Object)null)
				{
					return _itemPrefab;
				}
				GameObject prefab = Prefab;
				_itemPrefab = ((prefab != null) ? prefab.GetComponent<Item>() : null);
				if ((Object)(object)_itemPrefab == (Object)null)
				{
					Plugin.Log.LogError((object)"Item prefab NULL");
				}
				return _itemPrefab;
			}
		}

		public static AudioClip SpinUpAudioClip
		{
			get
			{
				if ((Object)(object)_spinClip != (Object)null)
				{
					return _spinClip;
				}
				AssetBundle bundle = Bundle;
				_spinClip = ((bundle != null) ? bundle.LoadAsset<AudioClip>("minigun_spin") : null);
				if ((Object)(object)_spinClip == (Object)null)
				{
					Plugin.Log.LogError((object)"Spin clip NULL");
				}
				return _spinClip;
			}
		}

		public static AudioClip FireLoopClip
		{
			get
			{
				if ((Object)(object)_fireLoopClip != (Object)null)
				{
					return _fireLoopClip;
				}
				_fireLoopClip = MinigunAudioGen.GenerateFireLoop();
				if ((Object)(object)_fireLoopClip == (Object)null)
				{
					Plugin.Log.LogError((object)"Fire loop generation returned null.");
				}
				else
				{
					Plugin.Log.LogInfo((object)$"Fire loop generated: {_fireLoopClip.length}s, {_fireLoopClip.samples} samples");
				}
				return _fireLoopClip;
			}
		}

		public static AudioClip OverheatClip
		{
			get
			{
				if ((Object)(object)_overheatClip != (Object)null)
				{
					return _overheatClip;
				}
				_overheatClip = MinigunAudioGen.GenerateOverheatHiss();
				if ((Object)(object)_overheatClip == (Object)null)
				{
					Plugin.Log.LogError((object)"Overheat clip generation returned null.");
				}
				else
				{
					Plugin.Log.LogInfo((object)$"Overheat clip generated: {_overheatClip.length}s, {_overheatClip.samples} samples");
				}
				return _overheatClip;
			}
		}

		public static GameObject PurchasablePrefab
		{
			get
			{
				if ((Object)(object)_purchasablePrefab != (Object)null)
				{
					return _purchasablePrefab;
				}
				AssetBundle bundle = Bundle;
				_purchasablePrefab = ((bundle != null) ? bundle.LoadAsset<GameObject>("Minigun (Purchasable)") : null);
				if ((Object)(object)_purchasablePrefab != (Object)null)
				{
					return _purchasablePrefab;
				}
				if ((Object)(object)Bundle != (Object)null)
				{
					Plugin.Log.LogError((object)("Purchasable prefab NULL. Assets: " + string.Join(", ", Bundle.GetAllAssetNames())));
				}
				return _purchasablePrefab;
			}
		}

		private static AssetBundle LoadBundle()
		{
			_loadAttempted = true;
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName != null)
			{
				string text = Path.Combine(directoryName, "ADHDCory_Assets", "minigun");
				if (!File.Exists(text))
				{
					Plugin.Log.LogError((object)("Bundle not found: " + text));
					return null;
				}
				_bundle = AssetBundle.LoadFromFile(text);
			}
			if ((Object)(object)_bundle != (Object)null)
			{
				Plugin.Log.LogError((object)"Minigun bundle loaded successfully.");
				AfterBundleLoadSuccess();
				return _bundle;
			}
			Plugin.Log.LogError((object)"Failed to load bundle.");
			return null;
		}

		private static GameObject LoadPrefab()
		{
			if ((Object)(object)Bundle == (Object)null)
			{
				return null;
			}
			GameObject val = Bundle.LoadAsset<GameObject>("minigun");
			if ((Object)(object)val != (Object)null)
			{
				Item component = val.GetComponent<Item>();
				if ((Object)(object)component != (Object)null)
				{
					Traverse.Create((object)component).Field("_id").SetValue((object)(byte)86);
					Plugin.Log.LogInfo((object)$"Minigun ID stamped: item.ID = {component.ID}");
				}
				Item val2 = GameInfo.IDToItem((byte)69);
				if (!(val2 is Weapon))
				{
					Plugin.Log.LogInfo((object)"smgItem IS NOT weapon.");
					return null;
				}
				Shader val3 = Shader.Find("Shader Graphs/DefaultShader");
				if ((Object)(object)val3 == (Object)null)
				{
					Weapon val4 = (Weapon)(object)((val2 is Weapon) ? val2 : null);
					if (val4 != null)
					{
						Renderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Renderer>(true);
						foreach (Renderer val5 in componentsInChildren)
						{
							if (!(val5 is ParticleSystemRenderer) && !(((Object)((Component)val5).gameObject).name != "SMG") && Object.op_Implicit((Object)(object)val5.sharedMaterial))
							{
								val3 = val5.sharedMaterial.shader;
								break;
							}
						}
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val6 in componentsInChildren)
					{
						if (val6 is ParticleSystemRenderer || ((Object)((Component)val6).gameObject).name == "Hands")
						{
							continue;
						}
						Material[] sharedMaterials = val6.sharedMaterials;
						foreach (Material val7 in sharedMaterials)
						{
							if (Object.op_Implicit((Object)(object)val7))
							{
								val7.shader = val3;
							}
						}
					}
				}
				else
				{
					Plugin.Log.LogError((object)"DefaultShader not found (Shader.Find and SMG fallback both failed).");
				}
				Transform val8 = val.transform.Find("MinigunAnimated/Rig/Gun/Attachments/BarrelAttachments/DefaultBarrel/Fire");
				try
				{
					ParticleSystem val9 = null;
					ParticleSystem[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem val10 in componentsInChildren2)
					{
						if (((Object)((Component)val10).gameObject).name.ToLower().Contains("fire"))
						{
							val9 = val10;
							break;
						}
					}
					ParticleSystem val11 = (Object.op_Implicit((Object)(object)val8) ? ((Component)val8).GetComponent<ParticleSystem>() : null);
					ParticleSystemRenderer val12 = (Object.op_Implicit((Object)(object)val9) ? ((Component)val9).GetComponent<ParticleSystemRenderer>() : null);
					ParticleSystemRenderer val13 = (Object.op_Implicit((Object)(object)val11) ? ((Component)val11).GetComponent<ParticleSystemRenderer>() : null);
					if (Object.op_Implicit((Object)(object)val12) && Object.op_Implicit((Object)(object)val13) && Object.op_Implicit((Object)(object)((Renderer)val12).sharedMaterial))
					{
						((Renderer)val13).sharedMaterial = ((Renderer)val12).sharedMaterial;
						Plugin.Log.LogInfo((object)("Flash: Flash material copied from '" + ((Object)((Component)val9).gameObject).name + "'."));
					}
					else
					{
						Plugin.Log.LogError((object)$"Flash: Flash copy failed: baseFlash={Object.op_Implicit((Object)(object)val9)}, myRend={Object.op_Implicit((Object)(object)val13)}");
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Flash: Flash copy threw (non-fatal): " + ex.Message + " Stack Trace: " + ex.StackTrace));
				}
				try
				{
					Material val14 = null;
					Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val15 in componentsInChildren)
					{
						if (!(val15 is ParticleSystemRenderer) && !(((Object)((Component)val15).gameObject).name != "Hands"))
						{
							val14 = val15.sharedMaterial;
							break;
						}
					}
					if (Object.op_Implicit((Object)(object)val14))
					{
						componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
						foreach (Renderer val16 in componentsInChildren)
						{
							if (!(val16 is ParticleSystemRenderer) && !(((Object)((Component)val16).gameObject).name != "Hands"))
							{
								Material[] sharedMaterials2 = val16.sharedMaterials;
								for (int k = 0; k < sharedMaterials2.Length; k++)
								{
									sharedMaterials2[k] = val14;
								}
								val16.sharedMaterials = sharedMaterials2;
							}
						}
					}
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogError((object)("Hands: Hands copy threw (non-fatal): " + ex2.Message + " Stack Trace: " + ex2.StackTrace));
				}
				try
				{
					List<Renderer> list = (from r in val.GetComponentsInChildren<Renderer>(true)
						where !(r is ParticleSystemRenderer) && ((Object)((Component)r).gameObject).name != "Hands"
						select r).ToList();
					Traverse.Create((object)val).Field("_skinRenderers").SetValue((object)list);
					Plugin.Log.LogInfo((object)$"Skin renderers wired: {list.Count}");
				}
				catch (Exception ex3)
				{
					Plugin.Log.LogError((object)("Skin renderer wiring threw: " + ex3.Message));
				}
				Collider value = Traverse.Create((object)component).Field("_pickUpCollider").GetValue<Collider>();
				if ((Object)(object)value != (Object)null)
				{
					((Component)value).gameObject.tag = "Item";
					((Component)value).gameObject.layer = LayerMask.NameToLayer("Item");
				}
				return val;
			}
			Plugin.Log.LogError((object)("Prefab not found. Assets: " + string.Join(", ", Bundle.GetAllAssetNames())));
			return null;
		}

		private static void AfterBundleLoadSuccess()
		{
			RegisterAllAudio();
		}

		private static void RegisterAllAudio()
		{
			LoaderHelper.RegisterAudioClip(Bundle.LoadAsset<AudioClip>("silence"), "silence1");
			Plugin.Log.LogInfo((object)"Re-registered clips after AudioManager.Start");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameInfo), "Awake")]
		private static void GameInfo_Awake_Postfix()
		{
			EnsureRegistered();
		}

		public static void EnsureRegistered()
		{
			if (!((Object)(object)GameInfo.IDToItem((byte)86) != (Object)null))
			{
				GameObject prefab = Prefab;
				Item val = ((prefab != null) ? prefab.GetComponent<Item>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					Traverse obj = Traverse.Create(typeof(GameInfo));
					obj.Field("_nameToSpawnable").GetValue<Dictionary<string, Item>>()[((Object)val).name.Replace(" ", "").ToLower()] = val;
					obj.Field("_idToSpawnable").GetValue<Dictionary<byte, Item>>()[86] = val;
					obj.Field("_allItems").GetValue<Dictionary<byte, Item>>()[86] = val;
					ManualLogSource log = Plugin.Log;
					object arg = (byte)86;
					Item obj2 = GameInfo.IDToItem((byte)86);
					log.LogInfo((object)$"Registered minigun id={arg}: {((obj2 != null) ? ((Object)obj2).name : null)}");
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Item), "GetName")]
		private static void GetName_Postfix(Item __instance, ref string __result)
		{
			__result = ((__instance.ID == 86) ? "Minigun" : __result);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioManager), "Start")]
		private static void AudioManager_Start_Postfix()
		{
			RegisterAllAudio();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Server), "OnStartClient")]
		private static void RegisterMinigunNetworkPrefab()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if ((Object)(object)networkManager == (Object)null)
			{
				Plugin.Log.LogError((object)"No NetworkManager for prefab registration.");
				return;
			}
			PrefabObjects prefabObjects = networkManager.GetPrefabObjects<SinglePrefabObjects>((ushort)999, true);
			NetworkObject component = Prefab.GetComponent<NetworkObject>();
			prefabObjects.AddObject(component, true, true);
			Plugin.Log.LogInfo((object)($"Minigun net prefab registered: collectionId={(ushort)999}, " + $"PrefabId={component.PrefabId}, SpawnableCollectionId={component.SpawnableCollectionId}"));
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Weapon), "OnDrop")]
		private static void Postfix(Weapon __instance)
		{
			if (((Item)__instance).ID == 86)
			{
				Animation value = Traverse.Create((object)__instance).Field("_anim").GetValue<Animation>();
				if ((Object)(object)value != (Object)null)
				{
					value.Stop();
				}
			}
		}

		public static void SpawnMinigunShopEntry(Scene scene)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			EnsureRegistered();
			if (StandPositions.TryGetValue(((Scene)(ref scene)).name, out (Vector3, float, Vector3) value))
			{
				if ((Object)(object)PurchasablePrefab == (Object)null)
				{
					Plugin.Log.LogError((object)"No purchasable prefab.");
					return;
				}
				Quaternion val = Quaternion.FromToRotation(Vector3.up, value.Item3);
				Quaternion val2 = Quaternion.Euler(0f, value.Item2, 0f);
				Quaternion val3 = val * val2;
				SceneManager.MoveGameObjectToScene(Object.Instantiate<GameObject>(PurchasablePrefab, value.Item1, val3), scene);
				Plugin.Log.LogInfo((object)$"Minigun stand placed at {value.Item1} in {((Scene)(ref scene)).name}");
			}
		}
	}
	[BepInPlugin("com.adhdcory.minigun_mod", "Minigun Mod", "1.0.3")]
	[HarmonyPatch]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			SceneManager.sceneLoaded += OnSceneLoaded;
			new Harmony("com.adhdcory.minigun_mod").PatchAll();
			Log.LogInfo((object)"Minigun mod loaded.");
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			MinigunLoader.SpawnMinigunShopEntry(scene);
		}
	}
}