Decompiled source of Drone Mod v0.1.17

BepInEx/plugins/DroneMod/DroneMod.dll

Decompiled 2 hours 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;
using Newtonsoft.Json.Serialization;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
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 DroneMod
{
	public enum GunClass
	{
		Shotgun,
		Pistol,
		SMG,
		Rifle,
		Sniper
	}
	public static class Rules
	{
		public const int KitPrice = 10000;

		public const int FishPrice = 20000;

		public const int BossPrice = 100000;

		public const int MaxLevel = 10;

		public const float AcquisitionSeconds = 1f;

		public const float ManagementRange = 12f;

		public static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		public static bool SurfaceAllowed(float normalY)
		{
			if (Finite(normalY))
			{
				return normalY >= 0.02f;
			}
			return false;
		}

		public static bool CanRecall(bool freeSlot, bool emptyHands)
		{
			return freeSlot || emptyHands;
		}

		public static bool NeedsWeaponPurchase(int currentWeaponId, int requestedWeaponId)
		{
			return currentWeaponId != requestedWeaponId;
		}

		private static int Level(int level)
		{
			return Math.Min(10, Math.Max(0, level));
		}

		private static double Growth(double rate, int level)
		{
			return Math.Pow(1.0 + rate, Level(level));
		}

		public static float ReloadSeconds(float baseline, int upgrades)
		{
			return (float)((double)Math.Max(0.01f, baseline) / Growth(0.1, upgrades));
		}

		public static string CleanName(string value)
		{
			if (value == null)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			string text = value.Trim();
			foreach (char c in text)
			{
				if (!char.IsControl(c) && c != '<' && c != '>')
				{
					stringBuilder.Append(c);
					if (stringBuilder.Length == 32)
					{
						break;
					}
				}
			}
			return stringBuilder.ToString();
		}

		public static bool InManagementRange(float distance)
		{
			if (Finite(distance))
			{
				return distance <= 12f;
			}
			return false;
		}

		public static int DronePrice(int ownedDrones)
		{
			if (ownedDrones > 0)
			{
				return 0;
			}
			return 10000;
		}

		public static int UpgradePrice(int level)
		{
			if (level < 0 || level >= 10)
			{
				return 0;
			}
			return 1500 * (level + 1);
		}

		public static int TierPrice(int tier)
		{
			return tier switch
			{
				1 => 100000, 
				0 => 20000, 
				_ => 0, 
			};
		}

		public static int UpgradeInvestment(int level)
		{
			int num = 0;
			for (int i = 0; i < Math.Min(10, Math.Max(0, level)); i++)
			{
				num += UpgradePrice(i);
			}
			return num;
		}

		public static int TierInvestment(int tier)
		{
			if (tier > 0)
			{
				if (tier != 1)
				{
					return 120000;
				}
				return 20000;
			}
			return 0;
		}

		public static int ResaleValue(int purchasePrice, int level, int tier)
		{
			return (Math.Max(10000, purchasePrice) + UpgradeInvestment(level) + TierInvestment(tier)) / 2;
		}

		public static int ResaleValue(int level, int tier)
		{
			return ResaleValue(10000, level, tier);
		}

		public static GunClass Classify(string name)
		{
			string text = name.ToLowerInvariant();
			if (text.Contains("snip") || text.Contains("awp") || text.Contains("scout"))
			{
				return GunClass.Sniper;
			}
			if (text.Contains("shot") || text.Contains("blunder"))
			{
				return GunClass.Shotgun;
			}
			if (text.Contains("smg") || text.Contains("uzi") || text.Contains("submachine") || text.Contains("mp5") || text.Contains("p90"))
			{
				return GunClass.SMG;
			}
			if (text.Contains("pistol") || text.Contains("revol") || text.Contains("handgun") || text.Contains("glock") || text.Contains("deagle") || text.Contains("desert eagle"))
			{
				return GunClass.Pistol;
			}
			return GunClass.Rifle;
		}

		public static float Radius(GunClass gun, int level)
		{
			return (float)((double)(new float[5] { 25f, 45f, 55f, 75f, 120f })[(int)gun] * Growth(0.05, level));
		}

		public static float Reload(GunClass gun, int level)
		{
			return (float)((double)(new float[5] { 3f, 2.4f, 2.8f, 3f, 3.5f })[(int)gun] / Growth(0.1, level));
		}

		public static float Interval(GunClass gun, int level)
		{
			return (float)((double)(new float[5] { 1.1f, 0.4f, 0.16f, 0.22f, 1.6f })[(int)gun] / Growth(0.1, level));
		}

		public static int Magazine(GunClass gun)
		{
			return (new int[5] { 2, 12, 25, 20, 5 })[(int)gun];
		}

		public static int Damage(int damage, int level)
		{
			return Math.Max(1, (int)Math.Round((double)damage * Growth(0.1, level)));
		}

		public static float Accuracy(int level)
		{
			return 0.85f + (float)Math.Min(10, Math.Max(0, level)) * 0.015f;
		}

		public static float AccuracyCone(int level)
		{
			return 3f - (float)Math.Min(10, Math.Max(0, level)) * 0.27f;
		}

		public static bool Eligible(int tier, bool seagull, bool fish, bool boss, bool dead, bool held)
		{
			if (!dead && !held && (seagull || fish))
			{
				if (!boss)
				{
					if (!seagull)
					{
						return tier >= 1 && fish;
					}
					return true;
				}
				return tier >= 2;
			}
			return false;
		}

		public static float FollowDistance(float value)
		{
			return Math.Min(5f, Math.Max(1f, value));
		}

		public static bool LeashReturning(float horizontalDistance, float radius, bool currentlyReturning)
		{
			radius = FollowDistance(radius);
			if (!currentlyReturning)
			{
				return horizontalDistance > radius;
			}
			return horizontalDistance > radius * 0.5f;
		}

		public static bool NeedsFollowRecovery(bool positionsFinite, float plannedSeparation, float actualSeparation, float heightFromPlayer)
		{
			if (positionsFinite && Finite(plannedSeparation) && Finite(actualSeparation) && !(plannedSeparation > 12f) && !(actualSeparation > 12f))
			{
				return heightFromPlayer < -0.75f;
			}
			return true;
		}

		public static float ColorChannel(float value)
		{
			return Math.Min(1f, Math.Max(0f, value));
		}
	}
	[Serializable]
	public sealed class DroneData
	{
		public int serial;

		public int level;

		public int tier;

		public int ammo;

		public int shots;

		public int reloads;

		public int acquisition;

		public int activations;

		public int modeChanges;

		public int purchasePrice;

		public int followDefaultsVersion;

		public ulong owner;

		public string ownerName;

		public string customName;

		public bool deployed;

		public bool friendlyFire;

		public bool acquiring;

		public bool hasTarget;

		public int mode;

		public int followPosition = 2;

		public float followDistance = 3f;

		public Vector3 bodyColor = new Vector3(0.1f, 0.14f, 0.18f);

		public Vector3 propellerColor = new Vector3(0.85f, 0.95f, 0.05f);

		public Vector3 accentColor = new Vector3(0.05f, 0.85f, 1f);

		public bool available = true;

		public string combatStatus = "Not deployed";

		public Vector3 surfaceNormal = Vector3.up;

		public Vector3 position;

		public Vector3 aim;

		public Vector3 shotAim;

		public float yaw;

		public SavedItem weapon;

		[NonSerialized]
		public float nextShot;

		[NonSerialized]
		public bool reloading;

		[NonSerialized]
		public Creature lockedTarget;

		[NonSerialized]
		public float lockUntil;

		[NonSerialized]
		public Vector3 followVelocity;

		[NonSerialized]
		public float activationUntil;

		[NonSerialized]
		public Vector3 lastObservedFollowPosition;

		[NonSerialized]
		public float followStuckSince;

		[NonSerialized]
		public bool hasObservedFollowPosition;

		[NonSerialized]
		public bool leashReturning;

		[NonSerialized]
		public bool returningFromMode;

		public string DisplayName
		{
			get
			{
				if (!string.IsNullOrEmpty(customName))
				{
					return customName;
				}
				return "Drone #" + serial;
			}
		}

		public Quaternion BaseRotation => Quaternion.FromToRotation(Vector3.up, (((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.01f) ? surfaceNormal : Vector3.up) * Quaternion.Euler(0f, yaw, 0f);
	}
	[Serializable]
	public sealed class WorldData
	{
		public string name;

		public List<DroneData> drones = new List<DroneData>();

		public List<int> retired = new List<int>();
	}
	[Serializable]
	public sealed class SaveData
	{
		public int version = 1;

		public int nextSerial = 1;

		public List<WorldData> worlds = new List<WorldData>();
	}
	[Serializable]
	public sealed class Command
	{
		public int protocol = 4;

		public int sequence;

		public int serial;

		public int argument;

		public string action;

		public string text;

		public Vector3 position;

		public Vector3 normal;
	}
	[Serializable]
	public sealed class Snapshot
	{
		public int protocol = 4;

		public string world;

		public List<DroneData> drones = new List<DroneData>();
	}
	[Serializable]
	public sealed class Reply
	{
		public int sequence;

		public int serial;

		public string message;
	}
	[Serializable]
	public sealed class HitFeedback
	{
		public Vector3 position;

		public int damage;

		public int worth;

		public bool killed;

		public string creatureName;
	}
	[Serializable]
	public sealed class ModeSoundEvent
	{
		public int serial;

		public int mode;

		public int eventId;

		public Vector3 position;
	}
	public struct RequestMessage : IBroadcast
	{
		public string json;
	}
	public struct StateMessage : IBroadcast
	{
		public string json;
	}
	public struct ReplyMessage : IBroadcast
	{
		public string json;
	}
	public struct HitFeedbackMessage : IBroadcast
	{
		public string json;
	}
	public struct ModeSoundMessage : IBroadcast
	{
		public string json;
	}
	public sealed class Gun
	{
		public Weapon prefab;

		public string name;

		public GunClass kind;

		public int damage;

		public int price;

		public int magazine;

		public int extendedMagazine;

		public int[] ammoDamages;

		public float reload;

		public int Magazine(SavedItem state)
		{
			if (state == null || !state.ExtendedMag)
			{
				return magazine;
			}
			return extendedMagazine;
		}

		public int Damage(SavedItem state)
		{
			int num = state?.AmmoType ?? 0;
			if (ammoDamages == null || num < 0 || num >= ammoDamages.Length)
			{
				return damage;
			}
			return ammoDamages[num];
		}
	}
	public static class Kit
	{
		public const byte Id = 248;

		public const ushort Collection = 42422;

		public static Item Prefab;

		private static GameObject storage;

		public static bool Is(Item item)
		{
			if ((Object)(object)item != (Object)null && item.ID == 248)
			{
				return (Object)(object)((Component)item).GetComponent<KitVisual>() != (Object)null;
			}
			return false;
		}

		public static int Serial(Item item)
		{
			if (!Is(item))
			{
				return 0;
			}
			return Mathf.RoundToInt(item.BettingMultiplier);
		}

		public static void Register()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: 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_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Prefab != (Object)null || (Object)(object)InstanceFinder.NetworkManager == (Object)null)
			{
				return;
			}
			Dictionary<byte, Item> dictionary = (Dictionary<byte, Item>)AccessTools.Field(typeof(GameInfo), "_idToSpawnable").GetValue(null);
			if (dictionary.Count == 0)
			{
				return;
			}
			if (dictionary.ContainsKey(248))
			{
				throw new Exception("DroneMod item ID 248 is already in use; refusing to replace another item.");
			}
			Item val = (from i in dictionary.Values
				where (Object)(object)i != (Object)null && ((object)i).GetType() == typeof(Item) && (Object)(object)((Component)i).GetComponent<NetworkObject>() != (Object)null
				orderby i.ID
				select i).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("No compatible base Item prefab found for the inventory kit.");
			}
			storage = new GameObject("DroneMod prefab storage");
			storage.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)storage);
			Item val2 = Object.Instantiate<Item>(val, storage.transform);
			((Object)val2).name = "Drone Mod Kit";
			AccessTools.Field(typeof(Item), "_id").SetValue(val2, (byte)248);
			AccessTools.Field(typeof(Item), "_cost").SetValue(val2, 10000);
			AccessTools.Field(typeof(Item), "_worth").SetValue(val2, 5000);
			AccessTools.Field(typeof(Item), "_ignoredBySeagulls").SetValue(val2, true);
			AccessTools.Field(typeof(Item), "_ignoredByMoneyNPC").SetValue(val2, false);
			AccessTools.Field(typeof(Item), "_ignoredByCloseDots").SetValue(val2, false);
			AccessTools.Field(typeof(Item), "_heldPos").SetValue(val2, (object)new Vector3(0f, -0.16f, 0.5f));
			AccessTools.Field(typeof(Item), "_heldRot").SetValue(val2, (object)new Vector3(6f, 0f, 0f));
			Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true);
			for (int num = 0; num < componentsInChildren.Length; num++)
			{
				componentsInChildren[num].enabled = false;
			}
			Collider[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Collider>(true);
			foreach (Collider val3 in componentsInChildren2)
			{
				if (!val3.isTrigger)
				{
					val3.enabled = false;
				}
			}
			GameObject val4 = new GameObject("DroneModBodyCollider");
			val4.transform.SetParent(((Component)val2).transform, false);
			BoxCollider val5 = val4.AddComponent<BoxCollider>();
			val5.center = new Vector3(0f, 0.25f, 0f);
			val5.size = new Vector3(1.18f, 0.42f, 1.06f);
			AccessTools.Field(typeof(Item), "_worldColliders").SetValue(val2, new Collider[1] { (Collider)val5 });
			Collider val6 = (Collider)AccessTools.Field(typeof(Item), "_pickUpCollider").GetValue(val2);
			if ((Object)(object)val6 != (Object)null)
			{
				val6.isTrigger = true;
			}
			if (val6 is SphereCollider)
			{
				((SphereCollider)val6).radius = 0.52f;
				((SphereCollider)val6).center = new Vector3(0f, 0.28f, 0f);
			}
			else if (val6 is BoxCollider)
			{
				((BoxCollider)val6).size = new Vector3(1.18f, 0.72f, 1.06f);
				((BoxCollider)val6).center = new Vector3(0f, 0.28f, 0f);
			}
			AccessTools.Field(typeof(Item), "_outOfHandHolder").SetValue(val2, null);
			AccessTools.Field(typeof(Item), "_inHandHolder").SetValue(val2, null);
			KitVisual kitVisual = ((Component)val2).gameObject.AddComponent<KitVisual>();
			kitVisual.Build();
			AccessTools.Field(typeof(Item), "_mesh").SetValue(val2, kitVisual.InventoryMesh());
			AccessTools.Field(typeof(Item), "_inventoryMeshScale").SetValue(val2, 0.58f);
			AccessTools.Field(typeof(Item), "_inventoryMeshPos").SetValue(val2, (object)new Vector3(0f, -0.2f, 0f));
			AccessTools.Field(typeof(Item), "_inventoryMeshRot").SetValue(val2, (object)new Vector3(0f, 35f, 0f));
			AccessTools.Field(typeof(Item), "_renderers").SetValue(val2, (from r in ((Component)kitVisual).GetComponentsInChildren<Renderer>(true)
				where r.enabled
				select r).ToList());
			NetworkObject component = ((Component)val2).GetComponent<NetworkObject>();
			component.SetIsSpawnable(true);
			PrefabObjects prefabObjects = InstanceFinder.NetworkManager.GetPrefabObjects<SinglePrefabObjects>((ushort)42422, true);
			if (prefabObjects.GetObjectCount() != 0)
			{
				throw new Exception("DroneMod network prefab collection 42422 is already occupied.");
			}
			prefabObjects.AddObject(component, false, true);
			dictionary.Add(248, val2);
			((Dictionary<byte, Item>)AccessTools.Field(typeof(GameInfo), "_allItems").GetValue(null)).Add(248, val2);
			((Dictionary<string, Item>)AccessTools.Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null)).Add("dronemodkit", val2);
			Prefab = val2;
			Plugin.Log("Inventory kit registered using " + ((Object)val).name + "; dedicated network collection " + (ushort)42422 + ".");
		}
	}
	public sealed class KitVisual : MonoBehaviour
	{
		public Transform head;

		public Transform socket;

		private Transform aimPivot;

		private Item item;

		private int gunId = -1;

		private int gunStateSignature = int.MinValue;

		private int lastShot;

		private int lastReload;

		private int lastAcquisition;

		private int lastActivation = int.MinValue;

		private LineRenderer tracer;

		private LineRenderer lockLaser;

		private float tracerUntil;

		private GameObject mountedGun;

		private Vector3 displayedPosition;

		private Vector3 displayVelocity;

		private Vector3 localFpvAim;

		private Vector3 lastFollowAuthoritativePosition;

		private Quaternion displayedRotation;

		private bool displayedPositionReady;

		private bool followTargetReady;

		private float followLastMovedAt;

		private float followIdleHoverBlend;

		private int displayedMode = int.MinValue;

		private Animation mountedAnimation;

		private Transform mountedMuzzle;

		private ParticleSystem mountedFireParticle;

		private BarrelAttachment mountedBarrel;

		private AudioSequence fireSequence;

		private AudioSequence fireLastSequence;

		private AudioSequence reloadSequence;

		private AudioSequence reloadLastSequence;

		private bool hasLastFire;

		private bool hasLastReload;

		private bool proceduralReload;

		private float recoilUntil;

		private float reloadStarted;

		private float reloadUntil;

		private Vector3 mountedBasePosition;

		private Quaternion mountedBaseRotation;

		private Material bodyMaterial;

		private Material propellerMaterial;

		private Material accentMaterial;

		private static Material glow;

		private static Material lockGlow;

		private readonly List<Transform> propellers = new List<Transform>();

		private bool materialsReady;

		private AudioSource startupSource;

		private AudioSource humA;

		private AudioSource humB;

		private AudioLowPassFilter humFilterA;

		private AudioLowPassFilter humFilterB;

		private bool humRunning;

		private bool humCrossfading;

		private bool wasFlying;

		private bool pendingStartup;

		private int activeHum;

		private float humAllowedAt;

		private float humCrossfadeAt;

		private float humFadeStart;

		private float launchVisualUntil;

		public Vector3 MuzzlePosition
		{
			get
			{
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: 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_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: 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_003c: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)mountedMuzzle != (Object)null))
				{
					if (!((Object)(object)head != (Object)null))
					{
						return ((Component)this).transform.position + ((Component)this).transform.up * 1.2f;
					}
					return head.position + head.forward * 0.55f;
				}
				return mountedMuzzle.position;
			}
		}

		public int InventoryGunSignature => WeaponSignature(((Object)(object)Plugin.Instance == (Object)null) ? null : Plugin.Instance.Find(Kit.Serial(item))?.weapon);

		public void Build()
		{
			//IL_0034: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_00ec: 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_00fc: Expected O, but got Unknown
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: 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_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: 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_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)((Component)this).transform.Find("DroneModBase") != (Object)null))
			{
				Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
				bodyMaterial = new Material(val)
				{
					color = new Color(0.1f, 0.18f, 0.28f)
				};
				propellerMaterial = new Material(val)
				{
					color = new Color(0.85f, 0.95f, 0.05f)
				};
				accentMaterial = new Material(val)
				{
					color = new Color(0.05f, 0.85f, 1f)
				};
				if ((Object)(object)glow == (Object)null)
				{
					glow = new Material(Shader.Find("Sprites/Default"))
					{
						color = Color.cyan
					};
				}
				if ((Object)(object)lockGlow == (Object)null)
				{
					lockGlow = new Material(Shader.Find("Sprites/Default"))
					{
						color = Color.red
					};
				}
				Part("DroneModBase", ((Component)this).transform, (PrimitiveType)0, new Vector3(0f, 0.29f, 0f), new Vector3(0.5f, 0.16f, 0.43f), bodyMaterial);
				Part("Canopy", ((Component)this).transform, (PrimitiveType)0, new Vector3(0f, 0.38f, 0.015f), new Vector3(0.33f, 0.13f, 0.28f), bodyMaterial);
				Part("BodyBand", ((Component)this).transform, (PrimitiveType)2, new Vector3(0f, 0.27f, 0f), new Vector3(0.51f, 0.055f, 0.44f), bodyMaterial);
				Vector3 val2 = default(Vector3);
				for (int i = 0; i < 4; i++)
				{
					float num = ((i % 2 == 0) ? (-1f) : 1f);
					float num2 = ((i < 2) ? 1f : (-1f));
					((Vector3)(ref val2))..ctor(num * 0.34f, 0.29f, num2 * 0.29f);
					Vector3 pos = val2 * 0.55f + new Vector3(0f, 0.015f, 0f);
					Part("Arm", ((Component)this).transform, (PrimitiveType)3, pos, new Vector3(0.065f, 0.055f, 0.43f), bodyMaterial).localEulerAngles = new Vector3(0f, num * num2 * -49f, 0f);
					Part("Motor", ((Component)this).transform, (PrimitiveType)2, val2, new Vector3(0.085f, 0.07f, 0.085f), bodyMaterial);
					Ring("PropGuard", ((Component)this).transform, val2 + Vector3.up * 0.035f, 0.245f, 0.205f, 0.035f, bodyMaterial);
					Part("GuardBraceX", ((Component)this).transform, (PrimitiveType)3, val2 + Vector3.up * 0.035f, new Vector3(0.46f, 0.025f, 0.025f), bodyMaterial);
					Part("GuardBraceZ", ((Component)this).transform, (PrimitiveType)3, val2 + Vector3.up * 0.035f, new Vector3(0.025f, 0.025f, 0.46f), bodyMaterial);
					Transform transform = new GameObject("Propeller").transform;
					transform.SetParent(((Component)this).transform, false);
					transform.localPosition = val2 + Vector3.up * 0.075f;
					propellers.Add(transform);
					Part("BladeA", transform, (PrimitiveType)3, Vector3.zero, new Vector3(0.38f, 0.018f, 0.055f), propellerMaterial).localEulerAngles = new Vector3(0f, 12f, 0f);
					Part("BladeB", transform, (PrimitiveType)3, Vector3.zero, new Vector3(0.055f, 0.018f, 0.38f), propellerMaterial).localEulerAngles = new Vector3(0f, 12f, 0f);
				}
				float[] array = new float[3] { -0.2f, 0f, 0.2f };
				foreach (float num3 in array)
				{
					Part("StatusLight", ((Component)this).transform, (PrimitiveType)3, new Vector3(num3, 0.28f, 0.405f), new Vector3(0.11f, 0.045f, 0.025f), accentMaterial);
				}
				head = new GameObject("DroneModHead").transform;
				head.SetParent(((Component)this).transform, false);
				head.localPosition = new Vector3(0f, 0.095f, 0f);
				Part("Cradle", head, (PrimitiveType)3, Vector3.zero, new Vector3(0.24f, 0.07f, 0.2f), accentMaterial);
				aimPivot = new GameObject("DroneModGunAimPivot").transform;
				aimPivot.SetParent(head, false);
				aimPivot.localPosition = new Vector3(0f, -0.055f, 0f);
				socket = new GameObject("WeaponSocket").transform;
				socket.SetParent(aimPivot, false);
				socket.localPosition = Vector3.zero;
				Part("SocketEmpty", socket, (PrimitiveType)3, Vector3.zero, new Vector3(0.16f, 0.045f, 0.18f), bodyMaterial);
			}
		}

		public void RefreshColors(DroneData data)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00ef: 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_010c: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			EnsureInstanceMaterials();
			if (data == null)
			{
				return;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Rules.ColorChannel(data.bodyColor.x), Rules.ColorChannel(data.bodyColor.y), Rules.ColorChannel(data.bodyColor.z));
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(Rules.ColorChannel(data.propellerColor.x), Rules.ColorChannel(data.propellerColor.y), Rules.ColorChannel(data.propellerColor.z));
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(Rules.ColorChannel(data.accentColor.x), Rules.ColorChannel(data.accentColor.y), Rules.ColorChannel(data.accentColor.z));
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(val.x, val.y, val.z);
			Color val5 = default(Color);
			((Color)(ref val5))..ctor(val2.x, val2.y, val2.z);
			Color val6 = default(Color);
			((Color)(ref val6))..ctor(val3.x, val3.y, val3.z);
			SetMaterialColor(bodyMaterial, val4);
			SetMaterialColor(propellerMaterial, val5);
			SetMaterialColor(accentMaterial, val6);
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val7 in componentsInChildren)
			{
				if (!((Object)(object)val7 == (Object)null) && !((Component)val7).transform.IsChildOf(socket))
				{
					string name = ((Object)((Component)val7).gameObject).name;
					Color val8 = (name.Contains("Blade") ? val5 : ((name == "StatusLight" || name == "Cradle") ? val6 : val4));
					MaterialPropertyBlock val9 = new MaterialPropertyBlock();
					val7.GetPropertyBlock(val9);
					val9.SetColor("_BaseColor", val8);
					val9.SetColor("_Color", val8);
					val7.SetPropertyBlock(val9);
				}
			}
		}

		private static void SetMaterialColor(Material material, Color color)
		{
			//IL_000b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)material == (Object)null))
			{
				material.color = color;
				if (material.HasProperty("_BaseColor"))
				{
					material.SetColor("_BaseColor", color);
				}
				if (material.HasProperty("_Color"))
				{
					material.SetColor("_Color", color);
				}
			}
		}

		private void EnsureInstanceMaterials()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0094: 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_009e: Expected O, but got Unknown
			if (materialsReady)
			{
				return;
			}
			materialsReady = true;
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
			bodyMaterial = (((Object)(object)bodyMaterial == (Object)null) ? new Material(val) : new Material(bodyMaterial));
			propellerMaterial = (((Object)(object)propellerMaterial == (Object)null) ? new Material(val) : new Material(propellerMaterial));
			accentMaterial = (((Object)(object)accentMaterial == (Object)null) ? new Material(val) : new Material(accentMaterial));
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (!((Component)val2).transform.IsChildOf(socket))
				{
					string name = ((Object)((Component)val2).gameObject).name;
					val2.sharedMaterial = (name.Contains("Blade") ? propellerMaterial : ((name == "StatusLight" || name == "Cradle") ? accentMaterial : bodyMaterial));
				}
			}
		}

		private static Transform Part(string name, Transform parent, PrimitiveType primitive, Vector3 pos, Vector3 scale, Material material)
		{
			//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)
			GameObject obj = GameObject.CreatePrimitive(primitive);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = pos;
			obj.transform.localScale = scale;
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			obj.GetComponent<Renderer>().sharedMaterial = material;
			return obj.transform;
		}

		private static Transform Ring(string name, Transform parent, Vector3 pos, float outerRadius, float innerRadius, float height, Material material)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[116];
			int[] array2 = new int[672];
			for (int i = 0; i <= 28; i++)
			{
				float num = (float)i * (float)Math.PI * 2f / 28f;
				float num2 = Mathf.Cos(num);
				float num3 = Mathf.Sin(num);
				int num4 = i * 4;
				array[num4] = new Vector3(num2 * outerRadius, (0f - height) * 0.5f, num3 * outerRadius);
				array[num4 + 1] = new Vector3(num2 * outerRadius, height * 0.5f, num3 * outerRadius);
				array[num4 + 2] = new Vector3(num2 * innerRadius, height * 0.5f, num3 * innerRadius);
				array[num4 + 3] = new Vector3(num2 * innerRadius, (0f - height) * 0.5f, num3 * innerRadius);
			}
			int num5 = 0;
			for (int j = 0; j < 28; j++)
			{
				int num6 = j * 4;
				int num7 = (j + 1) * 4;
				int[] array3 = new int[24]
				{
					num6,
					num6 + 1,
					num7 + 1,
					num6,
					num7 + 1,
					num7,
					num6 + 1,
					num6 + 2,
					num7 + 2,
					num6 + 1,
					num7 + 2,
					num7 + 1,
					num6 + 2,
					num6 + 3,
					num7 + 3,
					num6 + 2,
					num7 + 3,
					num7 + 2,
					num6 + 3,
					num6,
					num7,
					num6 + 3,
					num7,
					num7 + 3
				};
				for (int k = 0; k < array3.Length; k++)
				{
					array2[num5++] = array3[k];
				}
			}
			Mesh val = new Mesh
			{
				name = name + " Mesh",
				vertices = array,
				triangles = array2
			};
			val.RecalculateNormals();
			val.RecalculateBounds();
			GameObject val2 = new GameObject(name);
			val2.transform.SetParent(parent, false);
			val2.transform.localPosition = pos;
			val2.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = material;
			return val2.transform;
		}

		private static string RelativePath(Transform root, Transform child)
		{
			if ((Object)(object)root == (Object)null || (Object)(object)child == (Object)null)
			{
				return null;
			}
			if ((Object)(object)root == (Object)(object)child)
			{
				return "";
			}
			List<string> list = new List<string>();
			Transform val = child;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			if ((Object)(object)val != (Object)(object)root)
			{
				return null;
			}
			list.Reverse();
			return string.Join("/", list.ToArray());
		}

		private static Transform CloneTransform(Transform sourceRoot, Transform cloneRoot, Transform source)
		{
			string text = RelativePath(sourceRoot, source);
			if (text != null)
			{
				if (text.Length != 0)
				{
					return cloneRoot.Find(text);
				}
				return cloneRoot;
			}
			return null;
		}

		private static T Private<T>(object target, string name) where T : class
		{
			FieldInfo fieldInfo = ((target == null) ? null : AccessTools.Field(target.GetType(), name));
			if (!(fieldInfo == null))
			{
				return fieldInfo.GetValue(target) as T;
			}
			return null;
		}

		private static void ActivatePath(Transform child, Transform root)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(true);
				if (!((Object)(object)val == (Object)(object)root))
				{
					val = val.parent;
					continue;
				}
				break;
			}
		}

		private static bool IsWeaponRenderer(Renderer renderer)
		{
			if (!(renderer is MeshRenderer))
			{
				return renderer is SkinnedMeshRenderer;
			}
			return true;
		}

		private static void EnableVisuals(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			ActivatePath(root, root);
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (IsWeaponRenderer(val))
				{
					ActivatePath(((Component)val).transform, root);
					val.enabled = true;
					val.forceRenderingOff = false;
					val.lightmapIndex = -1;
					val.realtimeLightmapIndex = -1;
				}
			}
		}

		private void ToggleCopies<T>(Transform sourceRoot, Transform cloneRoot, List<T> choices, int selected) where T : Component
		{
			if (choices == null)
			{
				return;
			}
			for (int i = 0; i < choices.Count; i++)
			{
				Transform val = CloneTransform(sourceRoot, cloneRoot, ((Object)(object)choices[i] == (Object)null) ? null : ((Component)choices[i]).transform);
				if (!((Object)(object)val == (Object)null))
				{
					((Component)val).gameObject.SetActive(i == selected);
					if (i == selected)
					{
						ActivatePath(val, cloneRoot);
						EnableVisuals(val);
					}
				}
			}
		}

		private void BuildMountedGun(Gun gun, SavedItem state)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0910: Unknown result type (might be due to invalid IL or missing references)
			//IL_0915: Unknown result type (might be due to invalid IL or missing references)
			//IL_0926: Unknown result type (might be due to invalid IL or missing references)
			//IL_092b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_080b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0817: Unknown result type (might be due to invalid IL or missing references)
			//IL_083e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0845: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_0897: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fa: Unknown result type (might be due to invalid IL or missing references)
			Transform val = socket.Find("MountedGun");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			mountedGun = null;
			mountedAnimation = null;
			mountedMuzzle = null;
			mountedFireParticle = null;
			mountedBarrel = null;
			fireSequence = (fireLastSequence = (reloadSequence = (reloadLastSequence = null)));
			hasLastFire = (hasLastReload = false);
			if (gun == null || (Object)(object)gun.prefab == (Object)null)
			{
				return;
			}
			mountedGun = new GameObject("MountedGun");
			mountedGun.transform.SetParent(socket, false);
			bool activeSelf = ((Component)socket).gameObject.activeSelf;
			((Component)socket).gameObject.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(((Component)gun.prefab).gameObject, mountedGun.transform, false);
			((Object)val2).name = "WeaponRig";
			Weapon component = val2.GetComponent<Weapon>();
			if ((Object)(object)component != (Object)null && state != null)
			{
				try
				{
					((Item)component).LoadFromSave(state);
				}
				catch (Exception ex)
				{
					Plugin.Log("Native visual configuration fallback for " + gun.name + ": " + ex.Message);
				}
			}
			MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			Rigidbody[] componentsInChildren3 = val2.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			((Component)socket).gameObject.SetActive(activeSelf);
			val2.SetActive(true);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.Euler(((Item)gun.prefab).InventoryMeshRot);
			val2.transform.localScale = Vector3.one;
			Transform transform = ((Component)gun.prefab).transform;
			Attachments attachments = gun.prefab.Attachments;
			GameObject val3 = Private<GameObject>(gun.prefab, "_outOfHandHolder");
			GameObject val4 = Private<GameObject>(gun.prefab, "_inHandHolder");
			Transform val5 = CloneTransform(transform, val2.transform, ((Object)(object)val3 == (Object)null) ? null : val3.transform);
			Transform val6 = CloneTransform(transform, val2.transform, ((Object)(object)val4 == (Object)null) ? null : val4.transform);
			Transform val7 = (((Object)(object)val5 != (Object)null && ((Component)val5).GetComponentsInChildren<Renderer>(true).Any(IsWeaponRenderer)) ? val5 : (((Object)(object)val6 != (Object)null) ? val6 : val5));
			if ((Object)(object)val5 != (Object)null)
			{
				((Component)val5).gameObject.SetActive((Object)(object)val7 == (Object)(object)val5);
			}
			if ((Object)(object)val6 != (Object)null)
			{
				((Component)val6).gameObject.SetActive((Object)(object)val7 == (Object)(object)val6);
			}
			if ((Object)(object)val7 != (Object)null)
			{
				ActivatePath(val7, val2.transform);
				EnableVisuals(val7);
			}
			List<Renderer> list = Private<List<Renderer>>(gun.prefab, "_renderers");
			if (list != null)
			{
				foreach (Renderer item in list)
				{
					Transform val8 = CloneTransform(transform, val2.transform, ((Object)(object)item == (Object)null) ? null : ((Component)item).transform);
					if (!((Object)(object)val8 == (Object)null) && (!((Object)(object)val7 != (Object)null) || val8.IsChildOf(val7) || !((Object)(object)val8 != (Object)(object)val7)))
					{
						ActivatePath(val8, val2.transform);
						Renderer component2 = ((Component)val8).GetComponent<Renderer>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.enabled = true;
							component2.forceRenderingOff = false;
							component2.lightmapIndex = -1;
							component2.realtimeLightmapIndex = -1;
						}
					}
				}
			}
			List<Sight> list2 = Private<List<Sight>>(attachments, "_sights");
			List<BarrelAttachment> list3 = Private<List<BarrelAttachment>>(attachments, "_barrelAttachments");
			int selected = Mathf.Clamp((int)(state?.Sight ?? 0), 0, (list2 != null) ? (list2.Count - 1) : 0);
			int num = Mathf.Clamp((int)(state?.BarrelAttachment ?? 0), 0, (list3 != null) ? (list3.Count - 1) : 0);
			ToggleCopies<Sight>(transform, val2.transform, list2, selected);
			ToggleCopies<BarrelAttachment>(transform, val2.transform, list3, num);
			LaserSight val9 = Private<LaserSight>(attachments, "_laserSight");
			Transform val10 = CloneTransform(transform, val2.transform, ((Object)(object)val9 == (Object)null) ? null : ((Component)val9).transform);
			if ((Object)(object)val10 != (Object)null)
			{
				((Component)val10).gameObject.SetActive(state?.LaserSight ?? false);
				if (state != null && state.LaserSight)
				{
					ActivatePath(val10, val2.transform);
					EnableVisuals(val10);
				}
			}
			if (list3 != null && list3.Count > 0)
			{
				mountedBarrel = list3[num];
				mountedMuzzle = CloneTransform(transform, val2.transform, mountedBarrel.FirePoint);
				Transform val11 = CloneTransform(transform, val2.transform, ((Object)(object)mountedBarrel.FireParticle == (Object)null) ? null : ((Component)mountedBarrel.FireParticle).transform);
				if ((Object)(object)val11 != (Object)null)
				{
					mountedFireParticle = ((Component)val11).GetComponent<ParticleSystem>();
				}
			}
			Renderer[] componentsInChildren4;
			if (!val2.GetComponentsInChildren<Renderer>(false).Any(IsWeaponRenderer))
			{
				componentsInChildren4 = val2.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val12 in componentsInChildren4)
				{
					if (IsWeaponRenderer(val12))
					{
						ActivatePath(((Component)val12).transform, val2.transform);
						val12.enabled = true;
						val12.forceRenderingOff = false;
						val12.lightmapIndex = -1;
						val12.realtimeLightmapIndex = -1;
					}
				}
			}
			if (state != null && (Object)(object)((Item)gun.prefab).SkinPreset != (Object)null && ((Item)gun.prefab).SkinPreset.Skins.Count > 0)
			{
				int index = Mathf.Clamp((int)state.SkinIndex, 0, ((Item)gun.prefab).SkinPreset.Skins.Count - 1);
				componentsInChildren4 = val2.GetComponentsInChildren<Renderer>(false);
				foreach (Renderer val13 in componentsInChildren4)
				{
					if (IsWeaponRenderer(val13))
					{
						ShaderManager.ApplyItemSkin(((Item)gun.prefab).SkinPreset.Skins[index], val13, false);
					}
				}
			}
			mountedAnimation = val2.GetComponentInChildren<Animation>(true);
			fireSequence = Private<AudioSequence>(gun.prefab, "_fireAudioSeq");
			fireLastSequence = Private<AudioSequence>(gun.prefab, "_fireLastAudioSeq");
			reloadSequence = Private<AudioSequence>(gun.prefab, "_reloadAudioSeq");
			reloadLastSequence = Private<AudioSequence>(gun.prefab, "_reloadLastAudioSeq");
			hasLastFire = (bool)AccessTools.Field(typeof(Weapon), "_hasLastFireAnim").GetValue(gun.prefab);
			hasLastReload = (bool)AccessTools.Field(typeof(Weapon), "_hasLastReloadAnim").GetValue(gun.prefab);
			Renderer[] array = val2.GetComponentsInChildren<Renderer>(false).Where(IsWeaponRenderer).ToArray();
			Bounds val14 = default(Bounds);
			bool flag = false;
			componentsInChildren4 = array;
			foreach (Renderer val15 in componentsInChildren4)
			{
				if (!flag)
				{
					val14 = val15.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val14)).Encapsulate(val15.bounds);
				}
			}
			if (flag)
			{
				float num2 = 1.35f / Mathf.Max(0.001f, Mathf.Max(((Bounds)(ref val14)).size.x, Mathf.Max(((Bounds)(ref val14)).size.y, ((Bounds)(ref val14)).size.z)));
				mountedGun.transform.localScale = Vector3.one * num2;
				Renderer[] array2 = val2.GetComponentsInChildren<Renderer>(false).Where(IsWeaponRenderer).ToArray();
				flag = false;
				componentsInChildren4 = array2;
				foreach (Renderer val16 in componentsInChildren4)
				{
					if (!flag)
					{
						val14 = val16.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val14)).Encapsulate(val16.bounds);
					}
				}
				if (flag)
				{
					Vector3 val17 = socket.InverseTransformPoint(((Bounds)(ref val14)).center);
					mountedGun.transform.localPosition = new Vector3(0f - val17.x, -0.12f - val17.y, 0f - val17.z);
				}
			}
			mountedBasePosition = mountedGun.transform.localPosition;
			mountedBaseRotation = mountedGun.transform.localRotation;
			int num3 = val2.GetComponentsInChildren<Renderer>(false).Count(IsWeaponRenderer);
			Plugin.Log("Mounted visual " + gun.name + ": skin=" + (int)(state?.SkinIndex ?? 0) + ", sight=" + (int)(state?.Sight ?? 0) + ", barrel=" + (int)(state?.BarrelAttachment ?? 0) + ", active renderers=" + num3 + ", holder=" + (((Object)(object)val7 == (Object)null) ? "fallback" : ((Object)val7).name) + ".");
		}

		private static void SetLayerRecursively(GameObject root, int layer)
		{
			Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.layer = layer;
			}
		}

		public GameObject CreateInventoryGunPreview(Transform parent)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mountedGun == (Object)null || (Object)(object)parent == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(mountedGun, parent, false);
			((Object)val).name = "DroneModInventoryGunPreview";
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			val.transform.localPosition = new Vector3(0f, 0.02f, 0f);
			val.transform.localRotation = Quaternion.Euler(-8f, 20f, 0f);
			val.transform.localScale = mountedGun.transform.localScale * 0.82f;
			SetLayerRecursively(val, ((Component)parent).gameObject.layer);
			val.SetActive(true);
			Renderer[] componentsInChildren3 = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren3)
			{
				if (IsWeaponRenderer(val2))
				{
					ActivatePath(((Component)val2).transform, val.transform);
					val2.enabled = true;
					val2.lightmapIndex = -1;
					val2.realtimeLightmapIndex = -1;
				}
			}
			return val;
		}

		private static int WeaponSignature(SavedItem state)
		{
			if (state == null || !state.Exists)
			{
				return -1;
			}
			return ((((((17 * 31 + state.ItemID) * 31 + state.SkinIndex) * 31 + state.Sight) * 31 + state.BarrelAttachment) * 31 + state.AmmoType) * 31 + (state.ExtendedMag ? 1 : 0)) * 31 + (state.LaserSight ? 1 : 0);
		}

		private void PlayAnimation(string name, float duration = 0f)
		{
			if (!((Object)(object)mountedAnimation == (Object)null) && !((TrackedReference)(object)mountedAnimation[name] == (TrackedReference)null))
			{
				AnimationState val = mountedAnimation[name];
				val.speed = ((duration > 0f) ? (val.clip.length / Mathf.Max(0.05f, duration)) : 1f);
				mountedAnimation.Stop();
				mountedAnimation.Play(name);
			}
		}

		private void PlaySequence(AudioSequence sequence, float speed = 1f)
		{
			if (sequence != null && sequence.Steps != null && sequence.Steps.Length != 0)
			{
				((MonoBehaviour)this).StartCoroutine(PlaySequenceRoutine(sequence, Mathf.Max(0.05f, speed)));
			}
		}

		private IEnumerator PlaySequenceRoutine(AudioSequence sequence, float speed)
		{
			AudioSequenceStep[] steps = sequence.Steps;
			foreach (AudioSequenceStep step in steps)
			{
				if (step != null)
				{
					if (step.Timer > 0f)
					{
						yield return (object)new WaitForSeconds(step.Timer / speed);
					}
					AudioClip randomClip = step.GetRandomClip();
					if ((Object)(object)randomClip != (Object)null)
					{
						AudioSource.PlayClipAtPoint(randomClip, MuzzlePosition, sequence.Volume * step.Volume);
					}
				}
			}
		}

		private void PlayFire(DroneData data)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			recoilUntil = Time.time + 0.12f;
			string name = ((data.ammo == 0 && hasLastFire) ? "FireLast" : "Fire");
			PlayAnimation(name);
			if ((Object)(object)mountedFireParticle != (Object)null)
			{
				mountedFireParticle.Play();
			}
			if ((Object)(object)mountedBarrel != (Object)null && !string.IsNullOrEmpty(mountedBarrel.GetFireSound()))
			{
				AudioManager.PlayRandomClipAt(mountedBarrel.GetFireSound(), 1, Mathf.Max(1, mountedBarrel.FireSoundCount), MuzzlePosition, false, (AudioDistance)(mountedBarrel.UseMediumSoundDistance ? 2 : 3), mountedBarrel.FireSoundVolume, 0.1f);
			}
			PlaySequence((data.ammo == 0 && fireLastSequence != null) ? fireLastSequence : fireSequence);
		}

		private void PlayReload(DroneData data, Gun gun)
		{
			float num = Rules.ReloadSeconds(gun.reload, data.level);
			reloadStarted = Time.time;
			reloadUntil = Time.time + num;
			string text = ((data.ammo == 0 && hasLastReload) ? "ReloadLast" : "Reload");
			proceduralReload = (Object)(object)mountedAnimation == (Object)null || (TrackedReference)(object)mountedAnimation[text] == (TrackedReference)null;
			PlayAnimation(text, num);
			PlaySequence((data.ammo == 0 && reloadLastSequence != null) ? reloadLastSequence : reloadSequence, gun.reload / Mathf.Max(0.05f, num));
		}

		public Mesh InventoryMesh()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			//IL_005f: Expected O, but got Unknown
			MeshFilter[] source = (from f in ((Component)this).GetComponentsInChildren<MeshFilter>(true)
				where ((Component)f).GetComponent<Renderer>().enabled
				select f).ToArray();
			Mesh val = new Mesh
			{
				name = "DroneMod inventory mesh"
			};
			val.CombineMeshes(source.Select(delegate(MeshFilter f)
			{
				//IL_0002: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: 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)
				CombineInstance result = default(CombineInstance);
				((CombineInstance)(ref result)).mesh = f.sharedMesh;
				((CombineInstance)(ref result)).transform = ((Component)this).transform.worldToLocalMatrix * ((Component)f).transform.localToWorldMatrix;
				return result;
			}).ToArray());
			return val;
		}

		private void Awake()
		{
			item = ((Component)this).GetComponent<Item>();
			head = ((Component)this).transform.Find("DroneModHead");
			if ((Object)(object)head != (Object)null)
			{
				aimPivot = head.Find("DroneModGunAimPivot");
				socket = (((Object)(object)aimPivot == (Object)null) ? head.Find("WeaponSocket") : aimPivot.Find("WeaponSocket"));
			}
			propellers.Clear();
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "Propeller")
				{
					propellers.Add(val);
				}
			}
			SetupDroneAudio();
		}

		private AudioSource NewDroneSource(string sourceName)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(sourceName);
			val.transform.SetParent(((Component)this).transform, false);
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.loop = false;
			obj.spatialBlend = 1f;
			obj.rolloffMode = (AudioRolloffMode)0;
			obj.minDistance = 1.5f;
			obj.maxDistance = 18f;
			obj.dopplerLevel = 0.15f;
			return obj;
		}

		private void SetupDroneAudio()
		{
			if (!((Object)(object)startupSource != (Object)null))
			{
				startupSource = NewDroneSource("Drone startup audio");
				humA = NewDroneSource("Drone hum A");
				humB = NewDroneSource("Drone hum B");
				humFilterA = ((Component)humA).gameObject.AddComponent<AudioLowPassFilter>();
				humFilterB = ((Component)humB).gameObject.AddComponent<AudioLowPassFilter>();
				AudioLowPassFilter obj = humFilterA;
				bool enabled = (((Behaviour)humFilterB).enabled = false);
				((Behaviour)obj).enabled = enabled;
			}
		}

		private void StartHum(float volume)
		{
			AudioClip hum = DroneSounds.Hum;
			if (!((Object)(object)hum == (Object)null) && !humRunning)
			{
				activeHum = 0;
				humA.clip = hum;
				humB.clip = hum;
				humA.volume = 0f;
				humB.volume = 0f;
				humA.Play();
				humRunning = true;
				humCrossfading = false;
				humFadeStart = Time.time;
				humCrossfadeAt = Time.time + Mathf.Max(0.3f, hum.length - 0.25f);
			}
		}

		private void UpdateDroneAudio(DroneData data, bool flying)
		{
			SetupDroneAudio();
			bool flag = (Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.IsFpvDrone(data.serial);
			float num = (flag ? 0.024f : 0.08f);
			float num2 = (flag ? 1150f : 5000f);
			AudioLowPassFilter obj = humFilterA;
			bool enabled = (((Behaviour)humFilterB).enabled = flag);
			((Behaviour)obj).enabled = enabled;
			AudioLowPassFilter obj2 = humFilterA;
			float cutoffFrequency = (humFilterB.cutoffFrequency = num2);
			obj2.cutoffFrequency = cutoffFrequency;
			if (lastActivation == int.MinValue)
			{
				lastActivation = data.activations;
			}
			else if (data.activations != lastActivation)
			{
				lastActivation = data.activations;
				launchVisualUntil = Time.time + 0.75f;
				pendingStartup = flying;
				humA.Stop();
				humB.Stop();
				humRunning = false;
			}
			if (pendingStartup && flying && (Object)(object)DroneSounds.Startup != (Object)null)
			{
				pendingStartup = false;
				startupSource.clip = DroneSounds.Startup;
				startupSource.volume = 0.21f;
				startupSource.Play();
				humAllowedAt = Time.time + Mathf.Max(0.1f, DroneSounds.Startup.length - 0.22f);
			}
			if (flying && !wasFlying && humAllowedAt <= 0f)
			{
				humAllowedAt = Time.time;
			}
			wasFlying = flying;
			if (!flying)
			{
				humA.volume = Mathf.MoveTowards(humA.volume, 0f, Time.deltaTime * 0.65f);
				humB.volume = Mathf.MoveTowards(humB.volume, 0f, Time.deltaTime * 0.65f);
				if (humA.volume <= 0.001f && humB.volume <= 0.001f)
				{
					humA.Stop();
					humB.Stop();
					humRunning = false;
				}
				return;
			}
			if (!humRunning && Time.time >= humAllowedAt)
			{
				StartHum(num);
			}
			if (!humRunning)
			{
				return;
			}
			AudioSource val = ((activeHum == 0) ? humA : humB);
			AudioSource val2 = ((activeHum == 0) ? humB : humA);
			if (!humCrossfading && Time.time >= humCrossfadeAt)
			{
				val2.time = 0f;
				val2.volume = 0f;
				val2.Play();
				humFadeStart = Time.time;
				humCrossfading = true;
			}
			if (humCrossfading)
			{
				float num4 = Mathf.Clamp01((Time.time - humFadeStart) / 0.25f);
				val.volume = num * (1f - num4);
				val2.volume = num * num4;
				if (num4 >= 1f)
				{
					val.Stop();
					activeHum = 1 - activeHum;
					humCrossfading = false;
					humCrossfadeAt = humFadeStart + Mathf.Max(0.3f, DroneSounds.Hum.length - 0.25f);
				}
			}
			else
			{
				val.volume = Mathf.MoveTowards(val.volume, num, Time.deltaTime * 0.6f);
			}
		}

		private void AimMountedWeapon(Vector3 direction, float yawDegreesPerSecond, float aimDegreesPerSecond)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0119: 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_011b: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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 references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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)
			if (((Vector3)(ref direction)).sqrMagnitude < 0.0001f || (Object)(object)head == (Object)null || (Object)(object)aimPivot == (Object)null)
			{
				return;
			}
			((Vector3)(ref direction)).Normalize();
			Vector3 up = ((Component)this).transform.up;
			Vector3 val = Vector3.ProjectOnPlane(direction, up);
			if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				((Vector3)(ref val)).Normalize();
				Vector3 val2 = Vector3.ProjectOnPlane(((Component)this).transform.forward, up);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (((Vector3)(ref normalized)).sqrMagnitude < 0.0001f)
				{
					val2 = Vector3.ProjectOnPlane(Vector3.forward, up);
					normalized = ((Vector3)(ref val2)).normalized;
				}
				float num = Vector3.SignedAngle(normalized, val, up);
				Quaternion val3 = Quaternion.Euler(0f, num, 0f);
				head.localRotation = ((yawDegreesPerSecond <= 0f) ? val3 : Quaternion.RotateTowards(head.localRotation, val3, yawDegreesPerSecond * Time.deltaTime));
			}
			Quaternion val5;
			if ((Object)(object)mountedMuzzle != (Object)null)
			{
				Quaternion val4 = Quaternion.Inverse(aimPivot.rotation) * mountedMuzzle.rotation;
				val5 = Quaternion.LookRotation(direction, -up) * Quaternion.Inverse(val4);
			}
			else
			{
				val5 = Quaternion.LookRotation(direction, -up);
			}
			aimPivot.rotation = ((aimDegreesPerSecond <= 0f) ? val5 : Quaternion.RotateTowards(aimPivot.rotation, val5, aimDegreesPerSecond * Time.deltaTime));
		}

		private void LateUpdate()
		{
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: 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_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: 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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0813: Unknown result type (might be due to invalid IL or missing references)
			//IL_0829: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_0709: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0710: Unknown result type (might be due to invalid IL or missing references)
			//IL_0715: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_071e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0745: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_074c: Unknown result type (might be due to invalid IL or missing references)
			//IL_074e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0753: Unknown result type (might be due to invalid IL or missing references)
			//IL_0755: Unknown result type (might be due to invalid IL or missing references)
			//IL_0757: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_075e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0762: Unknown result type (might be due to invalid IL or missing references)
			//IL_0767: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_0777: Unknown result type (might be due to invalid IL or missing references)
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_077f: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0733: Unknown result type (might be due to invalid IL or missing references)
			//IL_0735: Unknown result type (might be due to invalid IL or missing references)
			//IL_073a: Unknown result type (might be due to invalid IL or missing references)
			//IL_073e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0743: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: 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_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: 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_086c: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a08: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1a: Unknown result type (might be due to invalid IL or missing references)
			//IL_099d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a4: Expected O, but got Unknown
			//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_08fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0901: Unknown result type (might be due to invalid IL or missing references)
			//IL_0905: Unknown result type (might be due to invalid IL or missing references)
			//IL_090a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0918: Unknown result type (might be due to invalid IL or missing references)
			//IL_091d: Unknown result type (might be due to invalid IL or missing references)
			//IL_094c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0951: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0acd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad4: Expected O, but got Unknown
			//IL_0b80: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null || (Object)(object)Plugin.Instance == (Object)null || (Object)(object)head == (Object)null)
			{
				return;
			}
			DroneData droneData = Plugin.Instance.Find(Kit.Serial(item));
			if (droneData == null)
			{
				return;
			}
			bool flag = droneData.deployed && (Object)(object)item.SyncedHolder == (Object)null;
			RefreshColors(droneData);
			if (flag)
			{
				foreach (Transform propeller in propellers)
				{
					if ((Object)(object)propeller != (Object)null)
					{
						propeller.Rotate(0f, 1080f * Time.deltaTime, 0f, (Space)1);
					}
				}
			}
			UpdateDroneAudio(droneData, flag);
			if (AccessTools.Field(typeof(Item), "_worldColliders").GetValue(item) is Collider[] array)
			{
				Collider[] array2 = array;
				foreach (Collider val in array2)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.enabled = !droneData.deployed;
					}
				}
			}
			Vector3 val2;
			if (droneData.deployed && (Object)(object)item.SyncedHolder == (Object)null)
			{
				item.ReconcileLocalHolderWithSyncedHolder();
				item.RigidbodySync.SetKinematic(true);
				if ((Object)(object)item.Rig != (Object)null)
				{
					item.Rig.detectCollisions = false;
				}
				Vector3 position = droneData.position;
				Quaternion rotation = droneData.BaseRotation;
				Vector3 aimDirection = Vector3.zero;
				bool flag2 = droneData.mode == 2 && Plugin.Instance.TryGetLocalFpvPose(droneData.serial, out position, out rotation, out aimDirection);
				localFpvAim = (flag2 ? aimDirection : Vector3.zero);
				float num = Mathf.Sin(Time.unscaledTime * 1.8f + (float)droneData.serial * 0.71f) * 0.1f;
				if (droneData.mode == 0)
				{
					if (!followTargetReady)
					{
						lastFollowAuthoritativePosition = droneData.position;
						followLastMovedAt = Time.unscaledTime;
						followTargetReady = true;
					}
					else
					{
						val2 = droneData.position - lastFollowAuthoritativePosition;
						if (((Vector3)(ref val2)).sqrMagnitude > 0.0004f)
						{
							lastFollowAuthoritativePosition = droneData.position;
							followLastMovedAt = Time.unscaledTime;
						}
					}
					bool flag3 = Time.unscaledTime - followLastMovedAt > 0.4f;
					followIdleHoverBlend = Mathf.MoveTowards(followIdleHoverBlend, flag3 ? 1f : 0f, Time.unscaledDeltaTime * 2.5f);
					position += droneData.BaseRotation * Vector3.up * (num * followIdleHoverBlend);
				}
				else
				{
					followTargetReady = false;
					followIdleHoverBlend = Mathf.MoveTowards(followIdleHoverBlend, 0f, Time.unscaledDeltaTime * 4f);
					if (droneData.mode == 1)
					{
						position += droneData.BaseRotation * Vector3.up * num;
					}
				}
				if (displayedPositionReady)
				{
					val2 = displayedPosition - position;
					if (!(((Vector3)(ref val2)).sqrMagnitude > 225f))
					{
						displayedPosition = Vector3.SmoothDamp(displayedPosition, position, ref displayVelocity, (droneData.mode == 2) ? 0.07f : ((droneData.mode == 0) ? 0.14f : 0.24f), 35f, Time.unscaledDeltaTime);
						float num2 = 1f - Mathf.Exp((0f - ((droneData.mode == 2) ? 12f : 8f)) * Time.unscaledDeltaTime);
						displayedRotation = Quaternion.Slerp(displayedRotation, rotation, num2);
						goto IL_0401;
					}
				}
				displayedPosition = position;
				displayVelocity = Vector3.zero;
				displayedRotation = rotation;
				displayedPositionReady = true;
				goto IL_0401;
			}
			displayedPositionReady = false;
			displayVelocity = Vector3.zero;
			displayedRotation = Quaternion.identity;
			displayedMode = int.MinValue;
			localFpvAim = Vector3.zero;
			followTargetReady = false;
			followIdleHoverBlend = 0f;
			if ((Object)(object)item.Rig != (Object)null)
			{
				item.Rig.detectCollisions = true;
			}
			head.localRotation = Quaternion.identity;
			if ((Object)(object)aimPivot != (Object)null)
			{
				aimPivot.localRotation = Quaternion.identity;
			}
			goto IL_0536;
			IL_0401:
			displayedMode = droneData.mode;
			((Component)this).transform.SetPositionAndRotation(displayedPosition, displayedRotation);
			if (Time.time < launchVisualUntil)
			{
				float num3 = Mathf.Clamp01((launchVisualUntil - Time.time) / 0.75f);
				float num4 = num3 * num3 * (3f - 2f * num3);
				((Component)this).transform.rotation = Quaternion.Slerp(droneData.BaseRotation, droneData.BaseRotation * Quaternion.Euler(52f, 14f, -30f), num4);
			}
			goto IL_0536;
			IL_0536:
			int wanted = ((droneData.weapon != null && droneData.weapon.Exists) ? droneData.weapon.ItemID : (-1));
			int num5 = WeaponSignature(droneData.weapon);
			if (wanted != gunId || num5 != gunStateSignature)
			{
				gunId = wanted;
				gunStateSignature = num5;
				Transform val3 = socket.Find("SocketEmpty");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(wanted < 0);
				}
				Gun gun = Plugin.Instance.Guns.FirstOrDefault((Gun g) => ((Item)g.prefab).ID == wanted);
				BuildMountedGun(gun, droneData.weapon);
				lastShot = droneData.shots;
				lastReload = droneData.reloads;
				lastAcquisition = droneData.acquisition;
			}
			if (droneData.deployed && (Object)(object)item.SyncedHolder == (Object)null && droneData.hasTarget && (Object)(object)mountedGun != (Object)null)
			{
				Vector3 direction = ((((Vector3)(ref localFpvAim)).sqrMagnitude > 0.5f) ? localFpvAim : (droneData.aim - MuzzlePosition));
				if (((Vector3)(ref direction)).sqrMagnitude > 0.01f)
				{
					AimMountedWeapon(direction, 0f, 0f);
				}
			}
			else if (droneData.deployed && (Object)(object)item.SyncedHolder == (Object)null && (Object)(object)mountedGun != (Object)null)
			{
				float num6 = Mathf.Repeat(Time.time * 12f + (float)droneData.serial * 47f, 360f);
				Vector3 up = ((Component)this).transform.up;
				val2 = Vector3.ProjectOnPlane(((Component)this).transform.forward, up);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (((Vector3)(ref normalized)).sqrMagnitude < 0.01f)
				{
					val2 = Vector3.ProjectOnPlane(Vector3.forward, up);
					normalized = ((Vector3)(ref val2)).normalized;
				}
				Vector3 val4 = Quaternion.AngleAxis(num6, up) * normalized;
				val2 = Vector3.Cross(up, val4);
				Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
				Vector3 direction2 = Quaternion.AngleAxis(-30f, normalized2) * val4;
				AimMountedWeapon(direction2, 20f, 45f);
			}
			else
			{
				head.localRotation = Quaternion.RotateTowards(head.localRotation, Quaternion.identity, 90f * Time.deltaTime);
				if ((Object)(object)aimPivot != (Object)null)
				{
					aimPivot.localRotation = Quaternion.RotateTowards(aimPivot.localRotation, Quaternion.identity, 90f * Time.deltaTime);
				}
			}
			if ((Object)(object)mountedGun != (Object)null)
			{
				mountedGun.transform.localPosition = mountedBasePosition;
				mountedGun.transform.localRotation = mountedBaseRotation;
				if (proceduralReload && Time.time < reloadUntil)
				{
					float num7 = Mathf.InverseLerp(reloadStarted, reloadUntil, Time.time);
					mountedGun.transform.localRotation = mountedBaseRotation * Quaternion.Euler(Mathf.Sin(num7 * (float)Math.PI) * 32f, 0f, Mathf.Sin(num7 * (float)Math.PI * 2f) * 8f);
				}
				else if (Time.time < recoilUntil)
				{
					val2 = socket.InverseTransformDirection(((Object)(object)mountedMuzzle != (Object)null) ? (-mountedMuzzle.forward) : (-head.forward));
					Vector3 normalized3 = ((Vector3)(ref val2)).normalized;
					mountedGun.transform.localPosition = mountedBasePosition + normalized3 * (Mathf.Sin(Mathf.InverseLerp(recoilUntil - 0.12f, recoilUntil, Time.time) * (float)Math.PI) * 0.07f);
				}
			}
			if (droneData.shots != lastShot)
			{
				lastShot = droneData.shots;
				if (droneData.deployed)
				{
					PlayFire(droneData);
					if ((Object)(object)tracer == (Object)null)
					{
						GameObject val5 = new GameObject("DroneMod tracer");
						val5.transform.SetParent(((Component)this).transform, false);
						tracer = val5.AddComponent<LineRenderer>();
						((Renderer)tracer).sharedMaterial = glow;
						tracer.startWidth = 0.025f;
						tracer.endWidth = 0.009f;
						tracer.positionCount = 2;
					}
					tracer.SetPosition(0, MuzzlePosition);
					tracer.SetPosition(1, droneData.shotAim);
					((Renderer)tracer).enabled = true;
					tracerUntil = Time.time + 0.09f;
				}
			}
			if (droneData.reloads != lastReload)
			{
				lastReload = droneData.reloads;
				Gun gun2 = Plugin.Instance.GetGun(droneData);
				if (droneData.deployed && gun2 != null)
				{
					PlayReload(droneData, gun2);
				}
			}
			if ((Object)(object)tracer != (Object)null && Time.time > tracerUntil)
			{
				((Renderer)tracer).enabled = false;
			}
			if (droneData.deployed && droneData.acquiring)
			{
				if ((Object)(object)lockLaser == (Object)null)
				{
					GameObject val6 = new GameObject("DroneMod target lock laser");
					val6.transform.SetParent(((Component)this).transform, false);
					lockLaser = val6.AddComponent<LineRenderer>();
					((Renderer)lockLaser).sharedMaterial = lockGlow;
					lockLaser.startWidth = 0.018f;
					lockLaser.endWidth = 0.008f;
					lockLaser.positionCount = 2;
				}
				lockLaser.SetPosition(0, MuzzlePosition);
				lockLaser.SetPosition(1, droneData.aim);
				((Renderer)lockLaser).enabled = true;
				if (droneData.acquisition != lastAcquisition)
				{
					lastAcquisition = droneData.acquisition;
					TargetSound.Play(((Component)this).transform.position);
				}
			}
			else if ((Object)(object)lockLaser != (Object)null)
			{
				((Renderer)lockLaser).enabled = false;
			}
		}
	}
	[BepInPlugin("ponyfisher.howtofish.dronemod", "Drone Mod", "0.1.17")]
	[DefaultExecutionOrder(29000)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class HiddenHud
		{
			public CanvasGroup group;

			public float alpha;

			public bool interactable;

			public bool blocks;

			public bool added;
		}

		private sealed class PlayerRendererState
		{
			public Renderer renderer;

			public bool enabled;

			public bool forceRenderingOff;
		}

		public const string Guid = "ponyfisher.howtofish.dronemod";

		public static Plugin Instance;

		public List<Gun> Guns = new List<Gun>();

		public List<DroneData> Current = new List<DroneData>();

		public bool Open;

		public string Status = "Load a game, then buy an empty drone kit.";

		public int Selected;

		private SaveData save = new SaveData();

		private WorldData world;

		private NetworkManager manager;

		private Harmony harmony;

		private string savePath;

		private bool persistenceReady = true;

		private bool registrationFailed;

		private bool catalogReady;

		private float nextTick;

		private float nextSave;

		private float nextState;

		private float nextHello;

		private int sequence;

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

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

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

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

		private readonly HashSet<string> playedModeSounds = new HashSet<string>();

		private int fpvSerial;

		private int pendingFpvSerial;

		private float fpvYaw;

		private float fpvPitch;

		private float nextFpvSend;

		private float fpvRequestUntil;

		private float fpvBaseFov;

		private float fpvZoomVelocity;

		private float fpvTurretHoldStart;

		private Vector3 fpvPosition;

		private Vector3 fpvMoveVelocity;

		private bool fpvPending;

		private bool fpvTurretHolding;

		private Camera fpvCamera;

		private Camera playerCamera;

		private GameObject fpvCameraObject;

		private bool playerCameraEnabled;

		private GUIStyle fpvHelpStyle;

		private GUIStyle fpvRecStyle;

		private readonly List<HiddenHud> hiddenHud = new List<HiddenHud>();

		private readonly List<PlayerRendererState> fpvPlayerRenderers = new List<PlayerRendererState>();

		private Rect panel = new Rect(40f, 60f, 730f, 640f);

		private Vector2 droneScroll;

		private Vector2 gunScroll;

		private bool socketOpen;

		private string nameDraft = "";

		private string confirmAction = "";

		private int nameSerial;

		private int activeTab;

		private Vector3 bodyDraft;

		private Vector3 propellerDraft;

		private Vector3 accentDraft;

		private float distanceDraft;

		private CursorLockMode oldLock;

		private GUIStyle titleStyle;

		private GUIStyle bodyStyle;

		private GUIStyle slotStyle;

		private GUIStyle windowStyle;

		private GUIStyle buttonStyle;

		private GUIStyle accentButton;

		private GUIStyle recallButtonStyle;

		private GUIStyle dangerButton;

		private GUIStyle selectedButton;

		private GUIStyle inputStyle;

		private GUIStyle headerStyle;

		private GUIStyle statusStyle;

		private GUIStyle toggleStyle;

		private Texture2D steel;

		private Texture2D steelInset;

		private Texture2D steelEdge;

		private Texture2D cyan;

		private Texture2D cyanHover;

		private Texture2D orange;

		private Texture2D orangeHover;

		private Texture2D red;

		private Texture2D redHover;

		private float holdStart;

		private int holdSerial;

		private bool holdFired;

		private string holdAction;

		private GUIStyle droneLabelStyle;

		private bool audited;

		private float auditAfter;

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

		public bool FpvActive { get; private set; }

		public bool FreeCam { get; private set; }

		public static void Log(string text)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)text);
			}
		}

		public bool IsFpvDrone(int serial)
		{
			if (FpvActive)
			{
				return fpvSerial == serial;
			}
			return false;
		}

		private void Awake()
		{
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Expected O, but got Unknown
			Instance = this;
			savePath = Path.Combine(Paths.ConfigPath, "DroneMod-worlds.json");
			try
			{
				if (File.Exists(savePath))
				{
					save = Codec.FromJson<SaveData>(File.ReadAllText(savePath));
					if (save == null || save.version != 1 || save.worlds == null)
					{
						throw new Exception("Unrecognized save format");
					}
				}
			}
			catch (Exception ex)
			{
				persistenceReady = false;
				Status = "Drone Mod save could not be read. Purchases disabled to protect it.";
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
			GenericWriter<RequestMessage>.SetWrite((Action<Writer, RequestMessage>)delegate(Writer w, RequestMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<RequestMessage>.SetRead((Func<Reader, RequestMessage>)((Reader r) => new RequestMessage
			{
				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.json);
			});
			GenericReader<ReplyMessage>.SetRead((Func<Reader, ReplyMessage>)((Reader r) => new ReplyMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<HitFeedbackMessage>.SetWrite((Action<Writer, HitFeedbackMessage>)delegate(Writer w, HitFeedbackMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<HitFeedbackMessage>.SetRead((Func<Reader, HitFeedbackMessage>)((Reader r) => new HitFeedbackMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<ModeSoundMessage>.SetWrite((Action<Writer, ModeSoundMessage>)delegate(Writer w, ModeSoundMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<ModeSoundMessage>.SetRead((Func<Reader, ModeSoundMessage>)((Reader r) => new ModeSoundMessage
			{
				json = r.ReadStringAllocated()
			}));
			harmony = new Harmony("ponyfisher.howtofish.dronemod");
			harmony.PatchAll(typeof(Plugin).Assembly);
			((MonoBehaviour)this).StartCoroutine(DroneSounds.Load());
			Log("Drone Mod 0.1.17 loaded. Press F3 to open Drone Control.");
		}

		private void Update()
		{
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			if (Keyboard.current != null && ((ButtonControl)Keyboard.current.f3Key).wasPressedThisFrame && !FpvActive && !fpvPending)
			{
				Toggle(!Open);
			}
			UpdateLocalDroneControl();
			UpdateHoldInteraction();
			if ((Object)(object)manager != (Object)(object)InstanceFinder.NetworkManager)
			{
				RegisterNetwork();
			}
			if (!registrationFailed && (Object)(object)Kit.Prefab == (Object)null)
			{
				try
				{
					Kit.Register();
				}
				catch (Exception ex)
				{
					registrationFailed = true;
					Status = "Drone item registration failed; see BepInEx log.";
					((BaseUnityPlugin)this).Logger.LogError((object)ex);
				}
			}
			if ((Object)(object)Kit.Prefab != (Object)null && !catalogReady)
			{
				BuildCatalog();
				catalogReady = true;
			}
			if (InstanceFinder.IsServerStarted && SaveManager.CurServerSave != null)
			{
				string name = SaveManager.CurServerSave.Name;
				if (world == null || world.name != name)
				{
					world = save.worlds.FirstOrDefault((WorldData w) => w.name == name);
					if (world == null)
					{
						world = new WorldData
						{
							name = name
						};
						save.worlds.Add(world);
					}
					Current = world.drones;
					audited = false;
					auditAfter = Time.unscaledTime + 5f;
					missingSince.Clear();
					kits.Clear();
					followOwners.Clear();
					lastSequence.Clear();
					rateLimit.Clear();
					bool flag = false;
					foreach (DroneData item in Current)
					{
						if (item.followDefaultsVersion < 1)
						{
							item.followPosition = 2;
							item.followDistance = 3f;
							item.followDefaultsVersion = 1;
							flag = true;
						}
						item.nextShot = Time.time + 1f;
						item.reloading = false;
						item.lockedTarget = null;
						item.acquiring = false;
						item.hasTarget = false;
					}
					if (flag)
					{
						Persist();
					}
				}
				if (Time.unscaledTime >= nextTick)
				{
					nextTick = Time.unscaledTime + 0.1f;
					ServerTick();
				}
				if (Time.unscaledTime >= nextState)
				{
					nextState = Time.unscaledTime + (Current.Any((DroneData d) => d.