Decompiled source of Boom Goes the Dynamite v0.2.5

BepInEx/plugins/BoomGoesTheDynamite/BoomGoesTheDynamite.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.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 BoomGoesTheDynamite
{
	public enum DeviceKind : byte
	{
		Super,
		Nuke,
		Timer,
		Mine
	}
	[Serializable]
	public sealed class DeviceState
	{
		public int objectId;

		public int timer = 5;

		public byte kind;

		public bool deployed;

		public bool armed;

		public bool activationStarted;

		public bool countdownStarted;

		public float armAt;

		public float voiceEndsAt;

		public Vector3 position;

		public Vector3 normal = Vector3.up;
	}
	[Serializable]
	public sealed class DeviceCommand
	{
		public int sequence;

		public int objectId;

		public int timer;

		public int kind;

		public string action;

		public Vector3 position;

		public Vector3 normal;
	}
	[Serializable]
	public sealed class DeviceSnapshot
	{
		public List<DeviceState> devices = new List<DeviceState>();
	}
	public struct CommandMessage : IBroadcast
	{
		public string json;
	}
	public struct StateMessage : IBroadcast
	{
		public string json;
	}
	public struct ReplyMessage : IBroadcast
	{
		public string text;
	}
	[Serializable]
	public sealed class DetonationEvent
	{
		public byte kind;

		public Vector3 position;

		public string sound;

		public float radius;
	}
	public struct NukeFlashMessage : IBroadcast
	{
		public string json;
	}
	[BepInPlugin("ponyfisher.howtofish.boomgoesthedynamite", "Boom goes the Dynamite", "0.2.5")]
	[DefaultExecutionOrder(29400)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "ponyfisher.howtofish.boomgoesthedynamite";

		public static Plugin Instance;

		public static readonly byte[] Ids = new byte[4] { 237, 236, 235, 234 };

		public static readonly ushort[] Collections = new ushort[4] { 42433, 42434, 42435, 42436 };

		public static readonly string[] Names = new string[4] { "Super Dynamite", "Nuke", "Time Bomb", "Proximity Mine" };

		public static readonly int[] Prices = new int[4] { 100, 1000, 150, 200 };

		public static readonly float[] DamageRadius = new float[4] { 13f, 250f, 8f, 7f };

		public static readonly int[] Damage = new int[4] { 250, 15000, 100, 110 };

		public static readonly Explosive[] Prefabs = (Explosive[])(object)new Explosive[4];

		private static int vanillaDamage;

		private static float vanillaRadius;

		private static float vanillaSoundVolume;

		public static bool SuppressDrop;

		public readonly List<DeviceState> Devices = new List<DeviceState>();

		private NetworkManager manager;

		private Harmony harmony;

		private bool registrationFailed;

		private bool menuOpen;

		private int sequence;

		private float nextState;

		private float nextTick;

		private float nextIcon;

		private float nextNukeAudio;

		private float holdFStarted;

		private float holdEStarted;

		private float nukeHoldStart;

		private float nukePickupStart;

		private bool fHolding;

		private bool eHolding;

		private bool holdEFired;

		private Item holdItem;

		private Item nukeTarget;

		private Item nukePickupTarget;

		private NPC vendor;

		private string status = "";

		private float statusUntil;

		private readonly HashSet<int> detonatedNukes = new HashSet<int>();

		private string currentWorld;

		private readonly Dictionary<int, int> lastSequence = new Dictionary<int, int>();

		private Rect window = new Rect(0f, 0f, 610f, 460f);

		private bool windowReady;

		private int chosenTimer = 5;

		private GUIStyle titleStyle;

		private GUIStyle boxStyle;

		private GUIStyle buttonStyle;

		private GUIStyle warningStyle;

		private bool flashActive;

		private bool flashMuted;

		private float flashStart;

		private float oldListenerVolume;

		private AudioSource aftermathTone;

		private float nukeProgress;

		private float nukePickupProgress;

		private bool timerOpen;

		public bool MenuOpen => menuOpen;

		public void TryRegister()
		{
			if (!registrationFailed && (Object)(object)Prefabs[0] == (Object)null)
			{
				RegisterPrefabs();
			}
		}

		public void ReportRegistration(Exception error)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Dynamite registration deferred: " + error.Message));
		}

		private static string Json(object value)
		{
			return JsonUtility.ToJson(value);
		}

		private static T Parse<T>(string json)
		{
			return JsonUtility.FromJson<T>(json);
		}

		public static bool IsBoom(Item item)
		{
			if ((Object)(object)item != (Object)null && Array.IndexOf(Ids, item.ID) >= 0)
			{
				return (Object)(object)((Component)item).GetComponent<BoomVisual>() != (Object)null;
			}
			return false;
		}

		public static DeviceKind Kind(Item item)
		{
			return (DeviceKind)Array.IndexOf(Ids, item.ID);
		}

		public DeviceState Find(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			NetworkObject net = ((Component)item).GetComponent<NetworkObject>();
			if (!((Object)(object)net == (Object)null))
			{
				return Devices.FirstOrDefault((DeviceState s) => s.objectId == net.ObjectId);
			}
			return null;
		}

		private static FieldInfo Field(Type type, string name)
		{
			return AccessTools.Field(type, name);
		}

		public static bool Activated(Explosive explosive)
		{
			if ((Object)(object)explosive != (Object)null)
			{
				return (bool)Field(typeof(Explosive), "_isActivated").GetValue(explosive);
			}
			return false;
		}

		public static float Remaining(Explosive explosive)
		{
			if (!((Object)(object)explosive == (Object)null))
			{
				return (float)Field(typeof(Explosive), "_timeUntilExplosion").GetValue(explosive);
			}
			return 0f;
		}

		private void Awake()
		{
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			Instance = this;
			GenericWriter<CommandMessage>.SetWrite((Action<Writer, CommandMessage>)delegate(Writer w, CommandMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<CommandMessage>.SetRead((Func<Reader, CommandMessage>)((Reader r) => new CommandMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<StateMessage>.SetWrite((Action<Writer, StateMessage>)delegate(Writer w, StateMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<StateMessage>.SetRead((Func<Reader, StateMessage>)((Reader r) => new StateMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<ReplyMessage>.SetWrite((Action<Writer, ReplyMessage>)delegate(Writer w, ReplyMessage v)
			{
				w.WriteString(v.text);
			});
			GenericReader<ReplyMessage>.SetRead((Func<Reader, ReplyMessage>)((Reader r) => new ReplyMessage
			{
				text = r.ReadStringAllocated()
			}));
			GenericWriter<NukeFlashMessage>.SetWrite((Action<Writer, NukeFlashMessage>)delegate(Writer w, NukeFlashMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<NukeFlashMessage>.SetRead((Func<Reader, NukeFlashMessage>)((Reader r) => new NukeFlashMessage
			{
				json = r.ReadStringAllocated()
			}));
			NukeAudio.EnsureLoaded((MonoBehaviour)(object)this);
			harmony = new Harmony("ponyfisher.howtofish.boomgoesthedynamite");
			harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Boom goes the Dynamite 0.2.5 loaded.");
		}

		private void RegisterNetwork()
		{
			if ((Object)(object)manager != (Object)null)
			{
				manager.ServerManager.UnregisterBroadcast<CommandMessage>((Action<NetworkConnection, CommandMessage, Channel>)Receive);
				manager.ClientManager.UnregisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState);
				manager.ClientManager.UnregisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply);
				manager.ClientManager.UnregisterBroadcast<NukeFlashMessage>((Action<NukeFlashMessage, Channel>)ReceiveFlash);
			}
			manager = InstanceFinder.NetworkManager;
			if (!((Object)(object)manager == (Object)null))
			{
				manager.ServerManager.RegisterBroadcast<CommandMessage>((Action<NetworkConnection, CommandMessage, Channel>)Receive, true);
				manager.ClientManager.RegisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState);
				manager.ClientManager.RegisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply);
				manager.ClientManager.RegisterBroadcast<NukeFlashMessage>((Action<NukeFlashMessage, Channel>)ReceiveFlash);
			}
		}

		private void Update()
		{
			if ((Object)(object)manager != (Object)(object)InstanceFinder.NetworkManager)
			{
				RegisterNetwork();
			}
			if (!registrationFailed && (Object)(object)Prefabs[0] == (Object)null)
			{
				try
				{
					RegisterPrefabs();
				}
				catch (Exception ex)
				{
					registrationFailed = true;
					((BaseUnityPlugin)this).Logger.LogError((object)ex);
					Say("Dynamite registration failed; see BepInEx log.");
				}
			}
			if (Time.unscaledTime >= nextIcon)
			{
				nextIcon = Time.unscaledTime + 0.25f;
				BoomInventoryIcon.RefreshAll();
			}
			if (Time.unscaledTime >= nextNukeAudio)
			{
				nextNukeAudio = Time.unscaledTime + 5f;
				NukeAudio.EnsureLoaded((MonoBehaviour)(object)this);
			}
			Player localPlayer = Player.LocalPlayer;
			vendor = FocusedVendor(localPlayer);
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				bool flag = (Object)(object)localPlayer != (Object)null && ((IsBoom(localPlayer.Holding.HeldItem) && Kind(localPlayer.Holding.HeldItem) == DeviceKind.Nuke) || (Object)(object)RayNuke(localPlayer) != (Object)null);
				if ((Object)(object)vendor != (Object)null && !flag && !menuOpen && ((ButtonControl)current.fKey).wasPressedThisFrame)
				{
					fHolding = true;
					holdFStarted = Time.unscaledTime;
				}
				if (fHolding && ((ButtonControl)current.fKey).isPressed && (Object)(object)vendor != (Object)null && !flag && Time.unscaledTime - holdFStarted >= 0.8f)
				{
					fHolding = false;
					OpenMenu();
				}
				if (!((ButtonControl)current.fKey).isPressed || (Object)(object)vendor == (Object)null || flag)
				{
					fHolding = false;
				}
				if (!menuOpen)
				{
					UpdateHeldInteraction(current, localPlayer);
					UpdateNukeActivation(current, localPlayer);
					UpdateNukePickup(current, localPlayer);
				}
				if (menuOpen && ((ButtonControl)current.escapeKey).wasPressedThisFrame)
				{
					CloseMenu();
				}
			}
			UpdateFlash();
			if (InstanceFinder.IsServerStarted)
			{
				string text = ((SaveManager.CurServerSave == null) ? null : SaveManager.CurServerSave.Name);
				if (currentWorld != text)
				{
					currentWorld = text;
					detonatedNukes.Clear();
					Devices.Clear();
				}
				if (Time.unscaledTime >= nextTick)
				{
					nextTick = Time.unscaledTime + 0.15f;
					ServerTick();
				}
				if (Time.unscaledTime >= nextState)
				{
					nextState = Time.unscaledTime + 0.35f;
					Broadcast();
				}
			}
			else if (currentWorld != null)
			{
				currentWorld = null;
				detonatedNukes.Clear();
				Devices.Clear();
			}
		}

		private static ExplosionInfo CopyExplosion(ExplosionInfo source)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ExplosionInfo val = new ExplosionInfo();
			FieldInfo[] fields = typeof(ExplosionInfo).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!fieldInfo.IsInitOnly)
				{
					fieldInfo.SetValue(val, fieldInfo.GetValue(source));
				}
			}
			Field(typeof(ExplosionInfo), "<HasExploded>k__BackingField")?.SetValue(val, false);
			return val;
		}

		internal static void SetExplosion(Explosive item, DeviceKind kind)
		{
			ExplosionInfo val = CopyExplosion(((Item)item).GetExplosionInfo());
			int num = ((kind == DeviceKind.Super) ? Math.Min(1073741823, ((vanillaDamage > 0) ? vanillaDamage : val.Damage) * 3) : Damage[(uint)kind]);
			float num2 = ((kind == DeviceKind.Super) ? (((vanillaRadius > 0f) ? vanillaRadius : val.DamageRadius) * 3f) : DamageRadius[(uint)kind]);
			Field(typeof(ExplosionInfo), "_damage").SetValue(val, num);
			Field(typeof(ExplosionInfo), "damageRadius").SetValue(val, num2);
			Field(typeof(ExplosionInfo), "_forceRadius").SetValue(val, num2 * 1.1f);
			if (kind == DeviceKind.Nuke)
			{
				Field(typeof(ExplosionInfo), "_explosionSoundVol").SetValue(val, Mathf.Max(1f, vanillaSoundVolume * 3f));
			}
			Field(typeof(Explosive), "_explosionInfo").SetValue(item, val);
			Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(item, kind switch
			{
				DeviceKind.Timer => 5f, 
				DeviceKind.Mine => 0.5f, 
				_ => 5f, 
			});
			Field(typeof(Explosive), "_activatedExplosionDelay").SetValue(item, kind switch
			{
				DeviceKind.Mine => 0.5f, 
				DeviceKind.Nuke => 10f, 
				_ => 5f, 
			});
			Field(typeof(Explosive), "_activatable").SetValue(item, kind == DeviceKind.Super);
			if (kind == DeviceKind.Super)
			{
				Field(typeof(Explosive), "_fuseLightPercent").SetValue(item, 0f);
			}
		}

		private void RegisterPrefabs()
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_020c: 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)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)InstanceFinder.NetworkManager == (Object)null)
			{
				return;
			}
			Dictionary<byte, Item> dictionary = (Dictionary<byte, Item>)Field(typeof(GameInfo), "_idToSpawnable").GetValue(null);
			if (dictionary.Count == 0)
			{
				return;
			}
			Explosive val = (from e in dictionary.Values.OfType<Explosive>()
				where ((object)e).GetType() == typeof(Explosive) && (Object)(object)((Component)e).GetComponent<NetworkObject>() != (Object)null && (Object)(object)((Component)e).GetComponent<BoomVisual>() == (Object)null
				orderby ((Item)e).ID
				select e).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			vanillaDamage = ((Item)val).GetExplosionInfo().Damage;
			vanillaRadius = ((Item)val).GetExplosionInfo().DamageRadius;
			vanillaSoundVolume = ((Item)val).GetExplosionInfo().ExplosionSoundVol;
			for (int num = 0; num < 4; num++)
			{
				if (dictionary.ContainsKey(Ids[num]))
				{
					throw new Exception("Item ID " + Ids[num] + " is occupied by another mod.");
				}
			}
			GameObject val2 = new GameObject("Boom Dynamite prefab storage");
			val2.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val2);
			for (int num2 = 0; num2 < 4; num2++)
			{
				DeviceKind deviceKind = (DeviceKind)num2;
				Explosive val3 = Object.Instantiate<Explosive>(val, val2.transform);
				((Object)val3).name = Names[num2];
				Field(typeof(Item), "_id").SetValue(val3, Ids[num2]);
				Field(typeof(Item), "_cost").SetValue(val3, Prices[num2]);
				Field(typeof(Item), "_worth").SetValue(val3, Prices[num2] / 2);
				Field(typeof(Item), "_ignoredByMoneyNPC").SetValue(val3, false);
				Field(typeof(Item), "_heldPos").SetValue(val3, (object)new Vector3(0.18f, -0.34f, 0.7f));
				Field(typeof(Item), "_heldRot").SetValue(val3, (object)new Vector3(0f, 25f, 0f));
				SetExplosion(val3, deviceKind);
				Renderer[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Renderer>(true);
				for (int num3 = 0; num3 < componentsInChildren.Length; num3++)
				{
					componentsInChildren[num3].enabled = false;
				}
				BoomVisual boomVisual = ((Component)val3).gameObject.AddComponent<BoomVisual>();
				boomVisual.Build(deviceKind);
				Field(typeof(Item), "_renderers").SetValue(val3, (from r in ((Component)boomVisual).GetComponentsInChildren<Renderer>(true)
					where r.enabled
					select r).ToList());
				Field(typeof(Item), "_mesh").SetValue(val3, boomVisual.InventoryMesh);
				Field(typeof(Item), "_inventoryMeshScale").SetValue(val3, 0.7f);
				Field(typeof(Item), "_inventoryMeshPos").SetValue(val3, Vector3.zero);
				Field(typeof(Item), "_inventoryMeshRot").SetValue(val3, (object)new Vector3(20f, 35f, 0f));
				NetworkObject component = ((Component)val3).GetComponent<NetworkObject>();
				component.SetIsSpawnable(true);
				PrefabObjects prefabObjects = manager.GetPrefabObjects<SinglePrefabObjects>(Collections[num2], true);
				if (prefabObjects.GetObjectCount() != 0)
				{
					throw new Exception("Prefab collection " + Collections[num2] + " is occupied.");
				}
				prefabObjects.AddObject(component, false, true);
				dictionary.Add(Ids[num2], (Item)(object)val3);
				((Dictionary<byte, Item>)Field(typeof(GameInfo), "_allItems").GetValue(null)).Add(Ids[num2], (Item)(object)val3);
				((Dictionary<string, Item>)Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null)).Add("boomdynamite_" + deviceKind.ToString().ToLowerInvariant(), (Item)(object)val3);
				Prefabs[num2] = val3;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered four Boom Dynamite explosive items.");
		}

		private int OpenSlot(Player player)
		{
			int num = (int)AccessTools.Method(typeof(PlayerInventory), "GetTotalSlots", (Type[])null, (Type[])null).Invoke(player.Inventory, null);
			Item val = default(Item);
			for (byte b = 0; b < num; b++)
			{
				if (!player.Inventory._items.TryGetValue(b, ref val) || (Object)(object)val == (Object)null)
				{
					return b;
				}
			}
			return -1;
		}

		private void Receive(NetworkConnection connection, CommandMessage message, Channel channel)
		{
			if (!InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json) || message.json.Length > 2000)
			{
				return;
			}
			try
			{
				DeviceCommand deviceCommand = Parse<DeviceCommand>(message.json);
				if (deviceCommand != null && deviceCommand.sequence > 0 && (!lastSequence.TryGetValue(connection.ClientId, out var value) || deviceCommand.sequence > value))
				{
					lastSequence[connection.ClientId] = deviceCommand.sequence;
					Player val = ((IEnumerable<Player>)Object.FindObjectsByType<Player>()).FirstOrDefault((Func<Player, bool>)((Player p) => ((NetworkBehaviour)p).Owner == connection));
					if ((Object)(object)val != (Object)null)
					{
						Execute(val, deviceCommand, connection);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Rejected dynamite request: " + ex.Message));
			}
		}

		private void ReceiveState(StateMessage message, Channel channel)
		{
			if (InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json))
			{
				return;
			}
			DeviceSnapshot deviceSnapshot = Parse<DeviceSnapshot>(message.json);
			if (deviceSnapshot == null || deviceSnapshot.devices == null)
			{
				return;
			}
			Devices.Clear();
			Devices.AddRange(deviceSnapshot.devices);
			foreach (DeviceState device in Devices)
			{
				if (device.kind == 2)
				{
					Item obj = FindItem(device.objectId);
					Explosive val = (Explosive)(object)((obj is Explosive) ? obj : null);
					if ((Object)(object)val != (Object)null)
					{
						Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(val, (float)device.timer);
					}
				}
			}
		}

		private void ReceiveReply(ReplyMessage message, Channel channel)
		{
			Say(message.text);
		}

		private void ReceiveFlash(NukeFlashMessage message, Channel channel)
		{
			if (InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json))
			{
				return;
			}
			try
			{
				DetonationEvent detonationEvent = Parse<DetonationEvent>(message.json);
				if (detonationEvent != null)
				{
					ShowDetonation(detonationEvent);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Invalid detonation event: " + ex.Message));
			}
		}

		private void Broadcast()
		{
			if ((Object)(object)manager != (Object)null)
			{
				manager.ServerManager.Broadcast<StateMessage>(new StateMessage
				{
					json = Json(new DeviceSnapshot
					{
						devices = Devices
					})
				}, true, (Channel)0);
			}
		}

		private void Say(string message)
		{
			status = message;
			statusUntil = Time.unscaledTime + 4f;
		}

		private void Reply(NetworkConnection connection, string message)
		{
			if (connection == (NetworkConnection)null || connection.IsLocalClient)
			{
				Say(message);
				return;
			}
			manager.ServerManager.Broadcast<ReplyMessage>(connection, new ReplyMessage
			{
				text = message
			}, true, (Channel)0);
		}

		private void Send(string action, int kind = 0, Item item = null, Vector3 position = default(Vector3), Vector3 normal = default(Vector3), int timer = 5)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.LocalPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				NetworkObject val = (((Object)(object)item == (Object)null) ? null : ((Component)item).GetComponent<NetworkObject>());
				DeviceCommand deviceCommand = new DeviceCommand
				{
					action = action,
					kind = kind,
					objectId = ((!((Object)(object)val == (Object)null)) ? val.ObjectId : 0),
					position = position,
					normal = normal,
					timer = timer,
					sequence = ++sequence
				};
				if (InstanceFinder.IsServerStarted)
				{
					Execute(localPlayer, deviceCommand, null);
				}
				else if ((Object)(object)manager != (Object)null && InstanceFinder.IsClientStarted)
				{
					manager.ClientManager.Broadcast<CommandMessage>(new CommandMessage
					{
						json = Json(deviceCommand)
					}, (Channel)0);
				}
			}
		}

		private Item FindItem(int objectId)
		{
			return ((IEnumerable<Item>)Object.FindObjectsByType<Item>()).FirstOrDefault((Func<Item, bool>)delegate(Item i)
			{
				if (IsBoom(i))
				{
					NetworkObject component = ((Component)i).GetComponent<NetworkObject>();
					if (component == null)
					{
						return false;
					}
					return component.ObjectId == objectId;
				}
				return false;
			});
		}

		private bool ValidSurface(Player player, DeviceCommand cmd, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if (!Finite(cmd.position) || !Finite(cmd.normal) || ((Vector3)(ref cmd.normal)).sqrMagnitude < 0.5f || (Object)(object)player.CamObject == (Object)null || Vector3.Distance(player.CamObject.position, cmd.position) > 8.5f)
			{
				return false;
			}
			if (Kind(item) == DeviceKind.Nuke && ((Vector3)(ref cmd.normal)).normalized.y < Mathf.Cos((float)Math.PI / 6f))
			{
				return false;
			}
			foreach (RaycastHit item2 in from h in Physics.RaycastAll(cmd.position + ((Vector3)(ref cmd.normal)).normalized * 0.25f, -((Vector3)(ref cmd.normal)).normalized, 0.55f, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item2;
				if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() != (Object)(object)item && (Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)null && Vector3.Dot(((RaycastHit)(ref current)).normal, ((Vector3)(ref cmd.normal)).normalized) > 0.7f)
				{
					return true;
				}
			}
			return false;
		}

		private static bool Finite(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(v.x) && !float.IsNaN(v.y) && !float.IsNaN(v.z) && !float.IsInfinity(v.x) && !float.IsInfinity(v.y))
			{
				return !float.IsInfinity(v.z);
			}
			return false;
		}

		private void Execute(Player player, DeviceCommand cmd, NetworkConnection connection)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0693: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0710: Expected O, but got Unknown
			if (player.Dying.IsDead)
			{
				return;
			}
			try
			{
				if (cmd.action == "buy")
				{
					int kind = cmd.kind;
					if (kind < 0 || kind >= 4 || (Object)(object)Prefabs[kind] == (Object)null || !NearMoneyVendor(player))
					{
						Reply(connection, "Stay near a shopkeeper to buy dynamite.");
						return;
					}
					int num = OpenSlot(player);
					if (num < 0)
					{
						Reply(connection, "Free an inventory slot first.");
						return;
					}
					if (!Wallet.Charge(player, Prices[kind]))
					{
						Reply(connection, "Not enough money.");
						return;
					}
					try
					{
						Explosive val = Object.Instantiate<Explosive>(Prefabs[kind], ((Component)player).transform.position + Vector3.up, Quaternion.identity, Server.Instance.DynamicObjectsHolder);
						((Item)val).LoadFromSave(new SavedItem
						{
							Exists = true,
							ItemID = Ids[kind],
							BettingMultiplier = 1f,
							Weight = 1f,
							KillScoreMultiplier = 1f
						});
						InstanceFinder.ServerManager.Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene));
						((Item)val).SetSyncedHolder(player, true);
						player.Inventory.AddItem((byte)num, (Item)(object)val);
						if (!player.Inventory.HasItemInInventory((Item)(object)val))
						{
							throw new Exception("Inventory rejected the item.");
						}
						Reply(connection, Names[kind] + " purchased for $" + Prices[kind] + ".");
						return;
					}
					catch
					{
						Wallet.Credit(player, Prices[kind]);
						throw;
					}
				}
				Item val2 = FindItem(cmd.objectId);
				if ((Object)(object)val2 == (Object)null)
				{
					Reply(connection, "Explosive unavailable.");
					return;
				}
				DeviceKind deviceKind = Kind(val2);
				DeviceState deviceState;
				Vector3 val3;
				if (cmd.action == "activate")
				{
					if (deviceKind != DeviceKind.Nuke)
					{
						return;
					}
					deviceState = Find(val2);
					bool flag = (Object)(object)val2.SyncedHolder == (Object)(object)player;
					if (deviceState == null && flag)
					{
						deviceState = new DeviceState
						{
							objectId = cmd.objectId,
							kind = 1
						};
						Devices.Add(deviceState);
					}
					if (deviceState == null || deviceState.activationStarted || (!deviceState.deployed && !flag))
					{
						return;
					}
					if (!flag)
					{
						if (!((Object)(object)player.CamObject == (Object)null) && !(Vector3.Distance(player.CamObject.position, ((Component)val2).transform.position) > 5.5f))
						{
							Vector3 forward = player.CamObject.forward;
							val3 = ((Component)val2).transform.position + Vector3.up * 0.45f - player.CamObject.position;
							if (!(Vector3.Dot(forward, ((Vector3)(ref val3)).normalized) < 0.75f))
							{
								goto IL_02e9;
							}
						}
						Reply(connection, "Look at the deployed nuke from nearby.");
						return;
					}
					goto IL_02e9;
				}
				if (cmd.action == "pickup")
				{
					DeviceState deviceState2 = Find(val2);
					if (deviceKind != DeviceKind.Nuke || deviceState2 == null || !deviceState2.deployed || (Object)(object)val2.SyncedHolder != (Object)null)
					{
						Reply(connection, "That nuke is not deployed.");
						return;
					}
					if (!((Object)(object)player.CamObject == (Object)null) && !(Vector3.Distance(player.CamObject.position, ((Component)val2).transform.position) > 5.5f))
					{
						Vector3 forward2 = player.CamObject.forward;
						val3 = ((Component)val2).transform.position + Vector3.up * 0.45f - player.CamObject.position;
						if (!(Vector3.Dot(forward2, ((Vector3)(ref val3)).normalized) < 0.75f))
						{
							int num2 = OpenSlot(player);
							bool flag2 = (Object)(object)player.Holding.HeldItem == (Object)null && (Object)(object)player.Holding.UninitializedHeldItem == (Object)null && (Object)(object)player.Inventory.SyncedCurItem == (Object)null;
							if (num2 < 0 && !flag2)
							{
								Reply(connection, "Free an inventory slot or empty your hands first.");
								return;
							}
							deviceState2.deployed = false;
							val2.RigidbodySync.SetKinematic(false);
							int value = player.Inventory._syncedCurSlot.Value;
							val2.SetSyncedHolder(player, true);
							if (num2 >= 0)
							{
								player.Inventory.AddItem((byte)num2, val2);
							}
							val2.ReconcileLocalHolderWithSyncedHolder();
							if (num2 >= 0)
							{
								player.Inventory.ServerSetSyncedCurSlot(value);
							}
							if (!deviceState2.activationStarted)
							{
								Devices.Remove(deviceState2);
							}
							Broadcast();
							Reply(connection, "Nuke picked up.");
							return;
						}
					}
					Reply(connection, "Look at the deployed nuke from nearby.");
				}
				else if ((Object)(object)val2.SyncedHolder != (Object)(object)player || deviceKind == DeviceKind.Super)
				{
					Reply(connection, "Hold that explosive before placing it.");
				}
				else
				{
					if (!(cmd.action == "deploy"))
					{
						return;
					}
					if (!ValidSurface(player, cmd, val2))
					{
						Reply(connection, (deviceKind == DeviceKind.Nuke) ? "Place the nuke on level ground or a slope under 30 degrees." : "Look at a surface within 8 metres.");
						return;
					}
					SuppressDrop = true;
					try
					{
						val2.SpawnFromInventory();
						player.Inventory.RemoveItem(val2);
						if ((Object)(object)val2.Holder != (Object)null)
						{
							val3 = default(Vector3);
							Vector3 val4 = val3;
							val3 = default(Vector3);
							val2.Drop(false, val4, val3);
						}
						val2.SetSyncedHolder((Player)null, true);
						val2.ReconcileLocalHolderWithSyncedHolder();
						if ((Object)(object)player.Holding.HeldItem == (Object)(object)val2)
						{
							player.Hands.DropItem(false, val2);
							player.Holding.DropItem(false, val2);
							player.Holding.SetHeldItem((Item)null);
						}
						if ((Object)(object)player.Holding.UninitializedHeldItem == (Object)(object)val2)
						{
							player.Holding.SetUninitializedHeldItem((Item)null);
						}
					}
					finally
					{
						SuppressDrop = false;
					}
					DeviceState deviceState3 = Find(val2);
					if (deviceState3 == null)
					{
						deviceState3 = new DeviceState
						{
							objectId = cmd.objectId,
							kind = (byte)deviceKind
						};
						Devices.Add(deviceState3);
					}
					deviceState3.deployed = true;
					deviceState3.armed = false;
					if (deviceKind != DeviceKind.Nuke)
					{
						deviceState3.activationStarted = false;
						deviceState3.countdownStarted = false;
					}
					deviceState3.armAt = ((deviceKind == DeviceKind.Mine) ? (Time.unscaledTime + 1f) : 0f);
					deviceState3.timer = Mathf.Clamp(cmd.timer, 5, 20);
					deviceState3.normal = ((Vector3)(ref cmd.normal)).normalized;
					deviceState3.position = cmd.position + deviceState3.normal * 0.04f;
					val2.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)Server.Instance).Owner);
					val2.RigidbodySync.TeleportToPosRot(deviceState3.position, Quaternion.FromToRotation(Vector3.up, deviceState3.normal), (float[])null, (Quaternion[])null);
					val2.RigidbodySync.SetKinematic(true);
					Broadcast();
					if (deviceKind == DeviceKind.Timer)
					{
						Arm((Explosive)val2, deviceState3.timer, player);
					}
					Reply(connection, deviceKind switch
					{
						DeviceKind.Nuke => "Nuke deployed. Hold F to activate or hold E to pick it up.", 
						DeviceKind.Timer => "Time Bomb deployed; " + deviceState3.timer + "-second timer started.", 
						_ => "Proximity Mine deployed; arming for one second.", 
					});
				}
				return;
				IL_02e9:
				deviceState.activationStarted = true;
				deviceState.voiceEndsAt = Time.unscaledTime + NukeAudio.Duration;
				Broadcast();
				Reply(connection, "Nuke activated. Get clear!");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				Reply(connection, "Dynamite action failed; check the BepInEx log.");
			}
		}

		public static void Arm(Explosive explosive, float seconds, Player player)
		{
			if (!((Object)(object)explosive == (Object)null) && ((NetworkBehaviour)explosive).IsServerInitialized && !Activated(explosive))
			{
				Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(explosive, seconds);
				explosive.ForceExplode(player, false);
			}
		}

		public bool CanArmNuke(Explosive item)
		{
			DeviceState deviceState = Find((Item)(object)item);
			if (deviceState != null && deviceState.activationStarted)
			{
				return deviceState.countdownStarted;
			}
			return false;
		}

		public void OnDetonation(Explosive explosive)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServerStarted || (Object)(object)explosive == (Object)null)
			{
				return;
			}
			DeviceKind deviceKind = Kind((Item)(object)explosive);
			if (deviceKind != DeviceKind.Nuke && deviceKind != DeviceKind.Super)
			{
				return;
			}
			NetworkObject component = ((Component)explosive).GetComponent<NetworkObject>();
			int item = (((Object)(object)component == (Object)null) ? ((object)explosive).GetHashCode() : component.ObjectId);
			if (!detonatedNukes.Add(item))
			{
				return;
			}
			DetonationEvent detonationEvent = new DetonationEvent
			{
				kind = (byte)deviceKind,
				position = ((Component)explosive).transform.position,
				sound = ((Item)explosive).GetExplosionInfo().ExplosionSoundName,
				radius = ((Item)explosive).GetExplosionInfo().DamageRadius
			};
			if ((Object)(object)manager != (Object)null)
			{
				manager.ServerManager.Broadcast<NukeFlashMessage>(new NukeFlashMessage
				{
					json = Json(detonationEvent)
				}, true, (Channel)0);
			}
			if ((Object)(object)Player.LocalPlayer != (Object)null)
			{
				ShowDetonation(detonationEvent);
			}
			if (deviceKind != DeviceKind.Nuke)
			{
				return;
			}
			Creature[] array = Object.FindObjectsByType<Creature>();
			foreach (Creature val in array)
			{
				if (!((Object)(object)val == (Object)null) && !val.IsDead)
				{
					val.ServerChangeHp(Mathf.Max(1, val.Hp));
					if (!val.IsDead)
					{
						object obj = Field(typeof(Creature), "_hp")?.GetValue(val);
						(obj?.GetType().GetProperty("Value"))?.SetValue(obj, 0, null);
					}
				}
			}
			Player[] array2 = Object.FindObjectsByType<Player>();
			foreach (Player val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && !val2.Dying.IsDead && !PlayerManager.InGodMode)
				{
					val2.Vitals.TakeDamage(1000000, Vector3.zero, detonationEvent.position, true);
				}
			}
		}

		private void ShowDetonation(DetonationEvent effect)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (effect.kind == 0)
			{
				SuperBlastVisual.Spawn(effect.position, effect.radius);
			}
			else
			{
				if (effect.kind != 1)
				{
					return;
				}
				if (flashMuted)
				{
					AudioListener.volume = oldListenerVolume;
					if ((Object)(object)aftermathTone != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)aftermathTone).gameObject);
					}
					aftermathTone = null;
				}
				flashActive = true;
				flashMuted = false;
				flashStart = Time.unscaledTime + 0.15f;
				if (!string.IsNullOrEmpty(effect.sound) && (Object)(object)Player.LocalPlayer != (Object)null)
				{
					Vector3 val = (((Object)(object)Player.LocalPlayer.CamObject == (Object)null) ? effect.position : Player.LocalPlayer.CamObject.position);
					AudioManager.PlayClipAt(effect.sound, val, false, (AudioDistance)3, 1f, 0.05f);
					AudioManager.PlayClipAt(effect.sound, val, false, (AudioDistance)3, 1f, 0.05f);
				}
			}
		}

		private void UpdateFlash()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if (!flashActive || Time.unscaledTime < flashStart)
			{
				return;
			}
			if (!flashMuted)
			{
				oldListenerVolume = AudioListener.volume;
				flashMuted = true;
				AudioListener.volume = 0f;
				GameObject val = new GameObject("Nuke aftermath ringing");
				aftermathTone = val.AddComponent<AudioSource>();
				aftermathTone.clip = NukeAudio.Tinnitus;
				aftermathTone.loop = true;
				aftermathTone.spatialBlend = 0f;
				aftermathTone.ignoreListenerVolume = true;
				aftermathTone.volume = 0.18f;
				aftermathTone.Play();
			}
			float num = Time.unscaledTime - flashStart;
			float num2 = Mathf.Clamp01((num - 2f) / 2.5f);
			AudioListener.volume = oldListenerVolume * num2;
			if ((Object)(object)aftermathTone != (Object)null)
			{
				aftermathTone.volume = 0.18f * (1f - num2);
			}
			if (num >= 4.5f)
			{
				AudioListener.volume = oldListenerVolume;
				flashActive = false;
				flashMuted = false;
				if ((Object)(object)aftermathTone != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)aftermathTone).gameObject);
				}
				aftermathTone = null;
			}
		}

		private void ServerTick()
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			for (int num = Devices.Count - 1; num >= 0; num--)
			{
				DeviceState deviceState = Devices[num];
				Item val = FindItem(deviceState.objectId);
				if ((Object)(object)val == (Object)null)
				{
					Devices.RemoveAt(num);
				}
				else if (deviceState.kind == 1)
				{
					if (deviceState.activationStarted && !deviceState.countdownStarted && Time.unscaledTime >= deviceState.voiceEndsAt)
					{
						deviceState.countdownStarted = true;
						Arm((Explosive)val, 10f, val.LastPlayer);
						Broadcast();
					}
				}
				else
				{
					if (!deviceState.deployed)
					{
						continue;
					}
					if ((Object)(object)val.SyncedHolder != (Object)null)
					{
						Devices.RemoveAt(num);
					}
					else
					{
						if (deviceState.kind != 3 || Activated((Explosive)val))
						{
							continue;
						}
						if (!deviceState.armed)
						{
							if (Time.unscaledTime < deviceState.armAt)
							{
								continue;
							}
							deviceState.armed = true;
							Broadcast();
						}
						Creature[] array = Object.FindObjectsByType<Creature>();
						foreach (Creature val2 in array)
						{
							if ((Object)(object)val2 != (Object)null && !val2.IsDead && Vector3.Distance(((Component)val2).transform.position, deviceState.position) <= 3.5f)
							{
								Arm((Explosive)val, 0.5f, val.LastPlayer);
								Broadcast();
								break;
							}
						}
					}
				}
			}
		}

		private static bool IsMoneyVendor(NPC npc)
		{
			if ((Object)(object)npc == (Object)null)
			{
				return false;
			}
			if (Field(typeof(NPC), "_quests")?.GetValue(npc) is IEnumerable<NPCQuest> source)
			{
				return source.Any((NPCQuest q) => (Object)(object)q != (Object)null && (int)q.Type == 1);
			}
			return false;
		}

		private static Vector3 VendorInteractionPoint(NPC npc)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)npc.MouthPosForItems != (Object)null))
			{
				return ((Component)npc).transform.position + Vector3.up;
			}
			return npc.MouthPosForItems.position;
		}

		private bool NearMoneyVendor(Player player)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			Vector3 val = (((Object)(object)player.CamObject != (Object)null) ? player.CamObject.position : (((Component)player).transform.position + Vector3.up));
			NPC[] array = Object.FindObjectsByType<NPC>();
			foreach (NPC npc in array)
			{
				if (IsMoneyVendor(npc) && Vector3.Distance(val, VendorInteractionPoint(npc)) <= 7f)
				{
					return true;
				}
			}
			return false;
		}

		private NPC FocusedVendor(Player player)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null)
			{
				return null;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, 5.5f, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player))
				{
					NPC componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<NPC>();
					if (IsMoneyVendor(componentInParent))
					{
						return componentInParent;
					}
					if (!((RaycastHit)(ref current)).collider.isTrigger)
					{
						break;
					}
				}
			}
			NPC result = null;
			float num = 0.72f;
			NPC[] array = Object.FindObjectsByType<NPC>();
			foreach (NPC val in array)
			{
				if (!IsMoneyVendor(val))
				{
					continue;
				}
				Vector3 val2 = VendorInteractionPoint(val) - player.CamObject.position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!(magnitude > 5.5f) && !(magnitude < 0.01f))
				{
					float num3 = Vector3.Dot(player.CamObject.forward, val2 / magnitude);
					if (num3 > num)
					{
						result = val;
						num = num3;
					}
				}
			}
			return result;
		}

		private bool CrosshairSurface(Item held, out RaycastHit surface)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			surface = default(RaycastHit);
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null)
			{
				return false;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, 8f, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)localPlayer) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() == (Object)(object)held))
				{
					surface = current;
					return true;
				}
			}
			return false;
		}

		private void UpdateHeldInteraction(Keyboard kb, Player player)
		{
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead)
			{
				eHolding = false;
				holdItem = null;
				return;
			}
			Item val = (((Object)(object)player == (Object)null) ? null : player.Holding.HeldItem);
			if (((ButtonControl)kb.eKey).wasPressedThisFrame && IsBoom(val) && (Kind(val) == DeviceKind.Timer || Kind(val) == DeviceKind.Mine || Kind(val) == DeviceKind.Nuke))
			{
				holdItem = val;
				eHolding = true;
				holdEFired = false;
				holdEStarted = Time.unscaledTime;
			}
			if (eHolding && (Object)(object)holdItem != (Object)null && ((ButtonControl)kb.eKey).isPressed && !holdEFired && Kind(holdItem) != DeviceKind.Nuke && Time.unscaledTime - holdEStarted >= 0.8f)
			{
				holdEFired = true;
				if ((Object)(object)holdItem == (Object)null || (Object)(object)holdItem != (Object)(object)val)
				{
					return;
				}
				if (!CrosshairSurface(holdItem, out var surface))
				{
					Say("Look at a surface within 8 metres.");
					return;
				}
				Send("deploy", 0, holdItem, ((RaycastHit)(ref surface)).point, ((RaycastHit)(ref surface)).normal, chosenTimer);
			}
			if (((ButtonControl)kb.eKey).wasReleasedThisFrame && eHolding && !holdEFired && (Object)(object)holdItem == (Object)(object)val && Kind(val) == DeviceKind.Timer)
			{
				OpenTimer();
			}
			if (((ButtonControl)kb.eKey).wasReleasedThisFrame && eHolding && !holdEFired && (Object)(object)holdItem == (Object)(object)val && Kind(val) == DeviceKind.Nuke && Time.unscaledTime - holdEStarted < 0.8f)
			{
				if (CrosshairSurface(val, out var surface2))
				{
					Send("deploy", 0, val, ((RaycastHit)(ref surface2)).point, ((RaycastHit)(ref surface2)).normal, chosenTimer);
				}
				else
				{
					Say("Look at level ground to place the nuke.");
				}
			}
			if (!((ButtonControl)kb.eKey).isPressed)
			{
				eHolding = false;
				holdItem = null;
			}
		}

		private Item RayNuke(Player player)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null)
			{
				return null;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, 5f, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player)
				{
					continue;
				}
				Item componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>();
				if (IsBoom(componentInParent) && Kind(componentInParent) == DeviceKind.Nuke)
				{
					DeviceState deviceState = Find(componentInParent);
					if (deviceState != null && deviceState.deployed && (Object)(object)componentInParent.SyncedHolder == (Object)null)
					{
						return componentInParent;
					}
				}
				if (!((RaycastHit)(ref current)).collider.isTrigger)
				{
					break;
				}
			}
			return null;
		}

		public bool LookingAtNuke()
		{
			return (Object)(object)RayNuke(Player.LocalPlayer) != (Object)null;
		}

		private void UpdateNukeActivation(Keyboard kb, Player player)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead)
			{
				nukeTarget = null;
				nukeHoldStart = 0f;
				nukeProgress = 0f;
				return;
			}
			Item heldItem = player.Holding.HeldItem;
			Item val = ((IsBoom(heldItem) && Kind(heldItem) == DeviceKind.Nuke && (Find(heldItem) == null || !Find(heldItem).activationStarted)) ? heldItem : RayNuke(player));
			if ((Object)(object)val != (Object)null)
			{
				DeviceState deviceState = Find(val);
				if (deviceState != null && deviceState.activationStarted)
				{
					val = null;
				}
			}
			if ((Object)(object)val != (Object)(object)nukeTarget)
			{
				nukeTarget = val;
				nukeHoldStart = 0f;
				nukeProgress = 0f;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (((ButtonControl)kb.fKey).wasPressedThisFrame)
			{
				nukeHoldStart = Time.unscaledTime;
			}
			if (((ButtonControl)kb.fKey).isPressed && nukeHoldStart > 0f)
			{
				nukeProgress = Mathf.Clamp01((Time.unscaledTime - nukeHoldStart) / 5f);
				if (nukeProgress >= 1f)
				{
					Send("activate", 0, val);
					nukeHoldStart = 0f;
					nukeProgress = 0f;
					nukeTarget = null;
				}
			}
			if (((ButtonControl)kb.fKey).wasReleasedThisFrame)
			{
				nukeHoldStart = 0f;
				nukeProgress = 0f;
			}
		}

		private void UpdateNukePickup(Keyboard kb, Player player)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead)
			{
				nukePickupTarget = null;
				nukePickupStart = 0f;
				nukePickupProgress = 0f;
				return;
			}
			Item val = RayNuke(player);
			if ((Object)(object)val != (Object)(object)nukePickupTarget)
			{
				nukePickupTarget = val;
				nukePickupStart = 0f;
				nukePickupProgress = 0f;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (((ButtonControl)kb.eKey).wasPressedThisFrame)
			{
				nukePickupStart = Time.unscaledTime;
			}
			if (((ButtonControl)kb.eKey).isPressed && nukePickupStart > 0f)
			{
				nukePickupProgress = Mathf.Clamp01((Time.unscaledTime - nukePickupStart) / 1f);
				if (nukePickupProgress >= 1f)
				{
					Send("pickup", 0, val);
					nukePickupStart = 0f;
					nukePickupProgress = 0f;
					nukePickupTarget = null;
				}
			}
			if (((ButtonControl)kb.eKey).wasReleasedThisFrame)
			{
				nukePickupStart = 0f;
				nukePickupProgress = 0f;
			}
		}

		private void OpenMenu()
		{
			menuOpen = true;
			timerOpen = false;
			SetWindow();
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			PlayerCamera.ToggleMouse(true);
		}

		private void OpenTimer()
		{
			menuOpen = true;
			timerOpen = true;
			SetWindow();
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			PlayerCamera.ToggleMouse(true);
		}

		private void SetWindow()
		{
			if (!windowReady)
			{
				((Rect)(ref window)).x = ((float)Screen.width - ((Rect)(ref window)).width) / 2f;
				((Rect)(ref window)).y = ((float)Screen.height - ((Rect)(ref window)).height) / 2f;
				windowReady = true;
			}
		}

		private void CloseMenu()
		{
			menuOpen = false;
			timerOpen = false;
			PlayerCamera.ToggleMouse(false);
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
		}

		private void OnGUI()
		{
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Expected O, but got Unknown
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			InitStyles();
			if ((Object)(object)vendor != (Object)null && !menuOpen && (Object)(object)nukeTarget == (Object)null && (Object)(object)nukePickupTarget == (Object)null)
			{
				float num = (fHolding ? Mathf.Clamp01((Time.unscaledTime - holdFStarted) / 0.8f) : 0f);
				GUI.Box(new Rect((float)Screen.width * 0.5f - 240f, (float)Screen.height * 0.68f, 480f, 35f), "Hold F for Boom Dynamite Shop" + (fHolding ? ("  " + num.ToString("P0")) : ""), boxStyle);
			}
			Item item = (((Object)(object)Player.LocalPlayer == (Object)null) ? null : Player.LocalPlayer.Holding.HeldItem);
			if (!menuOpen && IsBoom(item))
			{
				string text = ((Kind(item) == DeviceKind.Timer) ? ("Tap E to set timer (" + chosenTimer + "s)  |  Hold E to deploy") : ((Kind(item) == DeviceKind.Nuke) ? "Tap E to place Nuke  |  Hold F 5 seconds to activate" : ((Kind(item) == DeviceKind.Mine) ? "Hold E to deploy Proximity Mine" : "Click Mouse1 to light fuse, then throw")));
				GUI.Box(new Rect((float)Screen.width * 0.5f - 320f, (float)Screen.height * 0.76f, 640f, 35f), text, boxStyle);
			}
			if (!menuOpen && (Object)(object)nukeTarget != (Object)null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.box)
				{
					fontSize = 23,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val.normal.textColor = new Color(1f, 0.12f, 0.1f);
				float num2 = (float)Screen.width * 0.5f - 270f;
				float num3 = (float)Screen.height * 0.7f;
				GUI.Box(new Rect(num2, num3, 540f, 52f), "HOLD F TO ACTIVATE NUKE  " + Mathf.RoundToInt(nukeProgress * 100f) + "%", val);
				Color color = GUI.color;
				GUI.color = new Color(1f, 0.06f, 0.04f);
				GUI.DrawTexture(new Rect(num2 + 8f, num3 + 45f, 524f * nukeProgress, 6f), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color;
			}
			if (!menuOpen && (Object)(object)nukePickupTarget != (Object)null)
			{
				float num4 = (float)Screen.width * 0.5f - 270f;
				float num5 = (float)Screen.height * 0.78f;
				GUI.Box(new Rect(num4, num5, 540f, 35f), "Hold E to pick up Nuke  " + Mathf.RoundToInt(nukePickupProgress * 100f) + "%", boxStyle);
			}
			if (Time.unscaledTime < statusUntil)
			{
				GUI.Box(new Rect((float)Screen.width * 0.5f - 260f, (float)Screen.height * 0.79f, 520f, 32f), status, boxStyle);
			}
			if (menuOpen)
			{
				((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref window)).width));
				((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref window)).height));
				window = GUI.Window(1112493901, window, new WindowFunction(DrawWindow), timerOpen ? "TIME BOMB TIMER" : "BOOM GOES THE DYNAMITE", boxStyle);
			}
			if (flashActive && Time.unscaledTime >= flashStart)
			{
				float num6 = Time.unscaledTime - flashStart;
				float num7 = ((num6 <= 2f) ? 1f : (1f - Mathf.Clamp01((num6 - 2f) / 2.5f)));
				int depth = GUI.depth;
				GUI.depth = -10000;
				Color color2 = GUI.color;
				GUI.color = new Color(1f, 1f, 1f, num7);
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color2;
				GUI.depth = depth;
			}
		}

		private void InitStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b9: 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_00d3: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			if (boxStyle == null)
			{
				boxStyle = new GUIStyle(GUI.skin.box)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				boxStyle.normal.textColor = Color.white;
				buttonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				titleStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 21,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				titleStyle.normal.textColor = new Color(1f, 0.25f, 0.2f);
				warningStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					wordWrap = true
				};
				warningStyle.normal.textColor = Color.white;
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Invalid comparison between Unknown and I4
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			Color color = GUI.color;
			GUI.color = new Color(0.16f, 0.02f, 0.025f, 0.97f);
			GUI.DrawTexture(new Rect(4f, 4f, ((Rect)(ref window)).width - 8f, ((Rect)(ref window)).height - 8f), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			GUI.Label(new Rect(15f, 32f, ((Rect)(ref window)).width - 30f, 34f), timerOpen ? "Choose the time bomb fuse" : "CHOOSE YOUR EXPLOSIVE", titleStyle);
			if (timerOpen)
			{
				chosenTimer = Mathf.RoundToInt(GUI.HorizontalSlider(new Rect(70f, 120f, ((Rect)(ref window)).width - 140f, 26f), (float)chosenTimer, 5f, 20f));
				GUI.Label(new Rect(60f, 153f, ((Rect)(ref window)).width - 120f, 35f), "Timer: " + chosenTimer + " seconds", titleStyle);
				if (GUI.Button(new Rect(90f, 222f, ((Rect)(ref window)).width - 180f, 50f), "SAVE TIMER", buttonStyle))
				{
					CloseMenu();
				}
			}
			else
			{
				for (int i = 0; i < 4; i++)
				{
					float num = 78 + i * 78;
					Texture2D val = BoomVisual.Icon((DeviceKind)i);
					if ((Object)(object)val != (Object)null)
					{
						GUI.DrawTexture(new Rect(26f, num, 62f, 62f), (Texture)(object)val, (ScaleMode)2, true);
					}
					GUI.Label(new Rect(103f, num + 7f, 270f, 48f), Names[i], titleStyle);
					if (GUI.Button(new Rect(((Rect)(ref window)).width - 184f, num + 9f, 155f, 44f), "BUY $" + Prices[i], buttonStyle))
					{
						Send("buy", i);
					}
				}
			}
			if (GUI.Button(new Rect(((Rect)(ref window)).width - 47f, 10f, 34f, 26f), "X", buttonStyle))
			{
				CloseMenu();
			}
			GUI.Label(new Rect(((Rect)(ref window)).width - 28f, ((Rect)(ref window)).height - 30f, 24f, 24f), "↘", warningStyle);
			Event current = Event.current;
			if ((int)current.type == 3)
			{
				Rect val2 = new Rect(((Rect)(ref window)).width - 36f, ((Rect)(ref window)).height - 38f, 36f, 38f);
				if (((Rect)(ref val2)).Contains(current.mousePosition))
				{
					((Rect)(ref window)).width = Mathf.Clamp(((Rect)(ref window)).width + current.delta.x, 500f, (float)Mathf.Max(500, Screen.width));
					((Rect)(ref window)).height = Mathf.Clamp(((Rect)(ref window)).height + current.delta.y, 400f, (float)Mathf.Max(400, Screen.height));
					current.Use();
				}
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref window)).width - 55f, 30f));
		}

		private void OnDestroy()
		{
			if (flashMuted)
			{
				AudioListener.volume = oldListenerVolume;
			}
			if ((Object)(object)aftermathTone != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)aftermathTone).gameObject);
			}
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Instance = null;
		}
	}
	internal static class Wallet
	{
		private static Type WalletType => Type.GetType("NoSharedMoney.Wallets, NoSharedMoney", throwOnError: false);

		public static bool Charge(Player player, int amount)
		{
			Type walletType = WalletType;
			if (walletType != null)
			{
				if ((int)AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null).Invoke(null, new object[1] { player }) < amount)
				{
					return false;
				}
				AccessTools.Method(walletType, "Remove", new Type[2]
				{
					typeof(Player),
					typeof(int)
				}, (Type[])null).Invoke(null, new object[2] { player, amount });
				return true;
			}
			if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(amount))
			{
				return false;
			}
			MoneyManager.RemoveMoney(amount, player);
			return true;
		}

		public static void Credit(Player player, int amount)
		{
			Type walletType = WalletType;
			if (walletType != null)
			{
				AccessTools.Method(walletType, "Add", new Type[2]
				{
					typeof(Player),
					typeof(int)
				}, (Type[])null).Invoke(null, new object[2] { player, amount });
			}
			else
			{
				MoneyManager.AddMoney(amount, player);
			}
		}
	}
	[HarmonyPatch(typeof(Item), "GetName")]
	internal static class BoomName
	{
		private static bool Prefix(Item __instance, ref string __result)
		{
			if (!Plugin.IsBoom(__instance))
			{
				return true;
			}
			__result = Plugin.Names[(uint)Plugin.Kind(__instance)];
			return false;
		}
	}
	public static class Beep
	{
		private static AudioClip shortClip;

		private static AudioClip loudClip;

		private static AudioClip Clip
		{
			get
			{
				if ((Object)(object)shortClip != (Object)null)
				{
					return shortClip;
				}
				int num = 1874;
				float[] array = new float[num];
				for (int i = 0; i < num; i++)
				{
					float num2 = (float)i / 22050f;
					float num3 = Mathf.Sin((float)Math.PI * (float)i / (float)num);
					array[i] = Mathf.Sin(num2 * 2f * (float)Math.PI * 900f) * num3 * 0.22f;
				}
				shortClip = AudioClip.Create("Boom Dynamite Beep", num, 1, 22050, false);
				shortClip.SetData(array, 0);
				return shortClip;
			}
		}

		public static void Play(Vector3 at, int count = 1)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < count; i++)
			{
				AudioSource.PlayClipAtPoint(Clip, at, 0.27f);
			}
		}

		public static void PlayLoud(Vector3 at)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)loudClip == (Object)null)
			{
				int num = 4189;
				float[] array = new float[num];
				for (int i = 0; i < num; i++)
				{
					float num2 = (float)i / 22050f;
					float num3 = Mathf.Sin((float)Math.PI * (float)i / (float)num);
					array[i] = Mathf.Sin(num2 * 2f * (float)Math.PI * 850f) * num3 * 0.65f;
				}
				loudClip = AudioClip.Create("Boom Dynamite Loud Beep", num, 1, 22050, false);
				loudClip.SetData(array, 0);
			}
			AudioSource.PlayClipAtPoint(loudClip, at, 0.85f);
		}
	}
	public sealed class BoomVisual : MonoBehaviour
	{
		private static readonly Texture2D[] icons = (Texture2D[])(object)new Texture2D[4];

		private static readonly string[] iconFiles = new string[4] { "super-dynamite.png", "nuke.png", "time-bomb.png", "proximity-mine.png" };

		private static Material red;

		private static Material dark;

		private static Material yellow;

		private static Material orange;

		private static Material white;

		private static Material glass;

		private static Material bubbleMaterial;

		private Mesh inventoryMesh;

		private Renderer bubble;

		private DeviceKind kind;

		private Item item;

		private Explosive explosive;

		private bool lastDeployed;

		private bool lastActivated;

		private int lastBeepSecond = int.MaxValue;

		private float nextAlarm;

		private float voiceLocalEnd;

		public Mesh InventoryMesh => inventoryMesh;

		public static Texture2D Icon(DeviceKind kind)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if ((int)kind < 0 || (int)kind >= 4)
			{
				return null;
			}
			if ((Object)(object)icons[(uint)kind] != (Object)null)
			{
				return icons[(uint)kind];
			}
			using Stream stream = typeof(BoomVisual).Assembly.GetManifestResourceStream("BoomDynamite." + iconFiles[(uint)kind]);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, memoryStream.ToArray());
			((Texture)val).wrapMode = (TextureWrapMode)1;
			icons[(uint)kind] = val;
			return val;
		}

		private static Material Material(Color color)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			return new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"))
			{
				color = color
			};
		}

		private static Transform Part(Transform parent, string name, PrimitiveType type, Vector3 pos, Vector3 scale, Material mat, Vector3 rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = pos;
			obj.transform.localEulerAngles = rotation;
			obj.transform.localScale = scale;
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			obj.GetComponent<Renderer>().sharedMaterial = mat;
			return obj.transform;
		}

		public void Build(DeviceKind choice)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0875: Unknown result type (might be due to invalid IL or missing references)
			//IL_0886: Unknown result type (might be due to invalid IL or missing references)
			//IL_0890: Unknown result type (might be due to invalid IL or missing references)
			//IL_0742: Unknown result type (might be due to invalid IL or missing references)
			//IL_0756: Unknown result type (might be due to invalid IL or missing references)
			//IL_0760: Unknown result type (might be due to invalid IL or missing references)
			//IL_0794: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0812: Unknown result type (might be due to invalid IL or missing references)
			//IL_0826: Unknown result type (might be due to invalid IL or missing references)
			//IL_0830: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0703: Unknown result type (might be due to invalid IL or missing references)
			//IL_071c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0948: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0932: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_091c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0906: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0993: Unknown result type (might be due to invalid IL or missing references)
			//IL_097d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)this).transform.Find("BoomDeviceModel") != (Object)null)
			{
				return;
			}
			kind = choice;
			item = ((Component)this).GetComponent<Item>();
			explosive = ((Component)this).GetComponent<Explosive>();
			if ((Object)(object)red == (Object)null)
			{
				red = Material(new Color(0.75f, 0.06f, 0.045f));
				dark = Material(new Color(0.11f, 0.12f, 0.15f));
				yellow = Material(new Color(1f, 0.67f, 0.035f));
				orange = Material(new Color(0.93f, 0.28f, 0.03f));
				white = Material(new Color(0.9f, 0.88f, 0.8f));
				glass = Material(new Color(0.23f, 0.75f, 0.85f));
				bubbleMaterial = new Material(Shader.Find("Sprites/Default"))
				{
					color = new Color(1f, 0.035f, 0.035f, 0.2f)
				};
			}
			Transform transform = new GameObject("BoomDeviceModel").transform;
			transform.SetParent(((Component)this).transform, false);
			if (kind == DeviceKind.Mine)
			{
				transform.localScale = Vector3.one * 0.7f;
			}
			Transform val = null;
			try
			{
				val = GlbModel.Create(transform, kind);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("Dynamite GLB import failed for " + kind.ToString() + ": " + ex.Message));
			}
			if ((Object)(object)val != (Object)null)
			{
				inventoryMesh = ((Component)val).GetComponent<MeshFilter>().sharedMesh;
			}
			else if (kind == DeviceKind.Super)
			{
				for (int i = 0; i < 2; i++)
				{
					for (int j = -1; j <= 1; j++)
					{
						Transform val2 = Part(transform, "RedDynamiteStick", (PrimitiveType)2, new Vector3((float)j * 0.18f, (float)i * 0.15f, 0f), new Vector3(0.1f, 0.38f, 0.1f), red, new Vector3(90f, 0f, 0f));
						if ((Object)(object)inventoryMesh == (Object)null)
						{
							inventoryMesh = ((Component)val2).GetComponent<MeshFilter>().sharedMesh;
						}
					}
				}
				Part(transform, "SteelStrapA", (PrimitiveType)3, new Vector3(0f, 0.08f, -0.24f), new Vector3(0.57f, 0.08f, 0.09f), dark, Vector3.zero);
				Part(transform, "SteelStrapB", (PrimitiveType)3, new Vector3(0f, 0.08f, 0.24f), new Vector3(0.57f, 0.08f, 0.09f), dark, Vector3.zero);
				Part(transform, "Fuse", (PrimitiveType)2, new Vector3(0f, 0.34f, 0f), new Vector3(0.035f, 0.16f, 0.035f), yellow, new Vector3(0f, 0f, -30f));
			}
			else if (kind == DeviceKind.Nuke)
			{
				Transform val3 = Part(transform, "NukeCanister", (PrimitiveType)2, new Vector3(0f, 0.38f, 0f), new Vector3(0.36f, 0.45f, 0.36f), dark, Vector3.zero);
				inventoryMesh = ((Component)val3).GetComponent<MeshFilter>().sharedMesh;
				Part(transform, "TopBand", (PrimitiveType)2, new Vector3(0f, 0.73f, 0f), new Vector3(0.37f, 0.055f, 0.37f), yellow, Vector3.zero);
				Part(transform, "BottomBand", (PrimitiveType)2, new Vector3(0f, 0.08f, 0f), new Vector3(0.37f, 0.055f, 0.37f), yellow, Vector3.zero);
				Part(transform, "HazardBadge", (PrimitiveType)3, new Vector3(0f, 0.42f, 0.365f), new Vector3(0.35f, 0.28f, 0.03f), yellow, Vector3.zero);
				Part(transform, "HazardCenter", (PrimitiveType)2, new Vector3(0f, 0.42f, 0.389f), new Vector3(0.06f, 0.012f, 0.06f), dark, new Vector3(90f, 0f, 0f));
				for (int k = 0; k < 3; k++)
				{
					Part(transform, "HazardRay", (PrimitiveType)3, new Vector3(0f, 0.42f, 0.39f), new Vector3(0.045f, 0.12f, 0.015f), dark, new Vector3(0f, 0f, (float)(k * 120)));
				}
				Part(transform, "NukeFuseCap", (PrimitiveType)2, new Vector3(0f, 0.86f, 0f), new Vector3(0.09f, 0.07f, 0.09f), orange, Vector3.zero);
			}
			else if (kind == DeviceKind.Timer)
			{
				Transform val4 = Part(transform, "TimerBlock", (PrimitiveType)3, new Vector3(0f, 0.25f, 0f), new Vector3(0.72f, 0.47f, 0.52f), orange, Vector3.zero);
				inventoryMesh = ((Component)val4).GetComponent<MeshFilter>().sharedMesh;
				Part(transform, "TimerBand", (PrimitiveType)3, new Vector3(0f, 0.25f, 0f), new Vector3(0.75f, 0.1f, 0.55f), dark, Vector3.zero);
				Part(transform, "ClockFace", (PrimitiveType)2, new Vector3(0f, 0.29f, 0.275f), new Vector3(0.22f, 0.02f, 0.22f), white, new Vector3(90f, 0f, 0f));
				Part(transform, "ClockHand", (PrimitiveType)3, new Vector3(0.03f, 0.34f, 0.3f), new Vector3(0.025f, 0.14f, 0.014f), red, new Vector3(0f, 0f, 25f));
				Part(transform, "WireLeft", (PrimitiveType)2, new Vector3(-0.16f, 0.58f, 0f), new Vector3(0.025f, 0.12f, 0.025f), red, new Vector3(0f, 0f, -20f));
				Part(transform, "WireRight", (PrimitiveType)2, new Vector3(0.16f, 0.58f, 0f), new Vector3(0.025f, 0.12f, 0.025f), glass, new Vector3(0f, 0f, 20f));
			}
			else
			{
				Transform val5 = Part(transform, "MineBody", (PrimitiveType)2, new Vector3(0f, 0.1f, 0f), new Vector3(0.6f, 0.12f, 0.6f), red, Vector3.zero);
				inventoryMesh = ((Component)val5).GetComponent<MeshFilter>().sharedMesh;
				Part(transform, "MineRim", (PrimitiveType)2, new Vector3(0f, 0.09f, 0f), new Vector3(0.62f, 0.075f, 0.62f), dark, Vector3.zero);
				Part(transform, "PressurePad", (PrimitiveType)2, new Vector3(0f, 0.18f, 0f), new Vector3(0.36f, 0.035f, 0.36f), dark, Vector3.zero);
				Part(transform, "RedSensor", (PrimitiveType)0, new Vector3(0f, 0.22f, 0.3f), new Vector3(0.1f, 0.06f, 0.1f), red, Vector3.zero);
			}
			if (kind == DeviceKind.Mine)
			{
				GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)0);
				((Object)val6).name = "MineDetectionBubble";
				val6.transform.SetParent(((Component)this).transform, false);
				val6.transform.localPosition = Vector3.zero;
				val6.transform.localScale = Vector3.one * 7f;
				Object.DestroyImmediate((Object)(object)val6.GetComponent<Collider>());
				bubble = val6.GetComponent<Renderer>();
				bubble.sharedMaterial = bubbleMaterial;
				bubble.enabled = false;
			}
			BoxCollider val7 = ((Component)transform).gameObject.AddComponent<BoxCollider>();
			val7.center = ((kind == DeviceKind.Nuke) ? new Vector3(0f, 0.43f, 0f) : ((kind == DeviceKind.Timer) ? new Vector3(0f, 0.29f, 0f) : ((kind == DeviceKind.Mine) ? new Vector3(0f, 0.12f, 0f) : new Vector3(0f, 0.12f, 0f))));
			val7.size = ((kind == DeviceKind.Nuke) ? new Vector3(0.76f, 0.9f, 0.76f) : ((kind == DeviceKind.Timer) ? new Vector3(0.76f, 0.65f, 0.56f) : ((kind == DeviceKind.Mine) ? new Vector3(1.22f, 0.28f, 1.22f) : new Vector3(0.68f, 0.52f, 0.85f))));
			FieldInfo fieldInfo = AccessTools.Field(typeof(Item), "_worldColliders");
			fieldInfo.SetValue(value: new List<Collider>((IEnumerable<Collider>)(((object)(fieldInfo.GetValue(item) as Collider[])) ?? ((object)new Collider[0]))) { (Collider)(object)val7 }.ToArray(), obj: item);
		}

		private void Awake()
		{
			item = ((Component)this).GetComponent<Item>();
			explosive = ((Component)this).GetComponent<Explosive>();
			if ((Object)(object)item != (Object)null && Plugin.IsBoom(item))
			{
				kind = Plugin.Kind(item);
				Plugin.SetExplosion(explosive, kind);
			}
			Transform val = ((Component)this).transform.Find("MineDetectionBubble");
			if ((Object)(object)val != (Object)null)
			{
				bubble = ((Component)val).GetComponent<Renderer>();
			}
		}

		private void Update()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null || (Object)(object)explosive == (Object)null || (Object)(object)Plugin.Instance == (Object)null)
			{
				return;
			}
			DeviceState deviceState = Plugin.Instance.Find(item);
			bool flag = deviceState?.deployed ?? false;
			if (flag)
			{
				((Component)this).transform.SetPositionAndRotation(deviceState.position, Quaternion.FromToRotation(Vector3.up, deviceState.normal));
			}
			bool flag2 = Plugin.Activated(explosive);
			if ((Object)(object)bubble != (Object)null)
			{
				bubble.enabled = flag && kind == DeviceKind.Mine && deviceState.armed && !flag2;
			}
			if (kind == DeviceKind.Mine && flag && !deviceState.armed && Time.unscaledTime >= nextAlarm)
			{
				nextAlarm = Time.unscaledTime + 0.25f;
				Beep.Play(((Component)this).transform.position);
			}
			if (kind == DeviceKind.Nuke && deviceState != null && deviceState.activationStarted && !lastActivated)
			{
				if (!deviceState.countdownStarted)
				{
					NukeAudio.PlayActivation(((Component)this).transform.position);
					voiceLocalEnd = Time.unscaledTime + NukeAudio.Duration;
				}
				else
				{
					voiceLocalEnd = Time.unscaledTime;
				}
			}
			if (flag2)
			{
				float num = Plugin.Remaining(explosive);
				if (kind == DeviceKind.Timer)
				{
					if (num > 1f)
					{
						int num2 = Mathf.CeilToInt(num);
						if (num2 < lastBeepSecond)
						{
							lastBeepSecond = num2;
							Beep.PlayLoud(((Component)this).transform.position);
						}
					}
					else if (Time.unscaledTime >= nextAlarm)
					{
						nextAlarm = Time.unscaledTime + 0.11f;
						Beep.PlayLoud(((Component)this).transform.position);
					}
				}
				else if (kind == DeviceKind.Mine && Time.unscaledTime >= nextAlarm)
				{
					nextAlarm = Time.unscaledTime + 0.14f;
					Beep.Play(((Component)this).transform.position);
				}
				else if (kind == DeviceKind.Nuke && Time.unscaledTime >= voiceLocalEnd && Time.unscaledTime >= nextAlarm)
				{
					float num3 = Mathf.Clamp01((10f - num) / 10f);
					nextAlarm = Time.unscaledTime + Mathf.Lerp(1f, 0.12f, num3 * num3);
					Beep.PlayLoud(((Component)this).transform.position);
				}
			}
			else
			{
				lastBeepSecond = int.MaxValue;
			}
			lastDeployed = flag;
			lastActivated = ((kind != DeviceKind.Nuke) ? flag2 : (deviceState?.activationStarted ?? false));
		}
	}
	public sealed class SuperBlastVisual : MonoBehaviour
	{
		private float born;

		private float diameter;

		private Renderer shell;

		public static void Spawn(Vector3 position, float radius)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)obj).name = "Super Dynamite Expanded Blast";
			obj.transform.position = position;
			Object.Destroy((Object)(object)obj.GetComponent<Collider>());
			Material sharedMaterial = new Material(Shader.Find("Sprites/Default"))
			{
				color = new Color(1f, 0.38f, 0.06f, 0.19f)
			};
			obj.GetComponent<Renderer>().sharedMaterial = sharedMaterial;
			obj.AddComponent<SuperBlastVisual>().diameter = Mathf.Max(1f, radius * 2f);
			Object.Destroy((Object)(object)obj, 1.1f);
		}

		private void Awake()
		{
			born = Time.unscaledTime;
			shell = ((Component)this).GetComponent<Renderer>();
		}

		private void Update()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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)
			float num = Mathf.Clamp01((Time.unscaledTime - born) / 0.75f);
			((Component)this).transform.localScale = Vector3.one * Mathf.Lerp(0.5f, diameter, num);
			if ((Object)(object)shell != (Object)null)
			{
				Color color = shell.material.color;
				color.a = 0.19f * (1f - num);
				shell.material.color = color;
			}
		}
	}
	[HarmonyPatch(typeof(GameInfo), "Awake")]
	internal static class RegisterBoomItems
	{
		private static void Postfix()
		{
			try
			{
				Plugin.Instance?.TryRegister();
			}
			catch (Exception error)
			{
				Plugin.Instance?.ReportRegistration(error);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "get_BlockInputs")]
	internal static class BlockBoomMenuInputs
	{
		private static void Postfix(Player __instance, ref bool __result)
		{
			if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.MenuOpen && (Object)(object)__instance == (Object)(object)Player.LocalPlayer)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch]
	internal static class BlockBoomCamera
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] array = new string[3] { "MouseInput", "ControllerRotation", "ApplyAimAssist" };
			foreach (string text in array)
			{
				yield return AccessTools.Method(typeof(PlayerCamera), text, (Type[])null, (Type[])null);
			}
		}

		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Instance == (Object)null))
			{
				return !Plugin.Instance.MenuOpen;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerHolding), "PickUpInput")]
	internal static class KeepBoomEForPlacement
	{
		private static bool Prefix()
		{
			Player localPlayer = Player.LocalPlayer;
			Item item = (((Object)(object)localPlayer == (Object)null) ? null : localPlayer.Holding.HeldItem);
			if (!Plugin.IsBoom(item) || (Plugin.Kind(item) != DeviceKind.Timer && Plugin.Kind(item) != DeviceKind.Mine && Plugin.Kind(item) != DeviceKind.Nuke))
			{
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					return !Plugin.Instance.LookingAtNuke();
				}
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Explosive), "ForceExplode")]
	internal static class NukeMustBeActivated
	{
		private static bool Prefix(Explosive __instance)
		{
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.IsBoom((Item)(object)__instance) && Plugin.Kind((Item)(object)__instance) == DeviceKind.Nuke)
			{
				return Plugin.Instance.CanArmNuke(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Explosive), "ServerExplode")]
	internal static class BoomDetonation
	{
		private static bool Prefix(Explosive __instance)
		{
			if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.IsBoom((Item)(object)__instance))
			{
				return true;
			}
			if (Plugin.Kind((Item)(object)__instance) == DeviceKind.Nuke && !Plugin.Instance.CanArmNuke(__instance))
			{
				return false;
			}
			Plugin.Instance.OnDetonation(__instance);
			return true;
		}
	}
	[HarmonyPatch(typeof(Explosive), "AnimateLighterAndFuse")]
	internal static class SilentNukeFuse
	{
		private static bool Prefix(Explosive __instance)
		{
			if (Plugin.IsBoom((Item)(object)__instance))
			{
				return Plugin.Kind((Item)(object)__instance) != DeviceKind.Nuke;
			}
			return true;
		}
	}
	public sealed class BoomSlotIcon : MonoBehaviour
	{
		private InventorySlot slot;

		private Renderer preview;

		private GameObject overlay;

		private bool wasEnabled;

		private bool applied;

		public void Apply(InventorySlot target)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing