Decompiled source of NukeStrike v1.13.8

Mods/NukeStrike.dll

Decompiled 13 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using LabFusion.Entities;
using LabFusion.Marrow.Pool;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.RPC;
using LabFusion.SDK.Metadata;
using LabFusion.SDK.Modules;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using NukeStrike;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.XR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(NukeStrikeMod), "NukeStrike", "1.13.8", "callofike", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[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 NukeStrike
{
	internal static class Bomber
	{
		private sealed class Tuning
		{
			public string Name;

			public float MaxSpeed;

			public float StallSpeed;

			public float TakeoffSpeed;

			public float PitchRate;

			public float RollRate;

			public float MaxPitch;

			public float MaxRoll;

			public float Accel;

			public float StickSmooth;

			public float Level;

			public Vector3 CentreOfMass;
		}

		private sealed class Plane
		{
			public GameObject Go;

			public Rigidbody Rb;

			public Transform Cockpit;

			public Transform Handle;

			public Transform BombBay;

			public Transform Ladder;

			public Tuning T = NukeTuning;

			public Transform Release;

			public Transform DoorL;

			public Transform DoorR;

			public Transform ButtonCap;

			public float Door;

			public float DoorTarget;

			public float CloseAt;

			public Vector3 KinVel;

			public bool DropQueued;

			public bool ButtonHeld;

			public Transform[] Props;

			public Collider[] Cols;

			public Seat Seat;

			public Vector3 Pos;

			public float Yaw;

			public float Pitch;

			public float Roll;

			public float Speed;

			public float Throttle;

			public float PropAngle;

			public float LastThrottleStep;

			public bool Airborne;

			public bool Driving;

			public bool FusionSynced;

			public Vector3 NetPos;

			public Vector3 NetVel;

			public Quaternion NetRot;

			public float NetAge = 99f;

			public float SendTimer;
		}

		private sealed class Bomb
		{
			public GameObject Go;

			public Rigidbody Rb;

			public int N;

			public Vector3 LastPos;

			public Vector3 LastVel;

			public Vector3 Dir;

			public float Age;

			public float Radius;

			public float Speed;
		}

		private sealed class PendingDrop
		{
			public int N;

			public float At;

			public bool ViaFusion;

			public bool LocalRetry;
		}

		private sealed class Blast
		{
			public int N;

			public string Barcode;

			public Vector3 Pos;

			public float RequestedAt;

			public float SeenAt;

			public bool ViaFusion;

			public bool LocalRetry;

			public GameObject Go;
		}

		public const string Barcode = "callofike.NukeStrike.Spawnable.NukeBomber";

		public const string SpiritBarcode = "callofike.NukeStrike.Spawnable.SpiritBomber";

		private const string BombBarcode = "callofike.NukeStrike.Spawnable.NukeStrikeFallingBomb";

		private const string DropBombPrefix = "callofike.NukeStrike.Spawnable.NukeStrikeBomb";

		private static readonly int[] DropBombSpeeds = new int[3] { 25, 35, 45 };

		private const string BlastLarge = "callofike.NukeStrike.Spawnable.NukeStrikeBlastLarge";

		private const string BlastHuge = "callofike.NukeStrike.Spawnable.NukeStrikeBlastHuge";

		private static readonly Tuning NukeTuning = new Tuning
		{
			Name = "Nuke Bomber",
			MaxSpeed = 45f,
			StallSpeed = 17f,
			TakeoffSpeed = 24f,
			PitchRate = 22f,
			RollRate = 45f,
			MaxPitch = 30f,
			MaxRoll = 50f,
			Accel = 5f,
			StickSmooth = 8f,
			Level = 1f,
			CentreOfMass = new Vector3(0f, 1.5f, 1f)
		};

		private static readonly Tuning SpiritTuning = new Tuning
		{
			Name = "Spirit Bomber",
			MaxSpeed = 45f,
			StallSpeed = 19f,
			TakeoffSpeed = 27f,
			PitchRate = 13f,
			RollRate = 26f,
			MaxPitch = 22f,
			MaxRoll = 40f,
			Accel = 3.2f,
			StickSmooth = 4f,
			Level = 0.6f,
			CentreOfMass = new Vector3(0f, 1.5f, -3f)
		};

		private const float DoorSpeed = 1.6f;

		private const float DoorHold = 1.3f;

		private const float ButtonReach = 0.08f;

		private const float GrabRadius = 0.35f;

		private const float ExitHold = 1f;

		private const float DropCooldown = 2f;

		private static readonly List<GameObject> PendingPlanes = new List<GameObject>();

		private static readonly List<Plane> Planes = new List<Plane>();

		private static readonly List<Bomb> Bombs = new List<Bomb>();

		private static readonly HashSet<(Collider, Collider)> Ignored = new HashSet<(Collider, Collider)>();

		private static Il2CppStructArray<RaycastHit> _hits;

		private static float _frameSum;

		private static float _frameMax;

		private static float _ignoreTimer;

		private static int _frameCount;

		private static int _slowFrames;

		private static StreamWriter _dbg;

		private static int _stepsThisFrame;

		private static int _stepsMin = 99;

		private static int _stepsMax;

		private static int _dbgFrames;

		private static float _dbgTimer;

		private static float _dbgFrameMax;

		private static float _dbgFrameSum;

		private static float _dbgJumpMax;

		private static float _dbgJumpSum;

		private static float _dbgLagMax;

		private static float _dbgFlush;

		private static Vector3 _lastHeadLocal;

		private static Vector3 _lastPelvisLocal;

		private static bool _haveHead;

		private static bool _havePelvis;

		private static Transform _pelvis;

		private static float _dbgPelvisMax;

		private static float _dbgPelvisSum;

		private static string _rigInterp = "?";

		private static FlightSmoothing _applied = (FlightSmoothing)(-1);

		private static Plane _flying;

		private static float _holdB;

		private static float _dropCooldown;

		private static float _bumpCooldown;

		private static float _statusTimer;

		private static Vector2 _left;

		private static Vector2 _right;

		private static bool _trigger;

		private static string _logFile;

		private static readonly List<PendingDrop> PendingDrops = new List<PendingDrop>();

		private static readonly List<Blast> Blasts = new List<Blast>();

		private static readonly List<GameObject> OtherBombs = new List<GameObject>();

		private static int _dropCount;

		private const float SpawnWait = 2.5f;

		private const float BombTimeout = 60f;

		private const float OutOfWorldY = -1500f;

		private const int MaxBombsInAir = 4;

		private static Il2CppStructArray<RaycastHit> Hits => _hits ?? (_hits = new Il2CppStructArray<RaycastHit>(64L));

		public static bool Flying => _flying != null;

		private static void Log(string msg)
		{
			NukeStrikeMod instance = NukeStrikeMod.Instance;
			if (instance != null)
			{
				((MelonBase)instance).LoggerInstance.Msg("[Bomber] " + msg);
			}
			try
			{
				if (_logFile == null)
				{
					_logFile = Path.Combine(MelonEnvironment.UserDataDirectory, "NukeStrike_bomber_log.txt");
					File.WriteAllText(_logFile, $"NukeStrike bomber log, {DateTime.Now}\n");
				}
				File.AppendAllText(_logFile, $"[{DateTime.Now:HH:mm:ss.fff}] {msg}\n");
			}
			catch
			{
			}
		}

		public static void Seen(Poolee poolee, GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				string text = null;
				try
				{
					text = (((Object)(object)poolee.SpawnableCrate != (Object)null) ? ((Scannable)poolee.SpawnableCrate).Barcode.ID : null);
				}
				catch
				{
				}
				if (text == "callofike.NukeStrike.Spawnable.NukeBomber" || text == "callofike.NukeStrike.Spawnable.SpiritBomber" || (text == null && (((Object)go).name.StartsWith("NukeBomber") || ((Object)go).name.StartsWith("SpiritBomber"))))
				{
					PendingPlanes.Add(go);
				}
				else if (text == "callofike.NukeStrike.Spawnable.NukeStrikeFallingBomb" || (text != null && text.StartsWith("callofike.NukeStrike.Spawnable.NukeStrikeBomb")) || (text == null && (((Object)go).name.StartsWith("NukeStrikeFallingBomb") || ((Object)go).name.StartsWith("NukeStrikeBomb"))))
				{
					OnBombSpawned(go);
				}
				else if (text == "callofike.NukeStrike.Spawnable.NukeStrikeBlastLarge" || text == "callofike.NukeStrike.Spawnable.NukeStrikeBlastHuge" || (text == null && ((Object)go).name.StartsWith("NukeStrikeBlast")))
				{
					OnBlastSpawned(go);
				}
			}
		}

		public static void Clear()
		{
			PendingPlanes.Clear();
			Planes.Clear();
			Bombs.Clear();
			PendingDrops.Clear();
			Blasts.Clear();
			OtherBombs.Clear();
			Ignored.Clear();
			_flying = null;
			_holdB = 0f;
		}

		public static void LateUpdate()
		{
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			Plane flying = _flying;
			int stepsThisFrame = _stepsThisFrame;
			_stepsThisFrame = 0;
			if (flying == null || (Object)(object)flying.Go == (Object)null || (Object)(object)Player.Head == (Object)null)
			{
				_haveHead = (_havePelvis = false);
				return;
			}
			try
			{
				if (_applied != NukeStrikeMod.Smoothing)
				{
					ApplySmoothing(flying);
				}
				float num = Time.unscaledDeltaTime * 1000f;
				_dbgFrames++;
				_dbgFrameSum += num;
				if (num > _dbgFrameMax)
				{
					_dbgFrameMax = num;
				}
				if (stepsThisFrame < _stepsMin)
				{
					_stepsMin = stepsThisFrame;
				}
				if (stepsThisFrame > _stepsMax)
				{
					_stepsMax = stepsThisFrame;
				}
				Vector3 val = flying.Go.transform.InverseTransformPoint(Player.Head.position);
				Vector3 val2;
				if (_haveHead)
				{
					val2 = val - _lastHeadLocal;
					float num2 = ((Vector3)(ref val2)).magnitude * 100f;
					_dbgJumpSum += num2;
					if (num2 > _dbgJumpMax)
					{
						_dbgJumpMax = num2;
					}
				}
				_lastHeadLocal = val;
				_haveHead = true;
				val2 = flying.Go.transform.position - flying.Rb.position;
				float num3 = ((Vector3)(ref val2)).magnitude * 100f;
				if (num3 > _dbgLagMax)
				{
					_dbgLagMax = num3;
				}
				if ((Object)(object)_pelvis != (Object)null)
				{
					Vector3 val3 = flying.Go.transform.InverseTransformPoint(_pelvis.position);
					if (_havePelvis)
					{
						val2 = val3 - _lastPelvisLocal;
						float num4 = ((Vector3)(ref val2)).magnitude * 100f;
						_dbgPelvisSum += num4;
						if (num4 > _dbgPelvisMax)
						{
							_dbgPelvisMax = num4;
						}
					}
					_lastPelvisLocal = val3;
					_havePelvis = true;
				}
				if ((_dbgTimer -= Time.unscaledDeltaTime) <= 0f)
				{
					_dbgTimer = 0.5f;
					float value = 0f;
					try
					{
						value = XRDevice.refreshRate;
					}
					catch
					{
					}
					if (_dbg == null)
					{
						_dbg = new StreamWriter(Path.Combine(MelonEnvironment.UserDataDirectory, "NukeStrike_flight_debug.txt"), append: true);
						_dbg.WriteLine($"--- {DateTime.Now:yyyy-MM-dd HH:mm:ss} NukeStrike flight debug. jump = head movement relative to the plane per frame; lag = drawn plane vs physics position");
					}
					_dbg.WriteLine($"{DateTime.Now:HH:mm:ss.f} {flying.T.Name} {NukeStrikeMod.Smoothing}: frame avg {_dbgFrameSum / (float)Mathf.Max(1, _dbgFrames):F1} ms max {_dbgFrameMax:F0} ms; physics {Time.fixedDeltaTime * 1000f:F1} ms ({1f / Time.fixedDeltaTime:F0} Hz), headset {value:F0} Hz, steps/frame {_stepsMin}-{_stepsMax}; speed {flying.Speed:F0} m/s; head jump avg {_dbgJumpSum / (float)Mathf.Max(1, _dbgFrames):F1} cm max {_dbgJumpMax:F1} cm; pelvis jump avg {_dbgPelvisSum / (float)Mathf.Max(1, _dbgFrames):F1} cm max {_dbgPelvisMax:F1} cm; plane lag max {_dbgLagMax:F0} cm (body drawn: {_rigInterp}); head at {val:F2}");
					_dbgFrames = 0;
					_dbgFrameSum = (_dbgFrameMax = (_dbgJumpSum = (_dbgJumpMax = (_dbgLagMax = (_dbgPelvisSum = (_dbgPelvisMax = 0f))))));
					_stepsMin = 99;
					_stepsMax = 0;
					if ((_dbgFlush -= 0.5f) <= 0f)
					{
						_dbgFlush = 5f;
						_dbg.Flush();
					}
				}
			}
			catch (Exception ex)
			{
				Log("flight debug: " + ex.Message);
				_haveHead = false;
			}
		}

		private static RigidbodyInterpolation BodyInterpolation()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			//IL_00e1: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			_pelvis = null;
			_havePelvis = false;
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
			{
				_rigInterp = "no rig";
				return (RigidbodyInterpolation)1;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (Rigidbody componentsInChild in ((Component)rigManager.physicsRig).GetComponentsInChildren<Rigidbody>(false))
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					if ((int)componentsInChild.interpolation == 0)
					{
						num++;
					}
					else if ((int)componentsInChild.interpolation == 1)
					{
						num2++;
					}
					else
					{
						num3++;
					}
					if ((Object)(object)_pelvis == (Object)null && ((Object)componentsInChild).name.ToLowerInvariant().Contains("pelvis"))
					{
						_pelvis = ((Component)componentsInChild).transform;
					}
				}
			}
			RigidbodyInterpolation val = (RigidbodyInterpolation)((num2 >= num && num2 >= num3) ? 1 : ((num3 > num) ? 2 : 0));
			_rigInterp = $"{val} ({num2} interpolated, {num} not, {num3} extrapolated; pelvis {(((Object)(object)_pelvis != (Object)null) ? ((Object)_pelvis).name : "not found")})";
			return val;
		}

		private static void ApplySmoothing(Plane p)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			_applied = NukeStrikeMod.Smoothing;
			RigidbodyInterpolation val = BodyInterpolation();
			p.Rb.isKinematic = _applied == FlightSmoothing.Kinematic;
			p.Rb.interpolation = (RigidbodyInterpolation)((_applied != FlightSmoothing.Off) ? ((_applied != FlightSmoothing.Auto) ? 1 : ((int)val)) : 0);
			Log($"flight smoothing: {_applied} (kinematic {p.Rb.isKinematic}, plane drawn {p.Rb.interpolation}; your body: {_rigInterp})");
			try
			{
				_dbg?.WriteLine($"{DateTime.Now:HH:mm:ss.f} switched to {_applied}");
			}
			catch
			{
			}
		}

		public static void Update()
		{
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			if (PendingPlanes.Count > 0)
			{
				foreach (GameObject go in PendingPlanes)
				{
					if ((Object)(object)go != (Object)null && !Planes.Exists((Plane p) => (Object)(object)p.Go == (Object)(object)go))
					{
						try
						{
							Register(go);
						}
						catch (Exception ex)
						{
							Log("could not set up a bomber: " + ex);
						}
					}
				}
				PendingPlanes.Clear();
			}
			Planes.RemoveAll((Plane p) => (Object)(object)p.Go == (Object)null || (!p.Go.activeInHierarchy && p != _flying));
			if (_dropCooldown > 0f)
			{
				_dropCooldown -= Time.deltaTime;
			}
			if (_bumpCooldown > 0f)
			{
				_bumpCooldown -= Time.deltaTime;
			}
			try
			{
				UpdatePlayer();
			}
			catch (Exception ex2)
			{
				Log("update failed: " + ex2);
			}
			try
			{
				UpdateDrops();
			}
			catch (Exception ex3)
			{
				Log("drop update failed: " + ex3);
			}
			if (_flying != null)
			{
				float num = Time.unscaledDeltaTime * 1000f;
				_frameSum += num;
				_frameCount++;
				if (num > _frameMax)
				{
					_frameMax = num;
				}
				if (num > 20f)
				{
					_slowFrames++;
				}
				if ((_ignoreTimer -= Time.deltaTime) <= 0f && (Object)(object)Player.RigManager != (Object)null)
				{
					_ignoreTimer = 3f;
					try
					{
						IgnorePlane(Player.RigManager, _flying, ignore: true);
					}
					catch (Exception ex4)
					{
						Log("ignore refresh: " + ex4.Message);
					}
				}
			}
			if (_flying != null && (_statusTimer -= Time.deltaTime) <= 0f)
			{
				_statusTimer = 15f;
				Plane flying = _flying;
				string value = ((_frameCount > 0) ? $"frames avg {_frameSum / (float)_frameCount:F1} ms, worst {_frameMax:F0} ms, {_slowFrames} over 20 ms, fixed step {Time.fixedDeltaTime * 1000f:F1} ms" : "no frames");
				_frameSum = (_frameMax = 0f);
				_frameCount = (_slowFrames = 0);
				if ((Object)(object)flying.Go != (Object)null)
				{
					Log($"status: {(flying.Airborne ? "flying" : "on the ground")}, {flying.Speed:F0} m/s, throttle {flying.Throttle * 100f:F0}%, at {flying.Go.transform.position}, seated {(Object)(object)flying.Seat != (Object)null && (Object)(object)flying.Seat.rigManager == (Object)(object)Player.RigManager}, cooldown {Mathf.Max(0f, _dropCooldown):F1} s; {value}; ignoring {Ignored.Count} collider pairs; {Status()}");
				}
			}
			foreach (Plane plane in Planes)
			{
				try
				{
					UpdateDoors(plane);
				}
				catch (Exception ex5)
				{
					Log("doors failed: " + ex5.Message);
				}
				plane.PropAngle += (plane.Driving ? (200f + 1600f * plane.Throttle) : 0f) * Time.deltaTime;
				Transform[] props = plane.Props;
				foreach (Transform val in props)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.localRotation = Quaternion.Euler(0f, 0f, plane.PropAngle);
					}
				}
			}
		}

		public static void FixedUpdate()
		{
			float fixedDeltaTime = Time.fixedDeltaTime;
			_stepsThisFrame++;
			try
			{
				if (_flying != null)
				{
					Fly(_flying, fixedDeltaTime);
				}
			}
			catch (Exception ex)
			{
				Log("flight failed: " + ex);
				_flying.Driving = false;
			}
			foreach (Plane plane in Planes)
			{
				if (plane != _flying)
				{
					FollowNet(plane, fixedDeltaTime);
				}
			}
			for (int num = Bombs.Count - 1; num >= 0; num--)
			{
				try
				{
					if (!UpdateBomb(Bombs[num], fixedDeltaTime))
					{
						Bombs.RemoveAt(num);
					}
				}
				catch (Exception ex2)
				{
					Log("bomb failed: " + ex2);
					Bombs.RemoveAt(num);
				}
			}
		}

		private static void Register(GameObject go)
		{
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			Plane plane = new Plane
			{
				Go = go,
				Rb = go.GetComponent<Rigidbody>(),
				Cockpit = go.transform.Find("Cockpit"),
				BombBay = go.transform.Find("BombBay"),
				Ladder = go.transform.Find("BoardingLadder")
			};
			plane.Handle = (((Object)(object)plane.Ladder != (Object)null) ? plane.Ladder.Find("BoardHandle") : null);
			if (((Object)go).name.StartsWith("SpiritBomber"))
			{
				plane.T = SpiritTuning;
			}
			plane.Release = go.transform.Find("BombRelease");
			plane.DoorL = go.transform.Find("BayDoorL");
			plane.DoorR = go.transform.Find("BayDoorR");
			Transform val = go.transform.Find("NukeButton");
			plane.ButtonCap = (((Object)(object)val != (Object)null) ? val.Find("Cap") : null);
			if ((Object)(object)plane.Rb == (Object)null || (Object)(object)plane.Cockpit == (Object)null || (Object)(object)plane.Handle == (Object)null)
			{
				Log(((Object)go).name + ": missing Rigidbody/Cockpit/BoardHandle (old pallet?)");
				return;
			}
			List<Transform> list = new List<Transform>();
			Transform val2 = go.transform.Find("Model");
			if ((Object)(object)val2 != (Object)null)
			{
				for (int i = 1; i <= 4; i++)
				{
					Transform val3 = val2.Find("PropHub" + i);
					if ((Object)(object)val3 != (Object)null)
					{
						list.Add(val3);
					}
				}
			}
			plane.Props = list.ToArray();
			plane.Cols = Il2CppArrayBase<Collider>.op_Implicit(go.GetComponentsInChildren<Collider>(true));
			plane.Rb.centerOfMass = plane.T.CentreOfMass;
			plane.Rb.interpolation = (RigidbodyInterpolation)1;
			plane.Seat = MakeSeat(plane);
			Planes.Add(plane);
			Log($"{plane.T.Name} spawned at {go.transform.position}{(((Object)(object)plane.DoorL != (Object)null) ? " (bay doors, NUKE button)" : "")}; seat {(((Object)(object)plane.Seat != (Object)null) ? ("ready at " + ((object)SafeButt(plane.Seat)/*cast due to .constrained prefix*/).ToString()) : "FAILED")}");
		}

		private static Seat MakeSeat(Plane p)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject("NukeBomberSeat");
				val.SetActive(false);
				val.transform.SetParent(p.Cockpit, false);
				Transform transform = new GameObject("FootLf").transform;
				transform.SetParent(val.transform, false);
				transform.localPosition = new Vector3(-0.14f, 0.02f, 1.19f);
				Transform transform2 = new GameObject("FootRt").transform;
				transform2.SetParent(val.transform, false);
				transform2.localPosition = new Vector3(0.14f, 0.02f, 1.19f);
				BoxCollider obj = val.AddComponent<BoxCollider>();
				((Collider)obj).isTrigger = true;
				obj.size = new Vector3(0.5f, 0.2f, 0.5f);
				Seat val2 = val.AddComponent<Seat>();
				val2.seatRb = p.Rb;
				val2.footLf = transform;
				val2.footRt = transform2;
				val2.minSeatBounds = new Vector3(0.1f, 0.05f, 0.1f);
				val2.maxSeatBounds = new Vector3(0.25f, 0.1f, 0.2f);
				val2.spineRom = new Vector4(60f, 180f, 60f, 40f);
				val2.primaryUpDown = (AxisAssignment)4;
				val2.primaryLeftRight = (AxisAssignment)4;
				val2.secondaryUpDown = (AxisAssignment)4;
				val2.secondaryLeftRight = (AxisAssignment)4;
				val2.blockUnseatAction = true;
				val.SetActive(true);
				Transform transform3 = val.transform;
				transform3.position += p.Cockpit.position - SafeButt(val2);
				return val2;
			}
			catch (Exception ex)
			{
				Log("could not make the seat: " + ex);
				return null;
			}
		}

		private static Vector3 SafeButt(Seat seat)
		{
			//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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return seat.buttTargetInWorld;
			}
			catch
			{
				return ((Component)seat).transform.position;
			}
		}

		private static void UpdatePlayer()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00c3: 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_00cf: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null)
			{
				return;
			}
			BaseController leftController = Player.LeftController;
			BaseController rightController = Player.RightController;
			if ((Object)(object)leftController == (Object)null || (Object)(object)rightController == (Object)null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (_flying != null)
			{
				Plane flying = _flying;
				if ((Object)(object)flying.Go == (Object)null || (Object)(object)flying.Seat == (Object)null || (Object)(object)flying.Seat.rigManager != (Object)(object)rigManager)
				{
					Log("out of the seat (not by B)");
					AfterExit(rigManager, teleport: false);
					return;
				}
				float num = 1f - Mathf.Exp((0f - flying.T.StickSmooth) * deltaTime);
				_left = Vector2.Lerp(_left, leftController.GetThumbStickAxis(), num);
				_right = Vector2.Lerp(_right, rightController.GetThumbStickAxis(), num);
				bool num2 = rightController.GetPrimaryInteractionButtonAxis() > 0.7f;
				if (num2 && !_trigger)
				{
					Drop(flying, "trigger");
				}
				_trigger = num2;
				if ((Object)(object)flying.ButtonCap != (Object)null)
				{
					UpdateButton(flying);
				}
				_holdB = (rightController.GetBButton() ? (_holdB + deltaTime) : 0f);
				if (_holdB >= 1f)
				{
					_holdB = 0f;
					Log("B held: getting out");
					try
					{
						flying.Seat.EgressRig(true);
					}
					catch (Exception ex)
					{
						Log("EgressRig: " + ex.Message);
					}
					AfterExit(rigManager, teleport: true);
				}
				return;
			}
			foreach (Plane plane in Planes)
			{
				if (!((Object)(object)plane.Seat == (Object)null))
				{
					Vector3 velocity = plane.Rb.velocity;
					if (!(((Vector3)(ref velocity)).sqrMagnitude > 4f) && (Grabs(plane, Player.LeftHand, leftController) || Grabs(plane, Player.RightHand, rightController)))
					{
						Board(rigManager, plane);
						break;
					}
				}
			}
		}

		private static bool Grabs(Plane p, Hand hand, BaseController c)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//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_0042: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand == (Object)null || c.GetGripForce() < 0.6f)
			{
				return false;
			}
			Vector3 val = p.Handle.position - p.Go.transform.up * 0.8f;
			Vector3 val2 = p.Handle.position + p.Go.transform.up * 0.9f;
			Vector3 position = ((Component)hand).transform.position;
			Vector3 val3 = val2 - val;
			Vector3 val4 = val + val3 * Mathf.Clamp01(Vector3.Dot(position - val, val3) / ((Vector3)(ref val3)).sqrMagnitude);
			return Vector3.Distance(position, val4) < 0.35f;
		}

		private static void Board(RigManager rig, Plane p)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			IgnorePlane(rig, p, ignore: true);
			bool flag = false;
			try
			{
				flag = p.Seat.TeleportRigToSeat(rig);
			}
			catch (Exception ex)
			{
				Log("TeleportRigToSeat: " + ex.Message);
			}
			p.Seat.IngressRig(rig);
			bool flag2 = (Object)(object)p.Seat.rigManager == (Object)(object)rig;
			p.FusionSynced = Net.IsSynced(p.Rb);
			Log($"boarding: teleport {(flag ? "ok" : "refused")}, seat rig is us: {flag2}" + (Net.InLobby ? $", Fusion syncs the plane: {p.FusionSynced}" : ""));
			if (!flag2)
			{
				IgnorePlane(rig, p, ignore: false);
				NukeStrikeMod.Notify("Couldn't get into the bomber (see log)", (NotificationType)2);
				return;
			}
			_flying = p;
			_holdB = 0f;
			_left = (_right = Vector2.zero);
			_trigger = true;
			p.Pos = p.Rb.position;
			Vector3 eulerAngles = p.Go.transform.eulerAngles;
			p.Yaw = eulerAngles.y;
			p.Pitch = (p.Roll = (p.Speed = (p.Throttle = 0f)));
			p.LastThrottleStep = 0f;
			p.Airborne = false;
			p.Driving = true;
			p.Rb.useGravity = false;
			if (Net.TakeOwnershipIfNeeded(p.Rb))
			{
				Log("asked Fusion for the plane's ownership");
			}
			NukeStrikeMod.Notify("Left stick: throttle / rudder. Right stick: pitch / roll. Right trigger: drop the nuke. Hold B: get out.", (NotificationType)0);
			try
			{
				Haptics.Pulse(Player.LeftController, 0.3f, 0.6f);
				Haptics.Pulse(Player.RightController, 0.3f, 0.6f);
			}
			catch
			{
			}
		}

		private static void AfterExit(RigManager rig, bool teleport)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			Plane flying = _flying;
			_flying = null;
			if (flying == null)
			{
				return;
			}
			flying.DropQueued = false;
			SetDoors(flying, 0f, send: true);
			IgnorePlane(rig, flying, ignore: false);
			flying.Driving = false;
			if ((Object)(object)flying.Go == (Object)null)
			{
				return;
			}
			flying.Rb.isKinematic = false;
			flying.Rb.interpolation = (RigidbodyInterpolation)1;
			_applied = (FlightSmoothing)(-1);
			flying.Rb.useGravity = true;
			if (!flying.Airborne)
			{
				Rigidbody rb = flying.Rb;
				rb.velocity *= 0.2f;
				flying.Rb.angularVelocity = Vector3.zero;
			}
			if (teleport)
			{
				Vector3 val = flying.Go.transform.position - flying.Go.transform.right * 4f + flying.Go.transform.forward * 9f;
				float num = GroundY(flying, val + Vector3.up * 3f, 30f);
				val.y = ((float.IsNegativeInfinity(num) || val.y - num > 6f) ? (val.y + 1f) : (num + 0.1f));
				bool value = false;
				try
				{
					value = rig.Teleport(val, true);
				}
				catch (Exception ex)
				{
					Log("Teleport: " + ex.Message);
				}
				Log($"out at {val} (teleport {value})");
			}
		}

		public static void ForceExit()
		{
			RigManager rigManager = Player.RigManager;
			if (_flying == null || (Object)(object)rigManager == (Object)null)
			{
				NukeStrikeMod.Notify("You're not in a bomber", (NotificationType)0);
				return;
			}
			try
			{
				_flying.Seat.EgressRig(true);
			}
			catch
			{
			}
			AfterExit(rigManager, teleport: true);
		}

		private static void IgnorePlane(RigManager rig, Plane p, bool ignore)
		{
			if (!ignore)
			{
				foreach (var (val, val2) in Ignored)
				{
					if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
					{
						Physics.IgnoreCollision(val, val2, false);
					}
				}
				Ignored.Clear();
			}
			else
			{
				if ((Object)(object)rig.physicsRig == (Object)null)
				{
					return;
				}
				List<Collider> list = new List<Collider>((IEnumerable<Collider>)((Component)rig.physicsRig).GetComponentsInChildren<Collider>(true));
				Hand[] array = (Hand[])(object)new Hand[2]
				{
					Player.LeftHand,
					Player.RightHand
				};
				foreach (Hand val3 in array)
				{
					try
					{
						GameObject val4 = (((Object)(object)val3 != (Object)null) ? Player.GetObjectInHand(val3) : null);
						Rigidbody val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponentInParent<Rigidbody>() : null);
						if ((Object)(object)val5 != (Object)null)
						{
							list.AddRange((IEnumerable<Collider>)((Component)val5).GetComponentsInChildren<Collider>(true));
						}
					}
					catch
					{
					}
				}
				foreach (Collider item in list)
				{
					Collider[] cols = p.Cols;
					foreach (Collider val6 in cols)
					{
						if ((Object)(object)item != (Object)null && (Object)(object)val6 != (Object)null && Ignored.Add((item, val6)))
						{
							Physics.IgnoreCollision(item, val6, true);
						}
					}
				}
			}
		}

		private static void Fly(Plane p, float dt)
		{
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: 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_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0768: Unknown result type (might be due to invalid IL or missing references)
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_070d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0712: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_07af: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d2: 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_0779: 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_0784: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			//IL_078f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0796: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_082c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0819: Unknown result type (might be due to invalid IL or missing references)
			//IL_0825: 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_0871: Unknown result type (might be due to invalid IL or missing references)
			//IL_0884: Unknown result type (might be due to invalid IL or missing references)
			//IL_087c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p.Go == (Object)null || !p.Driving)
			{
				return;
			}
			Rigidbody rb = p.Rb;
			p.Throttle = Mathf.Clamp01(p.Throttle + Dead(_left.y) * 0.45f * dt);
			float num = Mathf.Floor(p.Throttle * 4f) / 4f;
			if (num != p.LastThrottleStep)
			{
				p.LastThrottleStep = num;
				Haptics.Pulse(Player.LeftController, 0.05f, 0.4f);
			}
			Tuning t = p.T;
			float num2 = p.Throttle * t.MaxSpeed;
			p.Speed = Mathf.MoveTowards(p.Speed, num2, ((num2 > p.Speed) ? t.Accel : (p.Airborne ? 1.5f : 6f)) * dt);
			float num3 = Mathf.InverseLerp(t.StallSpeed, t.TakeoffSpeed, p.Speed);
			float num4 = Dead(_left.x);
			float num5 = 0f - Dead(_right.y);
			float num6 = Dead(_right.x);
			if (!p.Airborne)
			{
				p.Yaw += num4 * Mathf.Lerp(30f, 8f, p.Speed / t.TakeoffSpeed) * dt * Mathf.Clamp01(p.Speed / 2f + 0.3f);
				p.Roll = Mathf.MoveTowards(p.Roll, 0f, 30f * dt);
				float num7 = ((p.Speed > t.TakeoffSpeed * 0.85f) ? (Mathf.Clamp01(num5) * 10f) : 0f);
				p.Pitch = Mathf.MoveTowards(p.Pitch, num7, 8f * dt);
				Vector3 val = Quaternion.Euler(0f, p.Yaw, 0f) * Vector3.forward;
				p.Pos += val * p.Speed * dt;
				float num8 = GroundY(p, p.Pos + Vector3.up * 3f, 12f);
				if (!float.IsNegativeInfinity(num8))
				{
					p.Pos.y = Mathf.Max(num8, Mathf.Lerp(p.Pos.y, num8, 1f - Mathf.Exp(-15f * dt)));
				}
				else
				{
					p.Pos.y -= 9.81f * dt;
				}
				if (p.Speed >= t.TakeoffSpeed && p.Pitch > 4f)
				{
					p.Airborne = true;
					p.Pos.y += 0.05f;
					Log($"takeoff at {p.Speed:F0} m/s");
					Haptics.Pulse(Player.RightController, 0.2f, 0.5f);
				}
			}
			else
			{
				p.Pitch += num5 * t.PitchRate * dt;
				if (Mathf.Abs(num5) < 0.05f)
				{
					p.Pitch = Mathf.MoveTowards(p.Pitch, 0f, 6f * t.Level * dt);
				}
				p.Roll += num6 * t.RollRate * dt;
				if (Mathf.Abs(num6) < 0.05f)
				{
					p.Roll = Mathf.MoveTowards(p.Roll, 0f, 25f * t.Level * dt);
				}
				if (num3 < 1f)
				{
					p.Pitch = Mathf.MoveTowards(p.Pitch, -12f, (1f - num3) * 15f * dt);
				}
				p.Pitch = Mathf.Clamp(p.Pitch, 0f - t.MaxPitch, t.MaxPitch);
				p.Roll = Mathf.Clamp(p.Roll, 0f - t.MaxRoll, t.MaxRoll);
				p.Yaw += (562.07166f * Mathf.Tan(p.Roll * ((float)Math.PI / 180f)) / Mathf.Max(p.Speed, 15f) + num4 * 8f) * dt;
				p.Speed = Mathf.Clamp(p.Speed - Mathf.Sin(p.Pitch * ((float)Math.PI / 180f)) * 4f * dt, 0f, t.MaxSpeed * 1.2f);
				Vector3 val2 = Quaternion.Euler(0f - p.Pitch, p.Yaw, 0f) * Vector3.forward * p.Speed + Vector3.down * ((1f - num3) * 9f);
				p.Pos += val2 * dt;
				float num9 = GroundY(p, p.Pos + Vector3.up * 3f, 6f);
				if (!float.IsNegativeInfinity(num9) && p.Pos.y <= num9)
				{
					float num10 = 0f - val2.y;
					p.Pos.y = num9;
					p.Airborne = false;
					if (num10 < 7f && Mathf.Abs(p.Roll) < 25f && p.Pitch > -12f)
					{
						Log($"landed (sink {num10:F1} m/s, {p.Speed:F0} m/s)");
						Haptics.Pulse(Player.LeftController, 0.15f, 0.5f);
						Haptics.Pulse(Player.RightController, 0.15f, 0.5f);
					}
					else
					{
						p.Speed *= 0.2f;
						p.Throttle = 0f;
						Log($"hard landing (sink {num10:F1} m/s, roll {p.Roll:F0}, pitch {p.Pitch:F0})");
						NukeStrikeMod.Notify("Crash landing!", (NotificationType)1);
						Haptics.Pulse(Player.LeftController, 0.4f, 1f);
						Haptics.Pulse(Player.RightController, 0.4f, 1f);
					}
				}
			}
			Vector3 val3 = p.Pos - rb.position;
			if (((Vector3)(ref val3)).sqrMagnitude > 36f)
			{
				p.Pos = rb.position;
				p.Speed *= 0.3f;
				if (_bumpCooldown <= 0f)
				{
					_bumpCooldown = 2f;
					Log("blocked: hit something");
					NukeStrikeMod.Notify("Bump!", (NotificationType)1);
				}
			}
			Quaternion val4 = Quaternion.Euler(0f - p.Pitch, p.Yaw, 0f - p.Roll);
			if (rb.isKinematic)
			{
				p.KinVel = (p.Pos - rb.position) / dt;
				rb.MovePosition(p.Pos);
				rb.MoveRotation(val4);
			}
			else
			{
				rb.velocity = (p.Pos - rb.position) / dt;
				Quaternion val5 = val4 * Quaternion.Inverse(rb.rotation);
				float num11 = default(float);
				Vector3 val6 = default(Vector3);
				((Quaternion)(ref val5)).ToAngleAxis(ref num11, ref val6);
				if (num11 > 180f)
				{
					num11 -= 360f;
				}
				rb.angularVelocity = ((float.IsNaN(val6.x) || Mathf.Abs(num11) < 0.01f) ? Vector3.zero : (val6 * (num11 * ((float)Math.PI / 180f) / dt)));
			}
			p.SendTimer -= dt;
			if (!p.FusionSynced && p.SendTimer <= 0f && Net.InLobby)
			{
				p.SendTimer = 0.05f;
				Net.SendBomberPose(p.Pos, val4, rb.isKinematic ? p.KinVel : rb.velocity);
			}
		}

		public static void OnRemotePose(Vector3 pos, Quaternion rot, Vector3 vel)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			Plane plane = null;
			float num = 300f;
			foreach (Plane plane2 in Planes)
			{
				if (plane2 != _flying && !((Object)(object)plane2.Go == (Object)null))
				{
					float num2 = Vector3.Distance((plane2.NetAge < 2f) ? plane2.NetPos : plane2.Rb.position, pos);
					if (num2 < num)
					{
						num = num2;
						plane = plane2;
					}
				}
			}
			if (plane != null)
			{
				if (plane.NetAge >= 2f)
				{
					Log("following another player's bomber");
					plane.Rb.isKinematic = true;
				}
				plane.NetPos = pos;
				plane.NetRot = rot;
				plane.NetVel = vel;
				plane.NetAge = 0f;
			}
		}

		private static void FollowNet(Plane p, float dt)
		{
			//IL_0063: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)p.Go == (Object)null) && !(p.NetAge >= 2f))
			{
				p.NetAge += dt;
				if (p.NetAge >= 2f)
				{
					p.Rb.isKinematic = false;
					return;
				}
				float num = 1f - Mathf.Exp(-12f * dt);
				p.Rb.MovePosition(Vector3.Lerp(p.Rb.position, p.NetPos + p.NetVel * p.NetAge, num));
				p.Rb.MoveRotation(Quaternion.Slerp(p.Rb.rotation, p.NetRot, num));
			}
		}

		private static float Dead(float v)
		{
			if (!(Mathf.Abs(v) < 0.12f))
			{
				return (v - Mathf.Sign(v) * 0.12f) / 0.88f;
			}
			return 0f;
		}

		private static float GroundY(Plane p, Vector3 from, float range)
		{
			//IL_0021: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			float num = float.NegativeInfinity;
			Transform val = (((Object)(object)Player.RigManager != (Object)null) ? ((Component)Player.RigManager).transform : null);
			int num2 = Physics.RaycastNonAlloc(from, Vector3.down, Hits, range, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)Hits)[i];
				Transform transform = ((Component)((RaycastHit)(ref val2)).collider).transform;
				if (!transform.IsChildOf(p.Go.transform) && (!((Object)(object)val != (Object)null) || !transform.IsChildOf(val)) && (!((Object)(object)((RaycastHit)(ref val2)).rigidbody != (Object)null) || ((RaycastHit)(ref val2)).rigidbody.isKinematic) && !((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<RigManager>() != (Object)null) && ((RaycastHit)(ref val2)).point.y > num)
				{
					num = ((RaycastHit)(ref val2)).point.y;
				}
			}
			return num;
		}

		private static string Status()
		{
			return $"strikes active {NukeStrikeMod.ActiveStrikes}, bombs falling {Bombs.Count}, bombs waiting to spawn {PendingDrops.Count}, blast crates alive {Blasts.Count}";
		}

		private static void Drop(Plane p, string how)
		{
			if ((Object)(object)p.DoorL == (Object)null)
			{
				Release(p, how);
			}
			else if (!p.Airborne)
			{
				Log(how + ": on the ground, no drop");
				NukeStrikeMod.Notify("Take off first!", (NotificationType)0);
			}
			else if (!p.DropQueued)
			{
				if (_dropCooldown > 0f)
				{
					Log($"{how}: reloading ({_dropCooldown:F1} s left)");
					Haptics.Pulse(Player.RightController, 0.03f, 0.2f);
				}
				else if (Bombs.Count + PendingDrops.Count >= 4)
				{
					Log(how + ": " + 4 + " bombs already falling");
					NukeStrikeMod.Notify("Wait for a bomb to land", (NotificationType)0);
				}
				else
				{
					p.DropQueued = true;
					SetDoors(p, 1f, send: true);
					Log(how + ": bay doors opening");
				}
			}
		}

		private static void Release(Plane p, string how)
		{
			//IL_00e8: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if (!p.Airborne)
			{
				Log(how + ": on the ground, no drop");
				NukeStrikeMod.Notify("Take off first!", (NotificationType)0);
				return;
			}
			if (_dropCooldown > 0f)
			{
				Log($"{how}: reloading ({_dropCooldown:F1} s left)");
				Haptics.Pulse(Player.RightController, 0.03f, 0.2f);
				return;
			}
			if (Bombs.Count + PendingDrops.Count >= 4)
			{
				Log(how + ": " + 4 + " bombs already falling");
				NukeStrikeMod.Notify("Wait for a bomb to land", (NotificationType)0);
				return;
			}
			_dropCooldown = 2f;
			int num = ++_dropCount;
			Vector3 val = BayPoint(p);
			Quaternion rot = DropHeading(p);
			string text = DropBarcode(p.Speed);
			PendingDrop pendingDrop = new PendingDrop
			{
				N = num,
				At = Time.time
			};
			PendingDrops.Add(pendingDrop);
			pendingDrop.ViaFusion = Net.SpawnCrate(text, val, rot, effect: false);
			if (!pendingDrop.ViaFusion)
			{
				SpawnLocal(text, val, rot, $"drop #{num} bomb");
			}
			Log($"drop #{num} ({how}, {p.T.Name}): bomb {text.Substring(text.LastIndexOf('.') + 1)} requested at {val} ({p.Speed:F0} m/s, {(pendingDrop.ViaFusion ? "through Fusion" : "local")}); {Status()}");
			Haptics.Pulse(Player.RightController, 0.25f, 0.8f);
		}

		private static Vector3 BayPoint(Plane p)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			if (!((Object)(object)p.Release != (Object)null))
			{
				return (((Object)(object)p.BombBay != (Object)null) ? p.BombBay.position : p.Go.transform.position) - p.Go.transform.up * 2.6f;
			}
			return p.Release.position;
		}

		private static void SetDoors(Plane p, float target, bool send)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)p.DoorL == (Object)null) && p.DoorTarget != target)
			{
				p.DoorTarget = target;
				if (send && Net.InLobby)
				{
					Net.SendBomberDoors(p.Go.transform.position, target > 0.5f);
				}
			}
		}

		private static void UpdateDoors(Plane p)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p.DoorL == (Object)null || (Object)(object)p.Go == (Object)null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (p.Door != p.DoorTarget)
			{
				p.Door = Mathf.MoveTowards(p.Door, p.DoorTarget, 1.6f * deltaTime);
				float num = Mathf.SmoothStep(0f, 100f, p.Door);
				p.DoorL.localRotation = Quaternion.Euler(0f, 0f, 0f - num);
				if ((Object)(object)p.DoorR != (Object)null)
				{
					p.DoorR.localRotation = Quaternion.Euler(0f, 0f, num);
				}
			}
			if (p == _flying)
			{
				if (p.DropQueued && p.Door >= 0.98f)
				{
					p.DropQueued = false;
					Release(p, "bay");
					p.CloseAt = Time.time + 1.3f;
				}
				if (!p.DropQueued && p.DoorTarget > 0.5f && p.CloseAt > 0f && Time.time >= p.CloseAt)
				{
					p.CloseAt = 0f;
					SetDoors(p, 0f, send: true);
					Log("bay doors closing");
				}
			}
		}

		private static void UpdateButton(Plane p)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = p.ButtonCap.parent.position + p.ButtonCap.parent.up * 0.05f;
			float num = float.MaxValue;
			if ((Object)(object)Player.LeftHand != (Object)null)
			{
				num = Mathf.Min(num, Vector3.Distance(((Component)Player.LeftHand).transform.position, val));
			}
			if ((Object)(object)Player.RightHand != (Object)null)
			{
				num = Mathf.Min(num, Vector3.Distance(((Component)Player.RightHand).transform.position, val));
			}
			if (!p.ButtonHeld && num < 0.08f)
			{
				p.ButtonHeld = true;
				p.ButtonCap.localPosition = new Vector3(0f, -0.018f, 0f);
				Haptics.Pulse(Player.RightController, 0.08f, 0.9f);
				Drop(p, "NUKE button");
			}
			else if (p.ButtonHeld && num > 0.14f)
			{
				p.ButtonHeld = false;
				p.ButtonCap.localPosition = Vector3.zero;
			}
		}

		public static void OnRemoteDoors(Vector3 pos, bool open)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Plane plane = null;
			float num = 300f;
			foreach (Plane plane2 in Planes)
			{
				if (plane2 != _flying && !((Object)(object)plane2.Go == (Object)null) && !((Object)(object)plane2.DoorL == (Object)null))
				{
					float num2 = Vector3.Distance(plane2.Go.transform.position, pos);
					if (num2 < num)
					{
						num = num2;
						plane = plane2;
					}
				}
			}
			if (plane != null)
			{
				SetDoors(plane, open ? 1f : 0f, send: false);
			}
		}

		private static Quaternion DropHeading(Plane p)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Vector3 val = Vector3.ProjectOnPlane(p.Go.transform.forward, Vector3.up);
			return Quaternion.LookRotation((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.forward, Vector3.up);
		}

		private static string DropBarcode(float speed)
		{
			int num = DropBombSpeeds[0];
			int[] dropBombSpeeds = DropBombSpeeds;
			foreach (int num2 in dropBombSpeeds)
			{
				if (Mathf.Abs((float)num2 - speed) < Mathf.Abs((float)num - speed))
				{
					num = num2;
				}
			}
			string text = "callofike.NukeStrike.Spawnable.NukeStrikeBomb" + num;
			if (!Crates.Has(text))
			{
				return "callofike.NukeStrike.Spawnable.NukeStrikeFallingBomb";
			}
			return text;
		}

		private static float CrateSpeed(GameObject go)
		{
			string name = ((Object)go).name;
			int[] dropBombSpeeds = DropBombSpeeds;
			for (int i = 0; i < dropBombSpeeds.Length; i++)
			{
				int num = dropBombSpeeds[i];
				if (name.StartsWith("NukeStrikeBomb" + num))
				{
					return num;
				}
			}
			return 0f;
		}

		private static void IgnorePlanesAndBombs(GameObject go)
		{
			Il2CppArrayBase<Collider> componentsInChildren = go.GetComponentsInChildren<Collider>(true);
			foreach (Plane plane in Planes)
			{
				if (plane.Cols == null)
				{
					continue;
				}
				Collider[] cols = plane.Cols;
				foreach (Collider val in cols)
				{
					foreach (Collider item in componentsInChildren)
					{
						if ((Object)(object)item != (Object)null && (Object)(object)val != (Object)null)
						{
							Physics.IgnoreCollision(item, val, true);
						}
					}
				}
			}
			foreach (Bomb bomb in Bombs)
			{
				if (!((Object)(object)bomb.Go != (Object)null))
				{
					continue;
				}
				foreach (Collider componentsInChild in bomb.Go.GetComponentsInChildren<Collider>(true))
				{
					foreach (Collider item2 in componentsInChildren)
					{
						if ((Object)(object)item2 != (Object)null && (Object)(object)componentsInChild != (Object)null)
						{
							Physics.IgnoreCollision(item2, componentsInChild, true);
						}
					}
				}
			}
			foreach (GameObject otherBomb in OtherBombs)
			{
				if (!((Object)(object)otherBomb != (Object)null) || !((Object)(object)otherBomb != (Object)(object)go))
				{
					continue;
				}
				foreach (Collider componentsInChild2 in otherBomb.GetComponentsInChildren<Collider>(true))
				{
					foreach (Collider item3 in componentsInChildren)
					{
						if ((Object)(object)item3 != (Object)null && (Object)(object)componentsInChild2 != (Object)null)
						{
							Physics.IgnoreCollision(item3, componentsInChild2, true);
						}
					}
				}
			}
		}

		private static bool SpawnLocal(string barcode, Vector3 at, Quaternion rot, string what)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				HelperMethods.SpawnCrate(barcode, at, rot, Vector3.one, true, (Action<GameObject>)null, (Action<GameObject>)null);
				return true;
			}
			catch (Exception ex)
			{
				Log(what + ": local spawn failed: " + ex.Message);
				return false;
			}
		}

		private static void OnBombSpawned(GameObject go)
		{
			//IL_0094: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: 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)
			try
			{
				IgnorePlanesAndBombs(go);
			}
			catch
			{
			}
			if (_flying == null || PendingDrops.Count == 0)
			{
				OtherBombs.Add(go);
				return;
			}
			PendingDrop pendingDrop = PendingDrops[0];
			PendingDrops.RemoveAt(0);
			Plane flying = _flying;
			Rigidbody component = go.GetComponent<Rigidbody>();
			if ((Object)(object)component == (Object)null)
			{
				Log($"drop #{pendingDrop.N}: bomb crate has no Rigidbody (old pallet?)");
				return;
			}
			Vector3 val = (component.position = BayPoint(flying));
			go.transform.position = val;
			float num = CrateSpeed(go);
			if (num <= 0f)
			{
				component.velocity = flying.Rb.velocity;
			}
			component.angularVelocity = Vector3.zero;
			CapsuleCollider component2 = go.GetComponent<CapsuleCollider>();
			List<Bomb> bombs = Bombs;
			Bomb obj2 = new Bomb
			{
				Go = go,
				Rb = component,
				N = pendingDrop.N,
				LastPos = val,
				LastVel = component.velocity,
				Radius = (((Object)(object)component2 != (Object)null) ? component2.radius : 0.9f),
				Speed = num
			};
			Vector3 val3 = Vector3.ProjectOnPlane(flying.Go.transform.forward, Vector3.up);
			obj2.Dir = ((Vector3)(ref val3)).normalized;
			bombs.Add(obj2);
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(62, 5);
			defaultInterpolatedStringHandler.AppendLiteral("drop #");
			defaultInterpolatedStringHandler.AppendFormatted(pendingDrop.N);
			defaultInterpolatedStringHandler.AppendLiteral(": bomb crate appeared after ");
			defaultInterpolatedStringHandler.AppendFormatted(Time.time - pendingDrop.At, "F2");
			defaultInterpolatedStringHandler.AppendLiteral(" s (");
			defaultInterpolatedStringHandler.AppendFormatted(pendingDrop.LocalRetry ? "local retry" : (pendingDrop.ViaFusion ? "Fusion" : "local"));
			defaultInterpolatedStringHandler.AppendLiteral("), falling from ");
			defaultInterpolatedStringHandler.AppendFormatted<Vector3>(val);
			defaultInterpolatedStringHandler.AppendLiteral(" at ");
			val3 = component.velocity;
			defaultInterpolatedStringHandler.AppendFormatted(((Vector3)(ref val3)).magnitude, "F0");
			defaultInterpolatedStringHandler.AppendLiteral(" m/s");
			Log(defaultInterpolatedStringHandler.ToStringAndClear());
		}

		private static bool UpdateBomb(Bomb b, float dt)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: 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_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: 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_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)b.Go == (Object)null || !b.Go.activeInHierarchy)
			{
				Log($"drop #{b.N}: bomb vanished before it landed (despawned or destroyed by something else)");
				return false;
			}
			b.Age += dt;
			Vector3 position = b.Rb.position;
			Vector3 val = b.Rb.velocity;
			if (b.Speed > 0f)
			{
				if (b.Age > 0.05f && b.Age < 0.2f)
				{
					Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up);
					if (((Vector3)(ref val2)).magnitude < b.Speed * 0.5f)
					{
						val = (b.Rb.velocity = b.Go.transform.forward * b.Speed + Vector3.up * val.y);
						Log($"drop #{b.N}: the crate's own push didn't happen: pushed it at {b.Speed} m/s");
					}
				}
			}
			else if (((Vector3)(ref val)).sqrMagnitude > 1f)
			{
				b.Rb.MoveRotation(Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up));
			}
			if (position.y < -1500f || b.Age > 60f)
			{
				Log($"drop #{b.N}: bomb {((position.y < -1500f) ? "fell out of the world" : $"still falling after {60f:F0} s")} at {position}: removed, no explosion");
				Object.Destroy((Object)(object)b.Go);
				return false;
			}
			string how;
			Vector3? val4 = BombImpact(b.Go, b.LastPos, position, val, b.Radius, dt, NukeStrikeMod.AirburstHeight, out how);
			if (!val4.HasValue && b.Age > 1f && ((Vector3)(ref val)).sqrMagnitude < 9f)
			{
				val4 = position;
				how = "came to rest";
			}
			b.LastPos = position;
			b.LastVel = val;
			if (!val4.HasValue)
			{
				return true;
			}
			Vector3 value = val4.Value;
			if (!how.StartsWith("airburst"))
			{
				float num = Ground(b.Go, value + Vector3.up * 4f);
				if (!float.IsNegativeInfinity(num) && value.y - num < 8f)
				{
					value.y = num;
				}
			}
			Log($"drop #{b.N}: bomb hit ({how}) at {val4.Value} after {b.Age:F2} s; blast at {value}");
			Object.Destroy((Object)(object)b.Go);
			Log($"drop #{b.N}: bomb removed");
			Detonate(b.N, value, b.Dir);
			return false;
		}

		private static Vector3? BombImpact(GameObject bomb, Vector3 last, Vector3 pos, Vector3 vel, float radius, float dt, float airburst, out string how)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			how = null;
			Vector3 val = pos - last;
			float magnitude = ((Vector3)(ref val)).magnitude;
			Vector3 val2 = ((magnitude > 0.001f) ? (val / magnitude) : ((((Vector3)(ref vel)).sqrMagnitude > 0.01f) ? ((Vector3)(ref vel)).normalized : Vector3.down));
			float num = magnitude + ((Vector3)(ref vel)).magnitude * dt + 0.3f;
			Vector3? result = null;
			float num2 = float.MaxValue;
			int num3 = Physics.SphereCastNonAlloc(last, radius, val2, Hits, num, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < num3; i++)
			{
				RaycastHit val3 = ((Il2CppArrayBase<RaycastHit>)(object)Hits)[i];
				if (Solid(((RaycastHit)(ref val3)).collider, bomb))
				{
					Vector3 value = ((((RaycastHit)(ref val3)).distance == 0f && ((RaycastHit)(ref val3)).point == Vector3.zero) ? ((RaycastHit)(ref val3)).collider.ClosestPoint(last) : ((RaycastHit)(ref val3)).point);
					if (((RaycastHit)(ref val3)).distance < num2)
					{
						num2 = ((RaycastHit)(ref val3)).distance;
						result = value;
					}
				}
			}
			if (result.HasValue)
			{
				how = "contact";
				return result;
			}
			float num4 = Ground(bomb, new Vector3(pos.x, Mathf.Max(last.y, pos.y) + 2f, pos.z));
			if (!float.IsNegativeInfinity(num4))
			{
				if (pos.y - radius <= num4 + 0.05f)
				{
					how = "ground check";
					return new Vector3(pos.x, num4, pos.z);
				}
				if (airburst > 0f && pos.y - num4 <= airburst)
				{
					how = $"airburst {airburst:F0} m";
					return pos;
				}
			}
			return null;
		}

		private static bool Solid(Collider c, GameObject bomb)
		{
			if ((Object)(object)c == (Object)null || c.isTrigger || ((Component)c).transform.IsChildOf(bomb.transform))
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<RigManager>() != (Object)null)
			{
				return false;
			}
			Rigidbody attachedRigidbody = c.attachedRigidbody;
			if ((Object)(object)attachedRigidbody == (Object)null)
			{
				return true;
			}
			string name = ((Object)((Component)attachedRigidbody).gameObject).name;
			if (name.StartsWith("NukeStrikeBomb") || name.StartsWith("NukeStrikeFallingBomb") || name.StartsWith("NukeBomber") || name.StartsWith("SpiritBomber"))
			{
				return false;
			}
			if (!attachedRigidbody.isKinematic)
			{
				return attachedRigidbody.mass >= 1000f;
			}
			return true;
		}

		private static float Ground(GameObject bomb, Vector3 from)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			float num = float.NegativeInfinity;
			int num2 = Physics.RaycastNonAlloc(from, Vector3.down, Hits, 6000f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)Hits)[i];
				if (Solid(((RaycastHit)(ref val)).collider, bomb) && ((RaycastHit)(ref val)).point.y > num)
				{
					num = ((RaycastHit)(ref val)).point.y;
				}
			}
			return num;
		}

		private static void Detonate(int n, Vector3 at, Vector3 dir)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			float num = NukeStrikeMod.BlastRadius();
			string text = ((num < 52f) ? "callofike.NukeStrike.Spawnable.NukeStrikeBlastLarge" : "callofike.NukeStrike.Spawnable.NukeStrikeBlastHuge");
			Blast blast = new Blast
			{
				N = n,
				Barcode = text,
				Pos = at,
				RequestedAt = Time.time
			};
			Blasts.Add(blast);
			blast.ViaFusion = Net.SpawnCrate(text, at, Quaternion.identity, effect: false);
			bool flag = blast.ViaFusion || SpawnLocal(text, at, Quaternion.identity, $"drop #{n} blast");
			if (!flag)
			{
				Blasts.Remove(blast);
			}
			NukeStrikeMod.StartBomberBlast(at, dir, num, flag);
			Log($"drop #{n}: blast {text.Substring(text.LastIndexOf('.') + 1)} requested at {at} (R {num} m, {(blast.ViaFusion ? "through Fusion" : (flag ? "local" : "no crate: the mod draws it"))}); {Status()}");
		}

		private static void OnBlastSpawned(GameObject go)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = go.transform.position;
			Blast blast = null;
			foreach (Blast blast2 in Blasts)
			{
				if ((Object)(object)blast2.Go == (Object)null && Vector3.Distance(blast2.Pos, position) < 5f)
				{
					blast = blast2;
					break;
				}
			}
			if (blast != null)
			{
				blast.Go = go;
				blast.SeenAt = Time.time;
				Log($"drop #{blast.N}: blast crate appeared at {position} after {blast.SeenAt - blast.RequestedAt:F2} s ({(blast.LocalRetry ? "local retry" : (blast.ViaFusion ? "Fusion" : "local"))}), active {go.activeInHierarchy}");
			}
		}

		private static void UpdateDrops()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			for (int num = PendingDrops.Count - 1; num >= 0; num--)
			{
				PendingDrop pendingDrop = PendingDrops[num];
				if (!(Time.time - pendingDrop.At < 2.5f))
				{
					if (pendingDrop.ViaFusion && !pendingDrop.LocalRetry && _flying != null)
					{
						pendingDrop.LocalRetry = true;
						pendingDrop.At = Time.time;
						Log($"drop #{pendingDrop.N}: bomb crate didn't arrive through Fusion in {2.5f} s: spawning it locally");
						SpawnLocal("callofike.NukeStrike.Spawnable.NukeStrikeFallingBomb", BayPoint(_flying), Quaternion.LookRotation(_flying.Go.transform.forward, Vector3.up), $"drop #{pendingDrop.N} bomb");
					}
					else
					{
						PendingDrops.RemoveAt(num);
						Log($"drop #{pendingDrop.N}: bomb crate never appeared: drop cancelled");
					}
				}
			}
			for (int num2 = Blasts.Count - 1; num2 >= 0; num2--)
			{
				Blast blast = Blasts[num2];
				if (blast.SeenAt > 0f)
				{
					if ((Object)(object)blast.Go == (Object)null || !blast.Go.activeInHierarchy)
					{
						Blasts.RemoveAt(num2);
						Log($"drop #{blast.N}: blast crate gone after {Time.time - blast.SeenAt:F0} s (cleaned up)");
					}
				}
				else if (!(Time.time - blast.RequestedAt < 2.5f))
				{
					if (blast.ViaFusion && !blast.LocalRetry)
					{
						blast.LocalRetry = true;
						blast.RequestedAt = Time.time;
						Log($"drop #{blast.N}: blast crate didn't arrive through Fusion in {2.5f} s: spawning it locally");
						SpawnLocal(blast.Barcode, blast.Pos, Quaternion.identity, $"drop #{blast.N} blast");
					}
					else
					{
						Blasts.RemoveAt(num2);
						Log($"drop #{blast.N}: blast crate never appeared (is the pallet 1.3.2+ installed?)");
					}
				}
			}
			OtherBombs.RemoveAll((GameObject g) => (Object)(object)g == (Object)null || !g.activeInHierarchy);
		}

		public static void RemoteBlast(Vector3 at)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject otherBomb in OtherBombs)
			{
				if ((Object)(object)otherBomb != (Object)null && Vector3.Distance(otherBomb.transform.position, at) < 400f)
				{
					Object.Destroy((Object)(object)otherBomb);
				}
			}
			OtherBombs.RemoveAll((GameObject g) => (Object)(object)g == (Object)null);
		}
	}
	internal static class Crates
	{
		private const string Prefix = "callofike.NukeStrike.Spawnable.";

		private static readonly string[] Events = new string[4] { "NukeStrikeEventSmall", "NukeStrikeEvent", "NukeStrikeEventLarge", "NukeStrikeEventHuge" };

		private static readonly string[] Booms = new string[6] { "NukeBoomSonicBoom", "NukeBoomCinematic", "NukeBoomDeepRumble", "NukeBoomSharpBlast", "NukeBoomDistantThunder", "NukeBoomEarthquake" };

		public static string EventFor(float radius)
		{
			return "callofike.NukeStrike.Spawnable." + Events[(!(radius < 13f)) ? ((radius < 26f) ? 1 : ((radius < 52f) ? 2 : 3)) : 0];
		}

		public static string BoomFor(int sound)
		{
			return "callofike.NukeStrike.Spawnable." + Booms[Mathf.Clamp(sound, 0, Booms.Length - 1)];
		}

		public static bool Installed(StrikeInfo info)
		{
			if (Has(EventFor(info.Radius)))
			{
				return Has(BoomFor(info.Sound));
			}
			return false;
		}

		internal static bool Has(string barcode)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			try
			{
				AssetWarehouse instance = AssetWarehouse.Instance;
				return instance != null && instance.HasCrate(new Barcode(barcode));
			}
			catch
			{
				return false;
			}
		}

		public static int DestroyAll()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			try
			{
				foreach (Poolee item in Resources.FindObjectsOfTypeAll<Poolee>())
				{
					if ((Object)(object)item == (Object)null)
					{
						continue;
					}
					GameObject gameObject = ((Component)item).gameObject;
					if ((Object)(object)gameObject == (Object)null)
					{
						continue;
					}
					Scene scene = gameObject.scene;
					if (((Scene)(ref scene)).IsValid() && gameObject.activeInHierarchy)
					{
						string name = ((Object)gameObject).name;
						if (name.StartsWith("NukeStrikeEvent") || name.StartsWith("NukeStrikeDetonation") || name.StartsWith("NukeBoom") || name.StartsWith("NukeStrikeBlast") || name.StartsWith("NukeStrikeFallingBomb") || name.StartsWith("NukeStrikeBomb"))
						{
							Object.Destroy((Object)(object)gameObject);
							num++;
						}
					}
				}
			}
			catch (Exception ex)
			{
				NukeStrikeMod instance = NukeStrikeMod.Instance;
				if (instance != null)
				{
					((MelonBase)instance).LoggerInstance.Warning("Could not remove the NukeStrike crates: " + ex.Message);
				}
			}
			return num;
		}

		public static bool Spawn(StrikeInfo info)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			string text = EventFor(info.Radius);
			string text2 = BoomFor(info.Sound);
			Quaternion val = Quaternion.LookRotation(info.Dir, Vector3.up);
			if (Net.InLobby)
			{
				return Net.SpawnCrates(text, text2, info.Target, val);
			}
			try
			{
				HelperMethods.SpawnCrate(text, info.Target, val, Vector3.one, true, (Action<GameObject>)null, (Action<GameObject>)null);
				HelperMethods.SpawnCrate(text2, info.Target, Quaternion.identity, Vector3.one, true, (Action<GameObject>)null, (Action<GameObject>)null);
				return true;
			}
			catch (Exception ex)
			{
				NukeStrikeMod instance = NukeStrikeMod.Instance;
				if (instance != null)
				{
					((MelonBase)instance).LoggerInstance.Warning("Could not spawn the NukeStrike crates; drawing it locally: " + ex.Message);
				}
				return false;
			}
		}
	}
	internal static class Diag
	{
		private static bool Ours(string n)
		{
			if (n != null)
			{
				if (!n.StartsWith("nuke_"))
				{
					return n.StartsWith("NukeStrike_");
				}
				return true;
			}
			return false;
		}

		public static void Report(string when, int activeStrikes)
		{
			if (NukeStrikeMod.PrefDebugLog == null || !NukeStrikeMod.PrefDebugLog.Value)
			{
				return;
			}
			try
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				int num5 = 0;
				List<string> list = new List<string>();
				foreach (Material item in Resources.FindObjectsOfTypeAll<Material>())
				{
					if (!((Object)(object)item == (Object)null) && Ours(((Object)item).name))
					{
						num++;
						Shader shader = item.shader;
						if ((Object)(object)shader == (Object)null || !shader.isSupported || ((Object)shader).name == "Hidden/InternalErrorShader")
						{
							list.Add(((Object)item).name + " (" + (((Object)(object)shader == (Object)null) ? "no shader" : ((Object)shader).name) + ")");
						}
					}
				}
				foreach (Texture2D item2 in Resources.FindObjectsOfTypeAll<Texture2D>())
				{
					if ((Object)(object)item2 != (Object)null && Ours(((Object)item2).name))
					{
						num2++;
					}
				}
				foreach (AudioClip item3 in Resources.FindObjectsOfTypeAll<AudioClip>())
				{
					if ((Object)(object)item3 != (Object)null && Ours(((Object)item3).name))
					{
						num3++;
					}
				}
				foreach (GameObject item4 in Resources.FindObjectsOfTypeAll<GameObject>())
				{
					if ((Object)(object)item4 != (Object)null && (Object)(object)item4.transform.parent == (Object)null && Ours(((Object)item4).name))
					{
						num4++;
					}
				}
				foreach (ParticleSystem item5 in Resources.FindObjectsOfTypeAll<ParticleSystem>())
				{
					if ((Object)(object)item5 != (Object)null && Ours(((Object)((Component)item5).transform.root).name))
					{
						num5++;
					}
				}
				MelonLogger.Msg($"[NukeStrike] [debug] {when}: strikes={activeStrikes} objects={num4} particleSystems={num5} materials={num} textures={num2} sounds={num3}");
				if (list.Count > 0)
				{
					MelonLogger.Warning("[NukeStrike] [debug] materials with a missing shader (these draw PURPLE): " + string.Join(", ", list));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[NukeStrike] [debug] report failed: " + ex.Message);
			}
		}
	}
	internal class Explosion
	{
		private enum Kind
		{
			Fireball,
			Stem,
			Surge,
			Cap
		}

		private class Puff
		{
			public Transform T;

			public Material M;

			public Kind Kind;

			public Vector3 Offset;

			public float Size;

			public float Heat;

			public float Delay;

			public float Height01;

			public float Spin;
		}

		private const float Lifetime = 70f;

		private readonly FxCloud _fx;

		private const float SoundSpeed = 343f;

		private readonly Vector3 _pos;

		private readonly float _r;

		private float _t;

		private readonly GameObject _root;

		private readonly List<Puff> _puffs = new List<Puff>();

		private readonly Light _light;

		private readonly GameObject _ring;

		private readonly Material _ringMat;

		private readonly GameObject _flash;

		private readonly Material _flashMat;

		private readonly float _shockSpeed;

		private readonly float _shockMax;

		private float _shockRadius;

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

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

		private bool _playerHit;

		private bool _rumbled;

		private readonly float _playerDist;

		private readonly bool _push;

		private readonly bool _kill;

		private readonly bool _affectWorld;

		private const float OwnershipWait = 0.6f;

		private readonly List<(Rigidbody rb, float since)> _waiting = new List<(Rigidbody, float)>();

		private int _seenColliders;

		private int _bodies;

		private int _pushedCount;

		private int _npcsKilled;

		private int _npcsHurt;

		private int _ownershipRequests;

		private int _otherPlayers;

		private bool _reported;

		public Explosion(Vector3 pos, float r, int seed, int sound, bool push, bool kill, bool visuals = true, bool affectWorld = true)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Expected O, but got Unknown
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			_pos = pos;
			_r = r;
			_push = push;
			_kill = kill;
			_affectWorld = affectWorld;
			_shockMax = r * 9f;
			_shockSpeed = Mathf.Max(25f, r * 2.2f);
			_playerDist = (((Object)(object)Player.Head != (Object)null) ? Vector3.Distance(Player.Head.position, pos) : 9999f);
			_root = new GameObject("NukeStrike_Explosion");
			_root.transform.position = pos;
			Random rng = new Random(seed);
			if (!visuals)
			{
				return;
			}
			if (ParticleFx.Init())
			{
				try
				{
					_fx = new FxCloud(_root.transform, r, _shockSpeed, _shockMax, seed ^ 0x5F3759DF);
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("[NukeStrike] Particle explosion failed, using simple explosion: " + ex);
					_fx = null;
				}
			}
			try
			{
				MelonLogger.Msg("[NukeStrike] [debug] blast shaders: " + ((_fx != null) ? _fx.DescribeShaders() : "simple explosion (no particles)"));
			}
			catch
			{
			}
			if (_fx == null)
			{
				for (int i = 0; i < 16; i++)
				{
					Add(Kind.Fireball, RandDir(), Rand(0.55f, 0.85f), Rand(2.5f, 4.5f), Rand(0f, 0.08f));
				}
				for (int j = 0; j < 10; j++)
				{
					float num = (float)j / 10f * (float)Math.PI * 2f;
					Add(Kind.Cap, new Vector3(Mathf.Cos(num), Rand(-0.2f, 0.2f), Mathf.Sin(num)), Rand(0.6f, 0.8f), Rand(2f, 3.5f), Rand(0.2f, 0.6f));
				}
				for (int k = 0; k < 12; k++)
				{
					Add(Kind.Stem, new Vector3(Rand(-0.25f, 0.25f), 0f, Rand(-0.25f, 0.25f)), Rand(0.3f, 0.45f), Rand(1.5f, 3f), 0f, ((float)k + 0.5f) / 12f);
				}
				for (int l = 0; l < 18; l++)
				{
					float num2 = (float)l / 18f * (float)Math.PI * 2f + Rand(-0.1f, 0.1f);
					Add(Kind.Surge, new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)), Rand(0.35f, 0.55f), Rand(0.6f, 1.2f), Rand(0.3f, 0.8f));
				}
				_flashMat = Visuals.Glow(Color.white, 40f);
				_flash = Visuals.Prim((PrimitiveType)0, "flash", _root.transform, Vector3.zero, Vector3.zero, _flashMat, null, shadows: false);
				_ringMat = Visuals.Glow(new Color(1f, 0.95f, 0.85f), 3f);
				_ring = Visuals.Prim((PrimitiveType)2, "shockring", _root.transform, Vector3.up * 0.3f, Vector3.zero, _ringMat, null, shadows: false);
			}
			GameObject val = new GameObject("light");
			val.transform.SetParent(_root.transform, false);
			val.transform.localPosition = Vector3.up * r;
			_light = val.AddComponent<Light>();
			_light.type = (LightType)2;
			_light.range = r * 12f;
			_light.color = new Color(1f, 0.85f, 0.6f);
			_light.intensity = 0f;
			_light.shadows = (LightShadows)0;
			float num3 = Mathf.Min(_playerDist / 343f, 3f);
			float volume = Mathf.Clamp(1.15f - _playerDist / (r * 60f), 0.45f, 1f);
			AudioClip clip = Synth.BoomFor(sound);
			Synth.PlayBig(clip, pos, volume, num3, 0.3f);
			Synth.Source(_root, clip, 0.6f, Mathf.Max(40f, r * 4f), 8000f, loop: false, 0f).PlayDelayed(num3);
			void Add(Kind kind, Vector3 off, float size, float heat, float delay, float h01 = 0f)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				Material val2 = Visuals.Glow(Color.white, 10f);
				GameObject val3 = Visuals.Prim((PrimitiveType)0, kind.ToString(), _root.transform, Vector3.zero, Vector3.zero, val2, Quaternion.Euler(Rand(0f, 360f), Rand(0f, 360f), Rand(0f, 360f)), shadows: false);
				_puffs.Add(new Puff
				{
					T = val3.transform,
					M = (val2 ?? ((Renderer)val3.GetComponent<MeshRenderer>()).material),
					Kind = kind,
					Offset = off,
					Size = size,
					Heat = heat,
					Delay = delay,
					Height01 = h01,
					Spin = Rand(-20f, 20f)
				});
			}
			float Rand(float a, float b)
			{
				return a + (float)rng.NextDouble() * (b - a);
			}
			Vector3 RandDir()
			{
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				Vector3 result = default(Vector3);
				do
				{
					((Vector3)(ref result))..ctor(Rand(-1f, 1f), Rand(-1f, 1f), Rand(-1f, 1f));
				}
				while (((Vector3)(ref result)).sqrMagnitude > 1f || ((Vector3)(ref result)).sqrMagnitude < 0.05f);
				return result;
			}
		}

		public bool Update(float dt)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_01e6: 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_035f: 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 t