Decompiled source of OrbitalStrike v1.0.0

Mods/OrbitalStrike.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
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.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppUltEvents;
using LabFusion.Entities;
using LabFusion.Marrow.Integration;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using LabFusion.Senders;
using LabFusion.Voice;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using OrbitalStrike;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(OrbitalMod), "OrbitalStrike", "1.0.0", "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 OrbitalStrike
{
	internal sealed class Blast
	{
		private const float OwnershipWait = 0.6f;

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

		private readonly Vector3 _pos;

		private readonly float _r;

		private readonly float _speed;

		private readonly float _max;

		private readonly float _killR;

		private readonly float _hurtR;

		private readonly float _playerDist;

		private readonly bool _world;

		private float _t;

		private float _radius;

		private bool _playerHit;

		private bool _rumbled;

		private bool _reported;

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

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

		private readonly HashSet<byte> _players = new HashSet<byte>();

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

		private int _bodies;

		private int _thrown;

		private int _killed;

		private int _hurt;

		private int _otherHit;

		private int _otherBlocked;

		private Blast(Vector3 pos, float r, bool mine)
		{
			//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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			_pos = pos;
			_r = r;
			_speed = Mathf.Max(25f, r * 2.2f);
			_max = r * 9f;
			_killR = r * 1.6f;
			_hurtR = r * 3.5f;
			_playerDist = (((Object)(object)Player.Head != (Object)null) ? Vector3.Distance(Player.Head.position, pos) : 9999f);
			_world = mine;
		}

		public static void Start(Vector3 pos, float r, bool mine)
		{
			//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_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_0060: 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)
			foreach (Blast item in Live)
			{
				if (item._t < 3f)
				{
					Vector3 val = item._pos - pos;
					if (((Vector3)(ref val)).sqrMagnitude < 400f)
					{
						return;
					}
				}
			}
			Live.Add(new Blast(pos, r, mine));
			MelonLogger.Msg($"[OrbitalStrike] warhead at {pos} (R {r} m), {(mine ? "fired by me: props, NPCs and other players here" : "fired by another player")}");
		}

		public static void Clear()
		{
			Live.Clear();
		}

		public static void UpdateAll(float dt)
		{
			for (int num = Live.Count - 1; num >= 0; num--)
			{
				bool flag;
				try
				{
					flag = Live[num].Step(dt);
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("[OrbitalStrike] stopped a shockwave: " + ex.Message);
					flag = false;
				}
				if (!flag)
				{
					Live.RemoveAt(num);
				}
			}
		}

		private bool Step(float dt)
		{
			//IL_0048: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			_t += dt;
			_radius = Mathf.Min(_radius + _speed * dt, _max);
			if (!_playerHit && (Object)(object)Player.Head != (Object)null)
			{
				float num = Vector3.Distance(Player.Head.position, _pos);
				if (num <= _radius)
				{
					_playerHit = true;
					HitPlayer(num);
					float num2 = Mathf.Clamp01(1.15f - num / _max);
					if (num2 > 0.05f)
					{
						BlastSound.Play(_pos, 0.35f + 0.65f * num2);
					}
				}
			}
			if (!_rumbled && _playerDist <= _radius + 1f)
			{
				_rumbled = true;
				float amplitude = Mathf.Clamp01(1.2f - _playerDist / _max);
				Rumble(Player.LeftController, amplitude);
				Rumble(Player.RightController, amplitude);
			}
			if (_world && OrbitalMod.PrefBlastHurtOthers.Value && BlastNet.InLobby)
			{
				BlastNet.HurtPlayers(_pos, Mathf.Min(_radius, _hurtR), _killR, _hurtR, OrbitalMod.PrefDamage.Value / 100f, _players, ref _otherHit, ref _otherBlocked);
			}
			bool value = OrbitalMod.PrefBlastPushObjects.Value;
			bool value2 = OrbitalMod.PrefBlastKillNpcs.Value;
			bool value3 = OrbitalMod.PrefBlastPushMe.Value;
			for (int num3 = _waiting.Count - 1; num3 >= 0; num3--)
			{
				var (val, num4) = _waiting[num3];
				if ((Object)(object)val == (Object)null)
				{
					_waiting.RemoveAt(num3);
				}
				else if (BlastNet.ShouldAffect(val) || _t - num4 > 0.6f)
				{
					_waiting.RemoveAt(num3);
					Affect(val, value2, value);
				}
			}
			if (value || value2 || value3)
			{
				foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(_pos, _radius, -1, (QueryTriggerInteraction)1))
				{
					if ((Object)(object)item == (Object)null)
					{
						continue;
					}
					Rigidbody attachedRigidbody = item.attachedRigidbody;
					if ((Object)(object)attachedRigidbody == (Object)null || !_pushed.Add(((Object)attachedRigidbody).GetInstanceID()))
					{
						continue;
					}
					_bodies++;
					if (World.IsOurs(((Component)attachedRigidbody).transform))
					{
						continue;
					}
					RigManager val2 = null;
					try
					{
						val2 = ((Component)attachedRigidbody).GetComponentInParent<RigManager>();
					}
					catch
					{
					}
					if ((Object)(object)val2 != (Object)null)
					{
						if ((Object)(object)val2 == (Object)(object)Player.RigManager && value3 && Trucks.Mine == null)
						{
							Affect(attachedRigidbody, kill: false, push: true);
						}
					}
					else if (_world && (value || value2))
					{
						if (BlastNet.InLobby && BlastNet.TakeOwnership(attachedRigidbody))
						{
							_waiting.Add((attachedRigidbody, _t));
						}
						else
						{
							Affect(attachedRigidbody, value2, value);
						}
					}
				}
			}
			if (_radius < _max || _waiting.Count > 0)
			{
				return true;
			}
			if (!_reported)
			{
				_reported = true;
				MelonLogger.Msg($"[OrbitalStrike] shockwave done, R {_r} m: {_bodies} bodies, {_thrown} thrown, {_killed} NPCs killed, {_hurt} hurt, {_otherHit} other players hurt, {_otherBlocked} protected by the lobby");
			}
			return false;
		}

		private static void Rumble(BaseController c, float amplitude)
		{
			if ((Object)(object)c == (Object)null)
			{
				return;
			}
			try
			{
				c.HapticAction(0f, 1.2f, 80f, Mathf.Clamp01(amplitude));
			}
			catch
			{
			}
		}

		private void Affect(Rigidbody rb, bool kill, bool push)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rb == (Object)null)
			{
				return;
			}
			Vector3 val = rb.worldCenterOfMass - _pos;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (kill)
			{
				AIBrain val2 = FindBrain(rb);
				if ((Object)(object)val2 != (Object)null && _damaged.Add(((Object)val2).GetInstanceID()) && magnitude < _hurtR)
				{
					float share = ShareAt(magnitude);
					if (NpcKill.Hit(val2, share, "Warhead"))
					{
						_killed++;
					}
					else
					{
						_hurt++;
					}
				}
			}
			if (push && !rb.isKinematic)
			{
				float num = Mathf.Clamp01(1f - magnitude / _max);
				num *= num;
				Vector3 val3 = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.up) + Vector3.up * 0.35f;
				rb.AddForce(((Vector3)(ref val3)).normalized * (45f * num), (ForceMode)2);
				rb.AddTorque(Random.insideUnitSphere * (6f * num), (ForceMode)2);
				_thrown++;
			}
		}

		private float ShareAt(float d)
		{
			return ((d < _killR) ? 1f : Mathf.Lerp(1f, 0.05f, (d - _killR) / (_hurtR - _killR))) * OrbitalMod.PrefDamage.Value / 100f;
		}

		internal static AIBrain FindBrain(Rigidbody rb)
		{
			try
			{
				AIBrain componentInParent = ((Component)rb).GetComponentInParent<AIBrain>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
				MarrowBody component = ((Component)rb).GetComponent<MarrowBody>();
				MarrowEntity val = (((Object)(object)component != (Object)null) ? component.Entity : null);
				return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<AIBrain>() : null;
			}
			catch
			{
				return null;
			}
		}

		private void HitPlayer(float d)
		{
			if (!_world || !OrbitalMod.PrefBlastHurtMe.Value || d > _hurtR)
			{
				return;
			}
			try
			{
				RigManager rigManager = Player.RigManager;
				if (!((Object)(object)rigManager == (Object)null) && !((Object)(object)rigManager.health == (Object)null))
				{
					Player_Health val = ((Il2CppObjectBase)rigManager.health).TryCast<Player_Health>();
					if (!((Object)(object)val == (Object)null))
					{
						float num = ShareAt(d);
						float num2 = ((num >= 1f) ? 1000f : (((Health)val).max_Health * num));
						((Health)val).TAKEDAMAGE(num2);
						MelonLogger.Msg($"[OrbitalStrike] Warhead hit: me at {d:0} m, {num2:0} damage");
					}
				}
			}
			catch
			{
			}
		}
	}
	internal static class BlastNet
	{
		public static bool InLobby => TruckNet.InLobby;

		public static bool IsHost
		{
			get
			{
				if (!InLobby)
				{
					return false;
				}
				try
				{
					return Host();
				}
				catch
				{
					return false;
				}
			}
		}

		public static bool ShouldAffect(Rigidbody rb)
		{
			if (!InLobby)
			{
				return true;
			}
			try
			{
				return Should(rb);
			}
			catch
			{
				return true;
			}
		}

		public static bool TakeOwnership(Rigidbody rb)
		{
			if (!InLobby)
			{
				return false;
			}
			try
			{
				return Take(rb);
			}
			catch
			{
				return false;
			}
		}

		public static void HurtPlayers(Vector3 pos, float waveR, float killR, float hurtR, float scale, HashSet<byte> done, ref int hit, ref int blocked)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Hurt(pos, waveR, killR, hurtR, scale, done, ref hit, ref blocked);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] could not damage other players: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool Host()
		{
			return NetworkInfo.IsHost;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool Should(Rigidbody rb)
		{
			MarrowBody component = ((Component)rb).GetComponent<MarrowBody>();
			MarrowEntity val = (((Object)(object)component != (Object)null) ? component.Entity : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			NetworkEntity val2 = default(NetworkEntity);
			if (!IMarrowEntityExtender.Cache.TryGet(val, ref val2) || val2 == null)
			{
				return true;
			}
			if (!val2.HasOwner)
			{
				return NetworkInfo.IsHost;
			}
			return val2.IsOwner;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool Take(Rigidbody rb)
		{
			MarrowBody component = ((Component)rb).GetComponent<MarrowBody>();
			MarrowEntity val = (((Object)(object)component != (Object)null) ? component.Entity : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			NetworkEntity val2 = default(NetworkEntity);
			if (!IMarrowEntityExtender.Cache.TryGet(val, ref val2) || val2 == null)
			{
				return false;
			}
			if (val2.IsOwner)
			{
				return false;
			}
			NetworkEntityManager.TakeOwnership(val2);
			return true;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void Hurt(Vector3 pos, float waveR, float killR, float hurtR, float scale, HashSet<byte> done, ref int hit, ref int blocked)
		{
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_0179: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			foreach (NetworkPlayer item in new List<NetworkPlayer>(NetworkPlayer.Players))
			{
				if (item == null || item.PlayerID == null || !item.PlayerID.IsValid || item.PlayerID.IsMe || !item.HasRig)
				{
					continue;
				}
				byte smallID = item.PlayerID.SmallID;
				if (done.Contains(smallID))
				{
					continue;
				}
				Transform head = item.RigRefs.Head;
				if ((Object)(object)head == (Object)null)
				{
					continue;
				}
				float num = Vector3.Distance(head.position, pos);
				if (num > waveR)
				{
					continue;
				}
				done.Add(smallID);
				if (num > hurtR)
				{
					continue;
				}
				if (!NetworkCombatManager.CanAttack(item))
				{
					blocked++;
					continue;
				}
				float num2 = 0f;
				try
				{
					if ((Object)(object)item.RigRefs.Health != (Object)null)
					{
						num2 = ((Health)item.RigRefs.Health).max_Health;
					}
				}
				catch
				{
				}
				if (num2 <= 0f)
				{
					num2 = 100f;
				}
				float num3 = ((num < killR) ? 1f : Mathf.Lerp(1f, 0.05f, (num - killR) / (hurtR - killR))) * scale;
				float num4 = ((num3 >= 1f) ? (num2 * 10f + 1000f) : (num2 * num3));
				Vector3 val = ((num > 0.01f) ? ((head.position - pos) / num) : Vector3.up);
				Attack val2 = new Attack
				{
					damage = num4,
					attackType = (AttackType)2,
					origin = pos,
					direction = val,
					normal = -val,
					backFacing = false,
					collider = null,
					proxy = null
				};
				PlayerSender.SendPlayerDamage(smallID, val2, (BodyPart)2);
				MelonLogger.Msg($"[OrbitalStrike] Warhead hit: player {smallID} at {num:0} m, {num4:0} damage sent through Fusion{((num3 >= 1f) ? ", lethal" : "")}");
				hit++;
			}
		}

		public static void LaserPlayers(Vector3 at, float radius)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!InLobby)
			{
				return;
			}
			try
			{
				Burn(at, radius);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] could not damage other players: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void Burn(Vector3 at, float radius)
		{
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_0177: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_0072: 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_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_007e: Unknown result type (might be due to invalid IL or missing references)
			foreach (NetworkPlayer item in new List<NetworkPlayer>(NetworkPlayer.Players))
			{
				if (item == null || item.PlayerID == null || !item.PlayerID.IsValid || item.PlayerID.IsMe || !item.HasRig)
				{
					continue;
				}
				Transform head = item.RigRefs.Head;
				if ((Object)(object)head == (Object)null)
				{
					continue;
				}
				Vector3 val = head.position - at;
				float y = val.y;
				val.y = 0f;
				if (((Vector3)(ref val)).magnitude > radius || y < -2f || y > 6f || !NetworkCombatManager.CanAttack(item))
				{
					continue;
				}
				float num = 0f;
				try
				{
					if ((Object)(object)item.RigRefs.Health != (Object)null)
					{
						num = ((Health)item.RigRefs.Health).max_Health;
					}
				}
				catch
				{
				}
				if (num <= 0f)
				{
					num = 100f;
				}
				float num2 = Laser.ShareAt(((Vector3)(ref val)).magnitude, radius);
				float num3 = ((num2 >= 1f) ? (num * 10f + 1000f) : (num * num2));
				Attack val2 = new Attack
				{
					damage = num3,
					attackType = (AttackType)8,
					origin = at + Vector3.up * 40f,
					direction = Vector3.down,
					normal = Vector3.up,
					backFacing = false,
					collider = null,
					proxy = null
				};
				PlayerSender.SendPlayerDamage(item.PlayerID.SmallID, val2, (BodyPart)2);
				MelonLogger.Msg($"[OrbitalStrike] Laser hit: player {item.PlayerID.SmallID}, {num3:0.0} damage sent through Fusion{((num2 >= 1f) ? ", lethal" : "")}");
			}
		}
	}
	internal static class BlastSound
	{
		private sealed class Rng
		{
			private Random _r;

			public Rng(int seed)
			{
				_r = new Random(seed);
			}

			public float N()
			{
				return (float)(_r.NextDouble() * 2.0 - 1.0);
			}

			public float U()
			{
				return (float)_r.NextDouble();
			}
		}

		private struct Lp
		{
			private float _s;

			public float Run(float x, float hz)
			{
				float num = 1f - (float)Math.Exp(Math.PI * -2.0 * (double)hz / 44100.0);
				_s += num * (x - _s);
				return _s;
			}
		}

		private struct Hp
		{
			private Lp _lp;

			public float Run(float x, float hz)
			{
				return x - _lp.Run(x, hz);
			}
		}

		private const int Rate = 44100;

		private static AudioClip _clip;

		public static void Warm()
		{
			if (!((Object)(object)_clip != (Object)null))
			{
				float[] array = BlastWind();
				_clip = AudioClip.Create("orbital_blastwind", array.Length, 1, 44100, false);
				_clip.SetData(new Il2CppStructArray<float>(array), 0);
				((Object)_clip).hideFlags = (HideFlags)32;
			}
		}

		public static void Play(Vector3 from, float volume)
		{
			//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_0015: 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_0093: Expected O, but got Unknown
			Warm();
			GameObject val = new GameObject("OrbitalStrike_BlastWind");
			val.transform.position = from;
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.clip = _clip;
			obj.volume = Mathf.Clamp01(volume);
			obj.spatialBlend = 0.5f;
			obj.minDistance = 100000f;
			obj.maxDistance = 100001f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.dopplerLevel = 0f;
			obj.priority = 0;
			obj.playOnAwake = false;
			obj.Play();
			Object.Destroy((Object)val, _clip.length + 0.5f);
		}

		private static float Exp(float x)
		{
			return (float)Math.Exp(x);
		}

		private static float[] Finish(float[] d, float drive)
		{
			float num = (float)Math.Tanh(drive);
			for (int i = 0; i < d.Length; i++)
			{
				d[i] = (float)Math.Tanh(d[i] * drive) / num;
			}
			float num2 = 0.0001f;
			foreach (float value in d)
			{
				num2 = Math.Max(num2, Math.Abs(value));
			}
			float num3 = 0.95f / num2;
			for (int k = 0; k < d.Length; k++)
			{
				d[k] *= num3;
			}
			int num4 = Math.Min(d.Length, 2205);
			for (int l = 0; l < num4; l++)
			{
				d[d.Length - 1 - l] *= (float)l / (float)num4;
			}
			return d;
		}

		public static float[] BlastWind(float seconds = 5f)
		{
			int num = (int)(seconds * 44100f);
			float[] array = new float[num];
			Rng rng = new Rng(91);
			Lp lp = default(Lp);
			Lp lp2 = default(Lp);
			Lp lp3 = default(Lp);
			Lp lp4 = default(Lp);
			Lp lp5 = default(Lp);
			Lp lp6 = default(Lp);
			Lp lp7 = default(Lp);
			Hp hp = default(Hp);
			Hp hp2 = default(Hp);
			double num2 = 0.0;
			double num3 = 0.0;
			for (int i = 0; i < num; i++)
			{
				float num4 = (float)i / 44100f;
				float x = rng.N();
				float num5 = ((num4 < 0.003f) ? (num4 / 0.003f) : 1f);
				float num6 = 35f + 75f * Exp((0f - num4) / 0.06f);
				num2 += Math.PI * 2.0 * (double)num6 / 44100.0;
				num3 += Math.PI * 2.0 * (double)(28f + 20f * Exp((0f - num4) / 0.2f)) / 44100.0;
				float num7 = ((float)Math.Sin(num2) * 2.6f * Exp((0f - num4) / 0.3f) + (float)Math.Sin(num3) * 1.6f * Exp((0f - num4) / 0.7f) + lp5.Run(lp4.Run(x, 600f), 600f) * 3f * Exp((0f - num4) / 0.15f)) * num5;
				float num8 = lp7.Run(rng.N(), 3f) * 4f;
				float hz = 250f + 650f * Exp((0f - num4) / 1f);
				float num9 = hp.Run(lp3.Run(lp2.Run(lp.Run(x, hz), hz), hz), 50f) * ((num4 < 0.06f) ? (num4 / 0.06f) : 1f) * Exp((0f - num4) / 1.6f) * (1.2f + num8) * 2.6f;
				float num10 = hp2.Run(lp6.Run(x, 2200f), 500f) * ((rng.U() < 0.02f) ? 1f : 0.1f) * Exp((0f - num4) / 0.9f) * 0.35f;
				array[i] = num7 + num9 + num10;
			}
			return Finish(array, 1.8f);
		}
	}
	internal sealed class Canvas
	{
		public readonly int W;

		public readonly int H;

		private readonly Color32[] _px;

		private readonly Il2CppStructArray<Color32> _native;

		private readonly Texture2D _tex;

		private readonly Material _mat;

		public readonly GameObject Quad;

		public Canvas(Transform overlay, int w, int h, bool blank = false)
		{
			//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)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			W = w;
			H = h;
			_px = (Color32[])(object)new Color32[w * h];
			_native = new Il2CppStructArray<Color32>((long)(w * h));
			_tex = new Texture2D(w, h, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			((Object)_tex).hideFlags = (HideFlags)32;
			Quad = ((Component)overlay).gameObject;
			MeshRenderer component = ((Component)overlay).GetComponent<MeshRenderer>();
			_mat = ((Renderer)component).material;
			_mat.SetTexture("_MainTex", (Texture)(object)_tex);
			if (blank)
			{
				Show();
			}
			Quad.SetActive(true);
		}

		public void Dispose()
		{
			if ((Object)(object)_tex != (Object)null)
			{
				Object.Destroy((Object)(object)_tex);
			}
			if ((Object)(object)_mat != (Object)null)
			{
				Object.Destroy((Object)(object)_mat);
			}
		}

		public static void Black(RenderTexture rt)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rt == (Object)null))
			{
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = rt;
				GL.Clear(true, true, Color.black);
				RenderTexture.active = active;
			}
		}

		public void Clear()
		{
			Array.Clear(_px, 0, _px.Length);
		}

		public void Show()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _px.Length; i++)
			{
				((Il2CppArrayBase<Color32>)(object)_native)[i] = _px[i];
			}
			_tex.SetPixels32(_native);
			_tex.Apply(false);
		}

		public void Dot(int x, int y, Color32 c)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (x >= 0 && y >= 0 && x < W && y < H)
			{
				_px[y * W + x] = c;
			}
		}

		public void Box(int x, int y, int r, Color32 c)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			for (int i = -r; i <= r; i++)
			{
				for (int j = -r; j <= r; j++)
				{
					Dot(x + j, y + i, c);
				}
			}
		}

		public void Fill(int x, int y, int w, int h, Color32 c)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					Dot(x + j, y + i, c);
				}
			}
		}

		public void Line(int x0, int y0, int x1, int y1, Color32 c)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Abs(x1 - x0);
			int num2 = -Mathf.Abs(y1 - y0);
			int num3 = ((x0 < x1) ? 1 : (-1));
			int num4 = ((y0 < y1) ? 1 : (-1));
			int num5 = num + num2;
			for (int i = 0; i < 2000; i++)
			{
				Dot(x0, y0, c);
				if (x0 != x1 || y0 != y1)
				{
					int num6 = 2 * num5;
					if (num6 >= num2)
					{
						num5 += num2;
						x0 += num3;
					}
					if (num6 <= num)
					{
						num5 += num;
						y0 += num4;
					}
					continue;
				}
				break;
			}
		}

		public void Ring(int x, int y, int r, Color32 c)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 32; i++)
			{
				float num = (float)i * (float)Math.PI / 16f;
				Dot(x + Mathf.RoundToInt((float)r * Mathf.Cos(num)), y + Mathf.RoundToInt((float)r * Mathf.Sin(num)), c);
			}
		}

		public void Text(string s, int x, int y, Color32 c, int scale = 1)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			string text = s.ToUpperInvariant();
			foreach (char key in text)
			{
				if (Glyphs.Rows.TryGetValue(key, out var value))
				{
					for (int j = 0; j < 7; j++)
					{
						for (int k = 0; k < 5; k++)
						{
							if (value[j * 5 + k] != '1')
							{
								continue;
							}
							for (int l = 0; l < scale; l++)
							{
								for (int m = 0; m < scale; m++)
								{
									Dot(x + k * scale + l, y - j * scale - m, c);
								}
							}
						}
					}
				}
				x += 6 * scale;
			}
		}
	}
	internal static class FusionPlayers
	{
		private static bool? _loaded;

		private static readonly List<Vector3> Empty = new List<Vector3>();

		public static List<Vector3> Heads()
		{
			if (!_loaded.HasValue)
			{
				_loaded = false;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					if (assemblies[i].GetName().Name == "LabFusion")
					{
						_loaded = true;
					}
				}
			}
			if (_loaded != true)
			{
				return Empty;
			}
			try
			{
				return Read();
			}
			catch
			{
				_loaded = false;
				return Empty;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static List<Vector3> Read()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			foreach (NetworkPlayer player in NetworkPlayer.Players)
			{
				if (player != null && player.HasRig)
				{
					list.Add(player.RigRefs.Head.position);
				}
			}
			return list;
		}
	}
	internal static class Glyphs
	{
		public static readonly Dictionary<char, string> Rows = new Dictionary<char, string>
		{
			['A'] = "01110100011000111111100011000110001",
			['B'] = "11110100011000111110100011000111110",
			['C'] = "01110100011000010000100001000101110",
			['D'] = "11110100011000110001100011000111110",
			['E'] = "11111100001000011110100001000011111",
			['F'] = "11111100001000011110100001000010000",
			['G'] = "01111100001000010111100011000101111",
			['H'] = "10001100011000111111100011000110001",
			['I'] = "01110001000010000100001000010001110",
			['J'] = "00111000100001000010000101001001100",
			['K'] = "10001100101010011000101001001010001",
			['L'] = "10000100001000010000100001000011111",
			['M'] = "10001110111010110101100011000110001",
			['N'] = "10001110011010110011100011000110001",
			['O'] = "01110100011000110001100011000101110",
			['P'] = "11110100011000111110100001000010000",
			['Q'] = "01110100011000110001101011001001101",
			['R'] = "11110100011000111110101001001010001",
			['S'] = "01111100001000001110000010000111110",
			['T'] = "11111001000010000100001000010000100",
			['U'] = "10001100011000110001100011000101110",
			['V'] = "10001100011000110001100010101000100",
			['W'] = "10001100011000110101101011101110001",
			['X'] = "10001100010101000100010101000110001",
			['Y'] = "10001100010101000100001000010000100",
			['Z'] = "11111000010001000100010001000011111",
			['0'] = "01110100011001110101110011000101110",
			['1'] = "00100011000010000100001000010001110",
			['2'] = "01110100010000100010001000100011111",
			['3'] = "11110000010000101110000010000111110",
			['4'] = "00010001100101010010111110001000010",
			['5'] = "11111100001111000001000011000101110",
			['6'] = "00110010001000011110100011000101110",
			['7'] = "11111000010001000100010000100001000",
			['8'] = "01110100011000101110100011000101110",
			['9'] = "01110100011000101111000010001001100",
			['-'] = "00000000000000011111000000000000000",
			['.'] = "00000000000000000000000000110001100",
			[':'] = "00000011000110000000011000110000000",
			['/'] = "00001000010001000100010001000010000",
			['+'] = "00000001000010011111001000010000000",
			['%'] = "11001110010001000100010001001110011",
			['<'] = "00010001000100010000010000010000010",
			['>'] = "01000001000001000001000100010001000",
			['('] = "00010001000100001000010000010000010",
			[')'] = "01000001000001000010000100010001000",
			['['] = "01110010000100001000010000100001110",
			[']'] = "01110000100001000010000100001001110"
		};
	}
	internal static class ImpactShake
	{
		private const float Length = 1.4f;

		private const float Size = 0.009f;

		private const float Reach = 160f;

		private static float _left;

		private static float _gain;

		private static Transform _moved;

		private static Vector3 _applied;

		private static float Near(Vector3 at)
		{
			//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)
			if (!OrbitalMod.PrefLaserShake.Value || (Object)(object)Player.Head == (Object)null)
			{
				return 0f;
			}
			return Mathf.Clamp01(1.15f - Vector3.Distance(Player.Head.position, at) / 160f);
		}

		public static void Big(Vector3 at)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float num = Near(at);
			if (!(num <= 0f))
			{
				_gain = num;
				_left = 1.4f;
				Buzz(0.9f, 0.6f * num);
			}
		}

		public static void Pulse(Vector3 at)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float num = Near(at);
			if (num > 0f)
			{
				Buzz(0.2f, 0.2f * num);
			}
		}

		private static void Buzz(float seconds, float amount)
		{
			try
			{
				BaseController leftController = Player.LeftController;
				if (leftController != null)
				{
					leftController.HapticAction(0f, seconds, 70f, amount);
				}
				BaseController rightController = Player.RightController;
				if (rightController != null)
				{
					rightController.HapticAction(0f, seconds, 70f, amount);
				}
			}
			catch
			{
			}
		}

		public static void Update()
		{
			//IL_002d: 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_0013: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_moved != (Object)null)
			{
				Transform moved = _moved;
				moved.position -= _applied;
			}
			_moved = null;
			_applied = Vector3.zero;
		}

		public static void LateUpdate()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (!(_left <= 0f))
			{
				_left -= Time.deltaTime;
				OpenControllerRig controllerRig = Player.ControllerRig;
				if (!((Object)(object)controllerRig == (Object)null) && !((Object)(object)controllerRig.vrRoot == (Object)null))
				{
					float num = Mathf.Clamp01(_left / 1.4f) * _gain;
					float num2 = Time.time * 31f;
					_applied = new Vector3(Mathf.Sin(num2 * 1.1f), Mathf.Sin(num2 * 1.37f + 1f), Mathf.Sin(num2 * 0.93f + 2f)) * (0.009f * num);
					_moved = controllerRig.vrRoot;
					Transform moved = _moved;
					moved.position += _applied;
				}
			}
		}
	}
	internal static class NpcKill
	{
		private const float CheckAfter = 0.6f;

		private static readonly List<(AIBrain brain, string name, float at)> Checks = new List<(AIBrain, string, float)>();

		public static void Clear()
		{
			Checks.Clear();
		}

		public static bool Hit(AIBrain brain, float share, string source)
		{
			if ((Object)(object)brain == (Object)null)
			{
				return false;
			}
			if (brain.isDead)
			{
				return true;
			}
			string name = ((Object)((Component)brain).transform.root).name;
			BehaviourBaseNav behaviour = brain.behaviour;
			SubBehaviourHealth val = (((Object)(object)behaviour != (Object)null) ? behaviour.health : null);
			float num = ((val != null && val.maxHitPoints > 0f) ? val.maxHitPoints : 1f);
			float num2 = ((val != null) ? val.cur_hp : num);
			try
			{
				Extensions.DealDamage(brain, num * share);
			}
			catch
			{
			}
			float num3 = ((share >= 1f) ? 0f : Mathf.Max(0f, num2 - num * share));
			if (val != null)
			{
				try
				{
					val.cur_hp = num3;
				}
				catch
				{
				}
			}
			if (num3 > 0f)
			{
				MelonLogger.Msg($"[OrbitalStrike] {source} hit: {name}, HP {num2:0.##} -> {num3:0.##} of {num:0.##}");
				return false;
			}
			Die(brain, behaviour, val);
			bool flag = IsDead(brain);
			MelonLogger.Msg($"[OrbitalStrike] {source} hit: {name}, HP {num2:0.##} -> 0, {(flag ? "dead" : "kill sent")}");
			Checks.Add((brain, name, Time.time + 0.6f));
			return true;
		}

		private static bool IsDead(AIBrain brain)
		{
			if ((Object)(object)brain == (Object)null || brain.isDead)
			{
				return true;
			}
			try
			{
				PuppetMaster puppetMaster = brain.puppetMaster;
				return (Object)(object)puppetMaster == (Object)null || !puppetMaster.isAlive || puppetMaster.isKilling;
			}
			catch
			{
				return false;
			}
		}

		private static void Die(AIBrain brain, BehaviourBaseNav nav, SubBehaviourHealth health)
		{
			try
			{
				if ((Object)(object)nav != (Object)null)
				{
					nav.PuppetMasterKill();
				}
			}
			catch
			{
			}
			if (IsDead(brain))
			{
				return;
			}
			try
			{
				if ((Object)(object)brain.puppetMaster != (Object)null)
				{
					brain.puppetMaster.Kill();
				}
			}
			catch
			{
			}
			if (IsDead(brain))
			{
				return;
			}
			try
			{
				if (health != null)
				{
					health.Kill();
				}
			}
			catch
			{
			}
		}

		public static void Update()
		{
			for (int num = Checks.Count - 1; num >= 0; num--)
			{
				var (val, text, num2) = Checks[num];
				if (!(Time.time < num2))
				{
					Checks.RemoveAt(num);
					if (IsDead(val))
					{
						MelonLogger.Msg("[OrbitalStrike] confirmed dead: " + text);
					}
					else
					{
						Die(val, val.behaviour, ((Object)(object)val.behaviour != (Object)null) ? val.behaviour.health : null);
						MelonLogger.Warning("[OrbitalStrike] NOT DEAD after the kill: " + text + ". Tried again: " + (IsDead(val) ? "dead now" : "still alive"));
					}
				}
			}
		}
	}
	internal sealed class Laser
	{
		private const float Tick = 0.2f;

		private const float LimpSeconds = 2.5f;

		private const float BurnSeconds = 6f;

		private const float LimpMuscle = 0.12f;

		private const float CoreShare = 0.4f;

		private const float MinCore = 1.5f;

		private const float NearEdge = 0.5f;

		private const float FarEdge = 0.06f;

		private const int MaxBurning = 8;

		public GameObject Burn;

		private float _next;

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

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

		private readonly Dictionary<int, (AIBrain brain, Rigidbody rb, float d)> _npcs = new Dictionary<int, (AIBrain, Rigidbody, float)>();

		private readonly List<(PuppetMaster pm, float weight, float until)> _limp = new List<(PuppetMaster, float, float)>();

		private readonly List<(GameObject go, float until)> _burning = new List<(GameObject, float)>();

		private int _hits;

		private int _props;

		private int _ticks;

		private int _killed;

		public static float ShareAt(float distance, float radius)
		{
			float num = Mathf.Min(radius, Mathf.Max(1.5f, radius * 0.4f));
			return ((distance <= num) ? 1f : Mathf.Lerp(0.5f, 0.06f, Mathf.Clamp01((distance - num) / Mathf.Max(0.01f, radius - num)))) * OrbitalMod.PrefDamage.Value / 100f;
		}

		private static float Flat(Vector3 a, Vector3 b)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			a.y = (b.y = 0f);
			Vector3 val = a - b;
			return ((Vector3)(ref val)).magnitude;
		}

		public void Begin()
		{
			_next = 0f;
			_lit.Clear();
			_hits = (_props = (_ticks = (_killed = 0)));
		}

		public void End()
		{
			if (_ticks > 0)
			{
				MelonLogger.Msg($"[OrbitalStrike] laser finished: {_ticks} ticks, {_hits} NPC hits, {_killed} NPCs killed, {_props} prop pushes");
			}
		}

		public void Update()
		{
			for (int num = _limp.Count - 1; num >= 0; num--)
			{
				var (val, muscleWeight, num2) = _limp[num];
				if (!(Time.time < num2))
				{
					_limp.RemoveAt(num);
					try
					{
						if ((Object)(object)val != (Object)null && val.isAlive)
						{
							val.muscleWeight = muscleWeight;
						}
					}
					catch
					{
					}
				}
			}
			for (int num3 = _burning.Count - 1; num3 >= 0; num3--)
			{
				if (!((Object)(object)_burning[num3].go != (Object)null) || !(Time.time < _burning[num3].until))
				{
					if ((Object)(object)_burning[num3].go != (Object)null)
					{
						Object.Destroy((Object)(object)_burning[num3].go);
					}
					_burning.RemoveAt(num3);
				}
			}
		}

		public void Step(Vector3 at)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < _next)
			{
				return;
			}
			_next = Time.time + 0.2f;
			_ticks++;
			float value = OrbitalMod.PrefLaserRadius.Value;
			bool value2 = OrbitalMod.PrefBlastKillNpcs.Value;
			bool value3 = OrbitalMod.PrefBlastPushObjects.Value;
			_seenBody.Clear();
			_npcs.Clear();
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(at + Vector3.up, value, -1, (QueryTriggerInteraction)1))
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				Rigidbody attachedRigidbody = item.attachedRigidbody;
				if ((Object)(object)attachedRigidbody == (Object)null || !_seenBody.Add(((Object)attachedRigidbody).GetInstanceID()) || World.IsOurs(((Component)attachedRigidbody).transform))
				{
					continue;
				}
				RigManager val = null;
				try
				{
					val = ((Component)attachedRigidbody).GetComponentInParent<RigManager>();
				}
				catch
				{
				}
				if ((Object)(object)val != (Object)null || (BlastNet.InLobby && BlastNet.TakeOwnership(attachedRigidbody)))
				{
					continue;
				}
				AIBrain val2 = Blast.FindBrain(attachedRigidbody);
				if ((Object)(object)val2 != (Object)null)
				{
					int instanceID = ((Object)val2).GetInstanceID();
					float num = Flat(attachedRigidbody.worldCenterOfMass, at);
					if (!_npcs.TryGetValue(instanceID, out (AIBrain, Rigidbody, float) value4) || num < value4.Item3)
					{
						_npcs[instanceID] = (val2, attachedRigidbody, num);
					}
				}
				else if (value3 && !attachedRigidbody.isKinematic)
				{
					Shove(attachedRigidbody, at, 1.1f);
					_props++;
					if (_lit.Add(((Object)attachedRigidbody).GetInstanceID()))
					{
						Fire(((Component)attachedRigidbody).transform);
						MelonLogger.Msg("[OrbitalStrike] Laser hit: prop " + ((Object)attachedRigidbody).name);
					}
				}
			}
			foreach (KeyValuePair<int, (AIBrain, Rigidbody, float)> npc in _npcs)
			{
				var (val3, val4, distance) = npc.Value;
				if (val3.isDead)
				{
					continue;
				}
				bool flag = _lit.Add(npc.Key);
				if (flag)
				{
					Fire(((Component)val4).transform);
				}
				if (value2)
				{
					_hits++;
					if (NpcKill.Hit(val3, ShareAt(distance, value), "Laser"))
					{
						_killed++;
						continue;
					}
				}
				if (flag)
				{
					Limp(val3.puppetMaster);
					Shove(val4, at, 1.6f);
				}
			}
			if (OrbitalMod.PrefBlastHurtOthers.Value)
			{
				BlastNet.LaserPlayers(at, value);
			}
			if (OrbitalMod.PrefBlastHurtMe.Value)
			{
				Me(at, value);
			}
		}

		private static void Shove(Rigidbody rb, Vector3 at, float speed)
		{
			//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_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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!rb.isKinematic)
			{
				Vector3 val = rb.worldCenterOfMass - at;
				val.y = 0f;
				rb.AddForce(((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.forward) * speed + Vector3.up * speed * 0.6f, (ForceMode)2);
			}
		}

		private void Limp(PuppetMaster pm)
		{
			if ((Object)(object)pm == (Object)null)
			{
				return;
			}
			try
			{
				_limp.Add((pm, pm.muscleWeight, Time.time + 2.5f));
				pm.muscleWeight = 0.12f;
			}
			catch
			{
			}
		}

		private void Fire(Transform on)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Burn == (Object)null) && _burning.Count < 8)
			{
				GameObject val = Object.Instantiate<GameObject>(Burn, on, false);
				((Object)val).name = "OrbitalBurn";
				val.transform.localPosition = Vector3.zero;
				val.SetActive(true);
				_burning.Add((val, Time.time + 6f));
			}
		}

		private static void Me(Vector3 at, float radius)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			Transform head = Player.Head;
			if ((Object)(object)head == (Object)null)
			{
				return;
			}
			float num = Flat(head.position, at);
			float num2 = head.position.y - at.y;
			if (num > radius || num2 < -2f || num2 > 6f)
			{
				return;
			}
			try
			{
				Player_Health val = (((Object)(object)Player.RigManager != (Object)null && (Object)(object)Player.RigManager.health != (Object)null) ? ((Il2CppObjectBase)Player.RigManager.health).TryCast<Player_Health>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					float num3 = ShareAt(num, radius);
					float num4 = ((num3 >= 1f) ? 1000f : (((Health)val).max_Health * num3));
					((Health)val).TAKEDAMAGE(num4);
					MelonLogger.Msg($"[OrbitalStrike] Laser hit: me, {num4:0.0} damage");
				}
			}
			catch
			{
			}
		}
	}
	public class OrbitalMod : MelonMod
	{
		internal static MelonPreferences_Entry<int> PrefTruckSmoothing;

		internal static MelonPreferences_Entry<bool> PrefSafety;

		internal static MelonPreferences_Entry<bool> PrefBlastHurtMe;

		internal static MelonPreferences_Entry<bool> PrefBlastPushMe;

		internal static MelonPreferences_Entry<bool> PrefBlastPushObjects;

		internal static MelonPreferences_Entry<bool> PrefBlastKillNpcs;

		internal static MelonPreferences_Entry<bool> PrefBlastHurtOthers;

		internal static MelonPreferences_Entry<float> PrefDamage;

		internal static MelonPreferences_Entry<float> PrefLaserRadius;

		internal static MelonPreferences_Entry<string> PrefTalkMic;

		internal static MelonPreferences_Entry<int> PrefLaunchSound;

		internal static MelonPreferences_Entry<float> PrefLaunchVolume;

		internal static MelonPreferences_Entry<bool> PrefLaserShake;

		internal static readonly string[] LaunchNames = new string[4] { "Deep Rumble", "Distant Thunder Rumble", "Heavy Roar", "Quiet" };

		internal static MelonPreferences_Entry<bool> PrefTalk;

		internal static MelonPreferences_Entry<bool> PrefHearSelf;

		internal static MelonPreferences_Entry<bool> PrefVoiceLines;

		internal static int SafetyVersion;

		private static BoolElement _safetyItem;

		private static float _errorUntil;

		private static int _errors;

		internal static TruckSmoothing Smoothing
		{
			get
			{
				if (PrefTruckSmoothing == null)
				{
					return TruckSmoothing.Auto;
				}
				return (TruckSmoothing)Mathf.Clamp(PrefTruckSmoothing.Value, 0, 3);
			}
		}

		internal static void SetSafety(bool on)
		{
			if (PrefSafety.Value != on)
			{
				PrefSafety.Value = on;
				MelonPreferences.Save();
				SafetyVersion++;
				if (_safetyItem != null)
				{
					_safetyItem.Value = on;
				}
			}
		}

		public override void OnInitializeMelon()
		{
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: 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_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			MelonPreferences_Category obj = MelonPreferences.CreateCategory("OrbitalStrike");
			PrefTruckSmoothing = obj.CreateEntry<int>("TruckSmoothing", 0, "0 = Auto (fixed body, drawn like yours), 1 = Interpolate, 2 = Off, 3 = Velocity (free body)", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefSafety = obj.CreateEntry<bool>("Safety", true, "On: no firing within 30 m of your truck or console", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefBlastHurtMe = obj.CreateEntry<bool>("BlastHurtsMe", false, "Laser and warhead can hurt or kill you", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefBlastPushMe = obj.CreateEntry<bool>("BlastPushesMe", false, "Warhead: the shockwave throws your own player", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefBlastPushObjects = obj.CreateEntry<bool>("BlastPushesObjects", true, "Warhead: the shockwave throws objects and NPCs", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefBlastKillNpcs = obj.CreateEntry<bool>("BlastKillsNpcs", true, "Laser and warhead damage NPCs", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefBlastHurtOthers = obj.CreateEntry<bool>("BlastHurtsOtherPlayers", true, "When you fire: laser and warhead damage other players through Fusion, if the lobby allows it", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefTalk = obj.CreateEntry<bool>("LiveTalk", false, "TALK button: your voice from the sky while held, Fusion lobbies only", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefHearSelf = obj.CreateEntry<bool>("HearMyself", false, "Test: while TALK is held, your own voice comes back to you from the satellite loudspeaker", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefTalkMic = obj.CreateEntry<string>("SatelliteMicrophone", "", "Mic used while TALK is held. Empty = the same mic as Fusion", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefLaunchSound = obj.CreateEntry<int>("LaunchSound", 0, "0 = Deep Rumble, 1 = Distant Thunder Rumble, 2 = Heavy Roar, 3 = Quiet", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefLaunchVolume = obj.CreateEntry<float>("LaunchVolume", 100f, "Satellite launch sound, in percent", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefLaserShake = obj.CreateEntry<bool>("LaserShake", true, "A light view shake and controller rumble at the laser's first hit and stop, within 160 m", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefDamage = obj.CreateEntry<float>("Damage", 100f, "Laser and warhead, 100 = lethal: everything in the beam's core or the fireball dies", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefVoiceLines = obj.CreateEntry<bool>("BroadcastVoiceLines", true, "Off: the satellite says nothing when you fire, and BROADCAST stays silent. The countdown stays", (string)null, false, false, (ValueValidator)null, (string)null);
			PrefLaserRadius = obj.CreateEntry<float>("LaserRadius", 4f, "Laser: metres around the beam's ground point", (string)null, false, false, (ValueValidator)null, (string)null);
			Hooking.OnLevelUnloaded += World.Clear;
			TruckNet.Init();
			Page val = Page.Root.CreatePage("Orbital Strike", new Color(0.35f, 0.75f, 1f), 0, true);
			_safetyItem = val.CreateBool("Safety (30 m limit)", Color.yellow, PrefSafety.Value, (Action<bool>)SetSafety);
			val.CreateBool("Damage NPCs", Color.white, PrefBlastKillNpcs.Value, (Action<bool>)delegate(bool v)
			{
				PrefBlastKillNpcs.Value = v;
				Save();
			});
			val.CreateBool("Hurt other players", new Color(1f, 0.4f, 0.4f), PrefBlastHurtOthers.Value, (Action<bool>)delegate(bool v)
			{
				PrefBlastHurtOthers.Value = v;
				Save();
			});
			val.CreateBool("Can hurt you", Color.white, PrefBlastHurtMe.Value, (Action<bool>)delegate(bool v)
			{
				PrefBlastHurtMe.Value = v;
				Save();
			});
			val.CreateBool("Shockwave pushes me", Color.white, PrefBlastPushMe.Value, (Action<bool>)delegate(bool v)
			{
				PrefBlastPushMe.Value = v;
				Save();
			});
			val.CreateBool("Shockwave pushes objects", Color.white, PrefBlastPushObjects.Value, (Action<bool>)delegate(bool v)
			{
				PrefBlastPushObjects.Value = v;
				Save();
			});
			val.CreateFloat("Damage (100 = lethal)", Color.red, PrefDamage.Value, 10f, 10f, 100f, (Action<float>)delegate(float v)
			{
				PrefDamage.Value = v;
				Save();
			});
			val.CreateFloat("Laser radius (m)", Color.red, PrefLaserRadius.Value, 0.5f, 1f, 15f, (Action<float>)delegate(float v)
			{
				PrefLaserRadius.Value = v;
				Save();
			});
			val.CreateBool("Broadcast voice lines", Color.green, PrefVoiceLines.Value, (Action<bool>)delegate(bool v)
			{
				PrefVoiceLines.Value = v;
				Save();
			});
			val.CreateBool("TALK button (live voice)", Color.green, PrefTalk.Value, (Action<bool>)delegate(bool v)
			{
				PrefTalk.Value = v;
				Save();
			});
			TalkMic.Menu(val);
			Hooking.OnLevelLoaded += delegate
			{
				TalkMic.Refresh();
			};
			val.CreateBool("Hear myself (test)", Color.green, PrefHearSelf.Value, (Action<bool>)delegate(bool v)
			{
				PrefHearSelf.Value = v;
				Save();
			});
			FunctionElement launchRow = null;
			launchRow = val.CreateFunction(Launch(), Color.cyan, (Action)delegate
			{
				PrefLaunchSound.Value = (PrefLaunchSound.Value + 1) % LaunchNames.Length;
				((Element)launchRow).ElementName = Launch();
				Save();
			});
			val.CreateFloat("Launch volume (%)", Color.cyan, PrefLaunchVolume.Value, 10f, 0f, 100f, (Action<float>)delegate(float v)
			{
				PrefLaunchVolume.Value = v;
				Save();
			});
			val.CreateBool("Laser shake", Color.red, PrefLaserShake.Value, (Action<bool>)delegate(bool v)
			{
				PrefLaserShake.Value = v;
				Save();
			});
			val.CreateEnum("Truck smoothing", Color.cyan, (Enum)Smoothing, (Action<Enum>)delegate(Enum v)
			{
				PrefTruckSmoothing.Value = Convert.ToInt32(v);
				MelonPreferences.Save();
			});
			((MelonBase)this).LoggerInstance.Msg("OrbitalStrike 1.0.0 loaded: truck driving, target beacons, safe distance, aim on the ground, laser and warhead damage.");
			static string Launch()
			{
				return "Launch sound: " + LaunchNames[Mathf.Clamp(PrefLaunchSound.Value, 0, LaunchNames.Length - 1)];
			}
			static void Save()
			{
				MelonPreferences.Save();
			}
		}

		public override void OnApplicationQuit()
		{
			TalkMic.End();
		}

		public override void OnUpdate()
		{
			Guard(ImpactShake.Update);
			Guard(World.Update);
			Guard(Trucks.Update);
		}

		public override void OnFixedUpdate()
		{
			Guard(Trucks.FixedUpdate);
		}

		public override void OnLateUpdate()
		{
			Guard(Trucks.LateUpdate);
			Guard(ImpactShake.LateUpdate);
		}

		private void Guard(Action a)
		{
			if (Time.unscaledTime < _errorUntil)
			{
				return;
			}
			try
			{
				a();
			}
			catch (Exception ex)
			{
				if (_errors++ < 5)
				{
					((MelonBase)this).LoggerInstance.Warning("[OrbitalStrike] " + ex);
				}
				_errorUntil = Time.unscaledTime + 5f;
			}
		}
	}
	internal static class World
	{
		public static readonly List<Transform> Beacons = new List<Transform>();

		private static readonly List<Station> Stations = new List<Station>();

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

		public static void Seen(Poolee p)
		{
			GameObject val = (((Object)(object)p != (Object)null) ? ((Component)p).gameObject : null);
			if ((Object)(object)val != (Object)null)
			{
				Pending.Add(val);
			}
		}

		public static void Clear()
		{
			Beacons.Clear();
			Stations.Clear();
			Pending.Clear();
			TalkMic.End();
			Trucks.Clear();
			Blast.Clear();
			NpcKill.Clear();
		}

		public static void Update()
		{
			if (Pending.Count > 0)
			{
				GameObject[] array = Pending.ToArray();
				foreach (GameObject go in array)
				{
					if ((Object)(object)go == (Object)null || !go.activeInHierarchy)
					{
						continue;
					}
					if (((Object)go).name.StartsWith("OrbitalStrike_TargetBeacon"))
					{
						Transform item = Deep(go.transform, "Body");
						if (!Beacons.Contains(item))
						{
							Beacons.Add(item);
						}
					}
					else if (((Object)go).name.StartsWith("OrbitalStrike_UplinkStation"))
					{
						Trucks.Add(go.transform, radar: false);
						if (!Stations.Exists((Station s) => (Object)(object)s.Root == (Object)(object)go.transform))
						{
							Stations.Add(new Station(go.transform));
						}
					}
				}
				Pending.Clear();
			}
			Beacons.RemoveAll((Transform b) => (Object)(object)b == (Object)null || !((Component)b).gameObject.activeInHierarchy);
			for (int num = Stations.Count - 1; num >= 0; num--)
			{
				if (Stations[num].Gone)
				{
					Stations.RemoveAt(num);
				}
				else
				{
					Stations[num].Update();
				}
			}
			if (Stations.Count == 0)
			{
				TalkMic.End();
			}
			Blast.UpdateAll(Time.deltaTime);
			NpcKill.Update();
		}

		public static bool IsOurs(Transform t)
		{
			foreach (Station station in Stations)
			{
				if ((Object)(object)station.Root != (Object)null && t.IsChildOf(station.Root))
				{
					return true;
				}
			}
			return false;
		}

		public static Transform Deep(Transform root, string name)
		{
			foreach (Transform componentsInChild in ((Component)root).GetComponentsInChildren<Transform>(true))
			{
				if (((Object)componentsInChild).name == name)
				{
					return componentsInChild;
				}
			}
			throw new Exception("OrbitalStrike: no " + name + " under " + ((Object)root).name);
		}
	}
	internal sealed class Station
	{
		private const float SafeDistance = 30f;

		private const float TruckHalf = 9.5f;

		private const float GroundFromAbove = 900f;

		private static readonly Il2CppStructArray<RaycastHit> Hits = new Il2CppStructArray<RaycastHit>(32L);

		public readonly Transform Root;

		private readonly Animator _a;

		private readonly Rigidbody _probe;

		private readonly Transform _probeT;

		private readonly Transform _strike;

		private readonly Transform _aimF;

		private readonly Transform _aimR;

		private readonly Transform _console;

		private readonly Transform _mark;

		private readonly Transform _fireT;

		private readonly Transform _fireD;

		private readonly Transform _safeOn;

		private bool _safeSeen;

		private bool _lastSafe;

		private bool _wantApply;

		private float _applyAt;

		private int _safetyVersion;

		private readonly GameObject _tooClose;

		private readonly GameObject _tooCloseMain;

		private readonly GameObject _noBeacon;

		private readonly GameObject _noBeaconMain;

		private readonly Il2CppArrayBase<CrateSpawner> _spawners;

		private Transform _target;

		private bool _wasStriking;

		private bool _abortSent;

		private bool _wasFired;

		private bool _wasBeam;

		private bool _wasImpact;

		private float _pressAt = -100f;

		private float _talkSince;

		private float _talkLast;

		private bool _talking;

		private bool _hearApplied;

		private bool _hearOk;

		private readonly GameObject _sayOn;

		private readonly GameObject _bcAllowed;

		private readonly GameObject[] _launch = (GameObject[])(object)new GameObject[4];

		private readonly AudioSource[] _launchAudio = (AudioSource[])(object)new AudioSource[4];

		private readonly float[] _launchBase = new float[4];

		private readonly AudioSource _landAudio;

		private readonly GameObject _shockHit;

		private readonly GameObject _shockEnd;

		private bool _hitWasOn;

		private bool _endWasOn;

		private float _nextPulse;

		private readonly float _landBase;

		private int _launchSet = -1;

		private float _launchVolumeSet = -1f;

		private float _txLevel;

		private float _nextTxLog;

		private readonly GameObject _txPanel;

		private readonly GameObject _txLight;

		private readonly GameObject _txMuted;

		private readonly GameObject _voiceOut;

		private readonly Transform _txBar;

		private readonly GameObject _gTalk;

		private readonly GameObject _gSolo;

		private readonly GameObject _gPref;

		private readonly GameObject _talkLamp;

		private readonly UltEventHolder _talkRelease;

		private readonly Laser _laser = new Laser();

		private readonly Transform[] _yields = (Transform[])(object)new Transform[4];

		private float _nextGround;

		private float _groundY = float.NaN;

		private readonly Transform _stick;

		private readonly Transform _stickHandle;

		private readonly Rigidbody _stickRb;

		private readonly Dictionary<string, UltEventHolder> _sends = new Dictionary<string, UltEventHolder>();

		private bool _aDown;

		private float _nextZoom;

		public bool Mine { get; private set; }

		public bool Gone
		{
			get
			{
				if (!((Object)(object)Root == (Object)null))
				{
					return !((Component)Root).gameObject.activeInHierarchy;
				}
				return true;
			}
		}

		private void Send(string name)
		{
			if (!_sends.TryGetValue(name, out var value))
			{
				value = ((Component)World.Deep(Root, name)).GetComponent<UltEventHolder>();
				_sends[name] = value;
			}
			value.Invoke();
		}

		private void StickInput()
		{
			Hand_(Player.LeftHand, Player.LeftController);
			Hand_(Player.RightHand, Player.RightController);
		}

		private void Hand_(Hand hand, BaseController c)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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)
			if ((Object)(object)hand == (Object)null || (Object)(object)c == (Object)null || !(c.GetGripForce() > 0.5f))
			{
				return;
			}
			Vector3 val = ((Component)hand).transform.position - _stickHandle.position;
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.0625f))
			{
				return;
			}
			float y = c.GetThumbStickAxis().y;
			if (Mathf.Abs(y) > 0.6f && Time.unscaledTime >= _nextZoom)
			{
				_nextZoom = Time.unscaledTime + 0.3f;
				int integer = _a.GetInteger("Zoom");
				int num = Mathf.Clamp(integer + ((y > 0f) ? 1 : (-1)), 0, 4);
				if (num != integer)
				{
					Send("Send_ZOOM" + num);
				}
			}
			bool aButton = c.GetAButton();
			if (aButton && !_aDown)
			{
				Send("Send_SwLIGHT");
			}
			_aDown = aButton;
		}

		public Station(Transform root)
		{
			Root = root;
			_a = ((Component)root).GetComponent<Animator>();
			_stick = World.Deep(root, "Stick");
			_stickRb = ((Component)_stick).GetComponent<Rigidbody>();
			_stickHandle = _stick.Find("Handle");
			_probeT = World.Deep(root, "Probe");
			_probe = ((Component)_probeT).GetComponent<Rigidbody>();
			_strike = World.Deep(root, "Strike");
			_aimF = World.Deep(root, "AimF");
			_aimR = World.Deep(root, "AimR");
			_console = World.Deep(root, "Console");
			_mark = World.Deep(root, "TargetMark");
			_fireT = World.Deep(root, "FireTarget");
			_fireD = World.Deep(root, "FireDistance");
			_safeOn = World.Deep(root, "SafeOn");
			_tooClose = ((Component)World.Deep(root, "TooClose")).gameObject;
			_tooCloseMain = ((Component)World.Deep(root, "TooCloseMain")).gameObject;
			_noBeacon = ((Component)World.Deep(root, "NoBeacon")).gameObject;
			_noBeaconMain = ((Component)World.Deep(root, "NoBeaconMain")).gameObject;
			_spawners = ((Component)root).GetComponentsInChildren<CrateSpawner>(true);
			for (int i = 0; i < _yields.Length; i++)
			{
				_yields[i] = World.Deep(root, "Y" + i);
			}
			_laser.Burn = ((Component)World.Deep(root, "BurnFx")).gameObject;
			for (int j = 0; j < _launch.Length; j++)
			{
				_launch[j] = ((Component)World.Deep(root, "Launch" + j)).gameObject;
				_launchAudio[j] = _launch[j].GetComponent<AudioSource>();
				_launchBase[j] = _launchAudio[j].volume;
			}
			_landAudio = ((Component)World.Deep(root, "SndLand")).GetComponent<AudioSource>();
			_landBase = _landAudio.volume;
			_shockHit = ((Component)World.Deep(root, "ShockHit")).gameObject;
			_shockEnd = ((Component)World.Deep(root, "ShockEnd")).gameObject;
			_sayOn = ((Component)World.Deep(root, "SayOn")).gameObject;
			_bcAllowed = ((Component)World.Deep(root, "BcAllowed")).gameObject;
			_gTalk = ((Component)World.Deep(root, "GTalk")).gameObject;
			_gSolo = ((Component)World.Deep(root, "GTalkSolo")).gameObject;
			_gPref = ((Component)World.Deep(root, "GTalkPref")).gameObject;
			_txPanel = ((Component)World.Deep(root, "TxPanel")).gameObject;
			_txBar = World.Deep(root, "TxBar");
			_txLight = ((Component)World.Deep(root, "TxLight")).gameObject;
			_txMuted = ((Component)World.Deep(root, "TxMuted")).gameObject;
			_voiceOut = ((Component)World.Deep(root, "VoiceOut")).gameObject;
			_talkLamp = ((Component)World.Deep(root, "Sel_TALK")).gameObject;
			_talkRelease = ((Component)World.Deep(root, "TalkRelease")).GetComponent<UltEventHolder>();
		}

		private bool State(string n)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			AnimatorStateInfo currentAnimatorStateInfo = _a.GetCurrentAnimatorStateInfo(0);
			return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName(n);
		}

		private float DistanceToOwn(Vector3 p)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Root.InverseTransformPoint(p);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0f, 0f, Mathf.Clamp(val.z, -9.5f, 9.5f));
			Vector2 val3 = new Vector2(val.x - val2.x, val.z - val2.z);
			float magnitude = ((Vector2)(ref val3)).magnitude;
			Vector3 val4 = p - _console.position;
			val4.y = 0f;
			return Mathf.Min(magnitude, ((Vector3)(ref val4)).magnitude);
		}

		private Transform Pick(bool next)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> beacons = World.Beacons;
			if (beacons.Count == 0)
			{
				return null;
			}
			if (next && (Object)(object)_target != (Object)null && beacons.Count > 1)
			{
				int num = beacons.IndexOf(_target);
				return beacons[(num + 1) % beacons.Count];
			}
			if ((Object)(object)_target != (Object)null && beacons.Contains(_target))
			{
				return _target;
			}
			Transform result = null;
			float num2 = float.MaxValue;
			foreach (Transform item in beacons)
			{
				Vector3 val = item.position - Root.position;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude < num2)
				{
					num2 = sqrMagnitude;
					result = item;
				}
			}
			return result;
		}

		private static void Lock(Transform b)
		{
			GameObject gameObject = ((Component)World.Deep(b, "Beep")).gameObject;
			gameObject.SetActive(false);
			gameObject.SetActive(true);
			((Component)World.Deep(b, "LockedLight")).gameObject.SetActive(true);
		}

		private static void Unlock(Transform b)
		{
			if (!((Object)(object)b == (Object)null))
			{
				((Component)World.Deep(b, "LockedLight")).gameObject.SetActive(false);
			}
		}

		private static void Remove(Transform b)
		{
			if ((Object)(object)b == (Object)null)
			{
				return;
			}
			World.Beacons.Remove(b);
			Poolee componentInParent = ((Component)b).GetComponentInParent<Poolee>();
			try
			{
				if ((Object)(object)componentInParent != (Object)null)
				{
					componentInParent.Despawn();
					return;
				}
			}
			catch
			{
			}
			Object.Destroy((Object)(object)(((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)b.root).gameObject));
		}

		private void Beacon()
		{
			//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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			bool num = _a.GetInteger("BeaconMode") == 1;
			bool flag = _a.GetBool("BeaconNext");
			if (flag)
			{
				_a.ResetTrigger("BeaconNext");
			}
			if (!num)
			{
				if ((Object)(object)_target != (Object)null)
				{
					Unlock(_target);
					_target = null;
				}
				return;
			}
			Transform val = Pick(flag);
			if ((Object)(object)val != (Object)(object)_target)
			{
				Unlock(_target);
				_target = val;
				if ((Object)(object)_target != (Object)null)
				{
					Lock(_target);
				}
			}
			bool flag2 = (Object)(object)_target != (Object)null;
			((Component)_fireT).gameObject.SetActive(flag2);
			_noBeacon.SetActive(!flag2);
			_noBeaconMain.SetActive(!flag2);
			((Component)_mark).gameObject.SetActive(flag2);
			if (flag2)
			{
				if (!_probe.isKinematic)
				{
					_probe.isKinematic = true;
				}
				_probeT.position = _target.position + Vector3.up * 0.2f;
			}
		}

		private void Safety()
		{
			bool activeSelf = ((Component)_safeOn).gameObject.activeSelf;
			if (!_safeSeen)
			{
				_safeSeen = true;
				_lastSafe = activeSelf;
				_safetyVersion = OrbitalMod.SafetyVersion;
				_applyAt = Time.time + 1.5f;
				_wantApply = !TruckNet.InLobby;
			}
			if (activeSelf != _lastSafe)
			{
				_lastSafe = activeSelf;
				if (!TruckNet.InLobby && !_wantApply)
				{
					OrbitalMod.SetSafety(activeSelf);
					_safetyVersion = OrbitalMod.SafetyVersion;
				}
			}
			if (_safetyVersion != OrbitalMod.SafetyVersion)
			{
				_safetyVersion = OrbitalMod.SafetyVersion;
				_wantApply = true;
			}
			if (_wantApply && !(Time.time < _applyAt))
			{
				if (activeSelf == OrbitalMod.PrefSafety.Value)
				{
					_wantApply = false;
					return;
				}
				_applyAt = Time.time + 0.6f;
				((Component)World.Deep(Root, "Send_SwSAFETY")).GetComponent<UltEventHolder>().Invoke();
			}
		}

		private void Guard(bool striking)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!((Component)_safeOn).gameObject.activeSelf)
			{
				((Component)_fireD).gameObject.SetActive(true);
				_abortSent = false;
				return;
			}
			bool flag = DistanceToOwn(_strike.position) < 30f;
			((Component)_fireD).gameObject.SetActive(!flag);
			if (((Component)_fireT).gameObject.activeSelf)
			{
				_tooClose.SetActive(flag);
				_tooCloseMain.SetActive(flag);
			}
			if (flag && striking && !_abortSent)
			{
				_a.SetTrigger("Abort");
				_abortSent = true;
			}
			if (!striking)
			{
				_abortSent = false;
			}
		}

		private void Ground()
		{
			//IL_0006: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_00a4: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Abs(_aimF.localPosition.x) + Mathf.Abs(_aimR.localPosition.z);
			Vector3 localPosition = _strike.localPosition;
			if (num < 1f)
			{
				if (localPosition.y != -0.15f)
				{
					localPosition.y = -0.15f;
					_strike.localPosition = localPosition;
				}
				_groundY = float.NaN;
				return;
			}
			if (Time.time >= _nextGround)
			{
				_nextGround = Time.time + 0.1f;
				Vector3 position = _strike.position;
				position.y = Root.position.y + 900f;
				int num2 = Physics.RaycastNonAlloc(position, Vector3.down, Hits, 1800f, -1, (QueryTriggerInteraction)1);
				float num3 = float.MinValue;
				for (int i = 0; i < num2; i++)
				{
					RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)Hits)[i];
					Collider collider = ((RaycastHit)(ref val)).collider;
					if (!((Object)(object)collider == (Object)null) && !((Component)collider).transform.IsChildOf(Root))
					{
						Rigidbody attachedRigidbody = collider.attachedRigidbody;
						if ((!((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic || !(attachedRigidbody.mass < 1000f)) && ((RaycastHit)(ref val)).point.y > num3)
						{
							num3 = ((RaycastHit)(ref val)).point.y;
						}
					}
				}
				if (num3 > float.MinValue)
				{
					_groundY = num3;
				}
			}
			if (!float.IsNaN(_groundY))
			{
				localPosition.y = Mathf.Lerp(localPosition.y, _groundY - _aimR.position.y, 1f - Mathf.Exp((0f - Time.deltaTime) * 6f));
				_strike.localPosition = localPosition;
			}
		}

		private void Talk()
		{
			bool inLobby = TruckNet.InLobby;
			bool flag = inLobby && OrbitalMod.PrefTalk.Value;
			bool activeSelf = _talkLamp.activeSelf;
			if (activeSelf && !_talking)
			{
				_talkSince = Time.time;
				MelonLogger.Msg("[OrbitalStrike] TALK: on air");
			}
			if (!activeSelf && _talking)
			{
				MelonLogger.Msg("[OrbitalStrike] TALK: off air");
			}
			_talking = activeSelf;
			if (activeSelf && (!flag || Time.time - _talkSince > 90f))
			{
				_talkRelease.Invoke();
			}
			if (activeSelf)
			{
				_talkLast = Time.time;
				TalkMic.Begin();
			}
			else if (TalkMic.Active && Time.time - _talkLast > 0.5f)
			{
				TalkMic.End();
			}
			Transmit(activeSelf && inLobby, inLobby);
			if (_gTalk.activeSelf != flag)
			{
				_gTalk.SetActive(flag);
			}
			if (_gSolo.activeSelf != !inLobby)
			{
				_gSolo.SetActive(!inLobby);
			}
			bool flag2 = inLobby && !flag;
			if (_gPref.activeSelf != flag2)
			{
				_gPref.SetActive(flag2);
			}
		}

		private void Transmit(bool on, bool lobby)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//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)
			bool flag = lobby && OrbitalMod.PrefHearSelf.Value;
			if (flag != _hearApplied)
			{
				_hearApplied = flag;
				_hearOk = VoiceTx.HearSelf(Root, _voiceOut, flag);
			}
			if (_txPanel.activeSelf != on)
			{
				_txPanel.SetActive(on);
			}
			if (!on)
			{
				_txLevel = 0f;
				_nextTxLog = 0f;
				return;
			}
			VoiceTx.State state = VoiceTx.Read();
			_txLevel = Mathf.Max(state.Level, Mathf.MoveTowards(_txLevel, 0f, 2.5f * Time.deltaTime));
			_txBar.localScale = new Vector3(0.19f * _txLevel, 1f, 1f);
			if (_txLight.activeSelf != state.Sending)
			{
				_txLight.SetActive(state.Sending);
			}
			if (_txMuted.activeSelf != state.Muted)
			{
				_txMuted.SetActive(state.Muted);
			}
			if (!(Time.time < _nextTxLog))
			{
				_nextTxLog = Time.time + 1f;
				Vector3 position = _voiceOut.transform.position;
				string text = $"mic {TalkMic.Current}, sound at ({position.x:0}, {position.y:0}, {position.z:0}), {(((Object)(object)Player.Head != (Object)null) ? Vector3.Distance(Player.Head.position, position) : 0f):0} m from you";
				MelonLogger.Msg(state.Sending ? $"[OrbitalStrike] Voice TX: sending, level {state.Level:0.00}, {text}{((flag && _hearOk) ? ", hearing myself" : "")}" : ("[OrbitalStrike] Voice TX: nothing to send (" + (state.Muted ? "muted in Fusion" : (state.CanTalk ? "quiet" : "no microphone")) + "), " + text));
			}
		}

		private void LaunchSound()
		{
			int num = Mathf.Clamp(OrbitalMod.PrefLaunchSound.Value, 0, _launch.Length - 1);
			float num2 = Mathf.Clamp01(OrbitalMod.PrefLaunchVolume.Value / 100f);
			if (num == _launchSet && num2 == _launchVolumeSet)
			{
				return;
			}
			_launchSet = num;
			_launchVolumeSet = num2;
			_landAudio.volume = _landBase * num2;
			for (int i = 0; i < _launch.Length; i++)
			{
				_launchAudio[i].volume = _launchBase[i] * num2;
				if (_launch[i].activeSelf != (i == num))
				{
					_launch[i].SetActive(i == num);
				}
			}
		}

		private void Weapons()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			if (_a.GetBool("FireMine"))
			{
				_a.SetBool("FireMine", false);
				_pressAt = Time.time;
			}
			bool flag = State("Countdown") || State("Charge") || State("Deploy");
			if (flag && !_wasFired)
			{
				Mine = !BlastNet.InLobby || Time.time - _pressAt < 1.5f;
				MelonLogger.Msg("[OrbitalStrike] shot fired by " + (Mine ? "me: I apply its damage" : "another player"));
			}
			_wasFired = flag;
			bool flag2 = State("Beam");
			if (flag2 && !_wasBeam)
			{
				_laser.Begin();
			}
			if (flag2 && Mine)
			{
				_laser.Step(_strike.position);
			}
			if (!flag2 && _wasBeam)
			{
				_laser.End();
			}
			_wasBeam = flag2;
			_laser.Update();
			bool flag3 = State("Impact");
			if (_wasImpact && !flag3 && State("Cool"))
			{
				int num = 1;
				for (int i = 0; i < _yields.Length; i++)
				{
					if (((Component)_yields[i]).gameObject.activeSelf)
					{
						num = i;
					}
				}
				Blast.Start(_strike.position, num switch
				{
					0 => 8f, 
					2 => 35f, 
					3 => 70f, 
					_ => 18f, 
				}, Mine);
			}
			_wasImpact = flag3;
		}

		public void Update()
		{
			//IL_0034: 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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			BlastSound.Warm();
			StickInput();
			foreach (CrateSpawner spawner in _spawners)
			{
				if ((Object)(object)spawner != (Object)null)
				{
					((Component)spawner).transform.rotation = Quaternion.identity;
				}
			}
			Beacon();
			Safety();
			LaunchSound();
			bool activeInHierarchy = _shockHit.activeInHierarchy;
			bool activeInHierarchy2 = _shockEnd.activeInHierarchy;
			if ((activeInHierarchy && !_hitWasOn) || (activeInHierarchy2 && !_endWasOn))
			{
				ImpactShake.Big(_shockHit.transform.position);
			}
			_hitWasOn = activeInHierarchy;
			_endWasOn = activeInHierarchy2;
			if (State("Beam") && Time.time >= _nextPulse)
			{
				_nextPulse = Time.time + 1.1f;
				ImpactShake.Pulse(_shockHit.transform.position);
			}
			Talk();
			bool value = OrbitalMod.PrefVoiceLines.Value;
			if (_sayOn.activeSelf != value)
			{
				_sayOn.SetActive(value);
				_bcAllowed.SetActive(value);
			}
			Weapons();
			bool striking = State("Countdown") || State("Beam") || State("Charge") || State("Deploy") || State("Fall");
			Guard(striking);
			Ground();
			bool flag = State("Beam") || State("Impact");
			if (_wasStriking && !flag && _a.GetInteger("BeaconMode") == 1 && (Object)(object)_target != (Object)null)
			{
				Remove(_target);
				_target = null;
			}
			_wasStriking = flag;
		}
	}
	[HarmonyPatch(typeof(Poolee), "OnSpawnEvent")]
	internal static class SpawnPatch
	{
		public static void Postfix(Poolee __instance)
		{
			try
			{
				World.Seen(__instance);
			}
			catch
			{
			}
		}
	}
	internal static class TalkMic
	{
		private const string Category = "BONELAB Fusion";

		private const string Setting = "Input Device";

		private const string SameAsFusion = "Same as Fusion mic";

		private static Page _page;

		private static readonly Dictionary<string, FunctionElement> Rows = new Dictionary<string, FunctionElement>();

		private static string _restore;

		private static string _using;

		public static bool Active => _using != null;

		public static string Current => _using ?? "Fusion's mic";

		public static void Menu(Page parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_page = parent.CreatePage("Satellite microphone", Color.green, 0, true);
			_page.CreateFunction("Refresh list", Color.gray, (Action)Refresh);
			Row("Same as Fusion mic", "");
			Refresh();
		}

		public static void Refresh()
		{
			try
			{
				foreach (string item in (Il2CppArrayBase<string>)(object)Microphone.devices)
				{
					Row(item, item);
				}
				Marks();
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] can't list microphones: " + ex.Message);
			}
		}

		private static void Row(string label, string value)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!Rows.ContainsKey(value))
			{
				Rows[value] = _page.CreateFunction(label, Color.white, (Action)delegate
				{
					OrbitalMod.PrefTalkMic.Value = value;
					MelonPreferences.Save();
					Marks();
					MelonLogger.Msg("[OrbitalStrike] Satellite microphone: " + label);
				});
			}
		}

		private static void Marks()
		{
			//IL_0087: 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)
			string value = OrbitalMod.PrefTalkMic.Value;
			foreach (KeyValuePair<string, FunctionElement> row in Rows)
			{
				string text = ((row.Key.Length == 0) ? "Same as Fusion mic" : row.Key);
				((Element)row.Value).ElementName = ((row.Key == value) ? "> " : "") + text;
				((Element)row.Value).ElementColor = ((row.Key == value) ? Color.green : Color.white);
			}
		}

		private static MelonPreferences_Entry<string> Entry()
		{
			MelonPreferences_Category category = MelonPreferences.GetCategory("BONELAB Fusion");
			if (category == null)
			{
				return null;
			}
			return category.GetEntry<string>("Input Device");
		}

		public static void Begin()
		{
			if (_using != null)
			{
				return;
			}
			string value = OrbitalMod.PrefTalkMic.Value;
			if (string.IsNullOrEmpty(value))
			{
				return;
			}
			try
			{
				MelonPreferences_Entry<string> val = Entry();
				if (val == null || val.Value == value)
				{
					return;
				}
				bool flag = false;
				foreach (string item in (Il2CppArrayBase<string>)(object)Microphone.devices)
				{
					if (item == value)
					{
						flag = true;
					}
				}
				if (!flag)
				{
					MelonLogger.Warning("[OrbitalStrike] Satellite microphone not found: " + value + ". Using Fusion's mic.");
					return;
				}
				_restore = val.Value;
				Microphone.End(_restore);
				val.Value = value;
				_using = value;
				MelonLogger.Msg("[OrbitalStrike] TALK mic: " + value);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] couldn't switch the mic: " + ex.Message);
			}
		}

		public static void End()
		{
			if (_using == null)
			{
				return;
			}
			string text = _using;
			_using = null;
			try
			{
				MelonPreferences_Entry<string> val = Entry();
				if (val != null)
				{
					Microphone.End(text);
					val.Value = _restore;
					MelonLogger.Msg("[OrbitalStrike] TALK mic: back to Fusion's mic");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] couldn't switch the mic back: " + ex.Message);
			}
		}
	}
	internal static class TruckNet
	{
		public const byte NoLobbyId = 254;

		private static bool _fusion;

		public static bool InLobby
		{
			get
			{
				if (!_fusion)
				{
					return false;
				}
				try
				{
					return Has();
				}
				catch
				{
					return false;
				}
			}
		}

		public static byte MyId
		{
			get
			{
				if (!InLobby)
				{
					return 254;
				}
				try
				{
					return Me();
				}
				catch
				{
					return 254;
				}
			}
		}

		public static void Init()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					if (assemblies[i].GetName().Name == "LabFusion")
					{
						_fusion = true;
						break;
					}
				}
			}
			catch
			{
				_fusion = false;
			}
			if (!_fusion)
			{
				return;
			}
			try
			{
				Register();
				MelonLogger.Msg("[OrbitalStrike] LabFusion found: trucks are shared with the lobby.");
			}
			catch (Exception ex)
			{
				_fusion = false;
				MelonLogger.Warning("[OrbitalStrike] truck sync is off: " + ex.Message);
			}
		}

		public static ushort IdOf(Transform root)
		{
			if (!_fusion)
			{
				return 0;
			}
			try
			{
				return Id(root);
			}
			catch
			{
				return 0;
			}
		}

		public static void TakeOwnership(Transform root)
		{
			if (!InLobby)
			{
				return;
			}
			try
			{
				Own(root);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[OrbitalStrike] ownership: " + ex.Message);
			}
		}

		public static void SendPose(Transform root, bool radar, Vector3 pos, Quaternion rot, float speed, float steer, byte flags)
		{
			//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
			{
				Pose(root, radar, pos, rot, speed, steer, flags);
			}
			catch
			{
			}
		}

		public static void SendState(Transform root, bool radar, byte mode, byte lights, bool up, byte driver, byte leader)
		{
			try
			{
				State(root, radar, mode, lights, up, driver, leader);
			}
			catch
			{
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void Register()
		{
			FusionOrbitalTrucks.Register();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool Has()
		{
			return NetworkInfo.HasServer;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static byte Me()
		{
			return PlayerIDManager.LocalSmallID;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ushort Id(Transform root)
		{
			return FusionOrbitalTrucks.Id(root);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void Own(Transform root)
		{
			FusionOrbitalTrucks.Own(root);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void Pose(Transform root, bool radar, Vector3 pos, Quaternion rot, float speed, float steer, byte flags)
		{
			//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)
			FusionOrbitalTrucks.Pose(root, radar, pos, rot, speed, steer, flags);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void State(Transform root, bool radar, byte mode, byte lights, bool up, byte driver, byte leader)
		{
			FusionOrbitalTrucks.State(root, radar, mode, lights, up, driver, leader);
		}
	}
	internal static class FusionOrbitalTrucks
	{
		public static void Register()
		{
			ModuleMessageManager.RegisterHandler<OrbitalPoseMessage>();
			ModuleMessageManager.RegisterHandler<OrbitalStateMessage>();
		}

		private static NetworkEntity Entity(Transform root)
		{
			MarrowEntity component = ((Component)root).GetComponent<MarrowEntity>();
			NetworkEntity result = default(NetworkEntity);
			if (!((Object)(object)component != (Object)null) || !IMarrowEntityExtender.Cache.TryGet(component, ref result))
			{
				return null;
			}
			return result;
		}

		public static ushort Id(Transform root)
		{
			NetworkEntity val = Entity(root);
			if (val == null)
			{
				return 0;
			}
			return val.ID;
		}

		public static void Own(Transform root)
		{
			NetworkEntity val = Entity(root);
			if (val != null && !val.IsOwner)
			{
				NetworkEntityManager.TakeOwnership(val);
			}
		}

		public static void Pose(Transform root, bool radar, Vector3 pos, Quaternion rot, float speed, float steer, byte flags)
		{
			//IL_0019: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			MessageRelay.RelayModule<OrbitalPoseMessage, OrbitalPoseData>(new OrbitalPoseData
			{
				Id = Id(root),
				Radar = radar,
				Pos = pos,
				Rot = rot,
				Speed = speed,
				Steer = steer,
				Flags = flags
			}, CommonMessageRoutes.UnreliableToOtherClients);
		}

		public static void State(Transform root, bool radar, byte mode, byte lights, bool up, byte driver, byte leader)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			MessageRelay.RelayModule<OrbitalStateMessage, OrbitalStateData>(new OrbitalStateData
			{
				Id = Id(root),
				Radar = radar,
				Near = root.position,
				Mode = mode,
				Lights = lights,
				Up = up,
				Driver = driver,
				Leader = leader
			}, CommonMessageRoutes.ReliableToOtherClients);
		}
	}
	internal class OrbitalPoseData : INetSerializable
	{
		public ushort Id;

		public bool Radar;

		public Vector3 Pos;

		public Quaternion Rot;

		public float Speed;

		public float Steer;

		public byte Flags;

		public int? GetSize()
		{
			return 40;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Radar);
			NetSerializerUnityExtensions.SerializeValue(s, ref Pos);
			NetSerializerUnityExtensions.SerializeValue(s, ref Rot);
			s.SerializeValue(ref Speed);
			s.SerializeValue(ref Steer);
			s.SerializeValue(ref Flags);
		}
	}
	internal class OrbitalStateData : INetSerializable
	{
		public ushort Id;

		public bool Radar;

		public bool Up;

		public Vector3 Near;

		public byte Mode;

		public byte Lights;

		public byte Driver;

		public byte Leader;

		public int? GetSize()
		{
			return 20;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Radar);
			s.SerializeValue(ref Up);
			NetSerializerUnityExtensions.SerializeValue(s, ref Near);
			s.SerializeValue(ref Mode);
			s.SerializeValue(ref Lights);
			s.SerializeValue(ref Driver);
			s.SerializeValue(ref Leader);
		}
	}
	internal class OrbitalPoseMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID)
				{
					OrbitalPoseData orbitalPoseData = ((ReceivedMessage)(ref received)).ReadData<OrbitalPoseData>();
					if (orbitalPoseData != null)
					{
						Trucks.Find(orbitalPoseData.Id, orbitalPoseData.Radar, orbitalPoseData.Pos)?.OnPose(orbitalPoseData.Pos, orbitalPoseData.Rot, orbitalPoseData.Speed, orbitalPoseData.Steer, orbitalPoseData.Flags);
					}
				}
			}
			catch
			{
			}
		}
	}
	internal class OrbitalStateMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID)
				{
					OrbitalStateData orbitalStateData = ((ReceivedMessage)(ref received)).ReadData<OrbitalStateData>();
					if (orbitalStateData != null)
					{
						Trucks.Find(orbitalStateData.Id, orbitalStateData.Radar, orbitalStateData.Near)?.OnState(orbitalStateData.Mode, orbitalStateData.Lights, orbitalStateData.Up, orbitalStateData.Driver, orbitalStateData.Leader);
					}
				}
			}
			catch
			{
			}
		}
	}
	internal sealed class GameWorld : ITruckWorld
	{
		private readonly Transform _self;

		private static readonly Il2CppStructArray<RaycastHit> Hits = new Il2CppStructArray<RaycastHit>(32L);

		public GameWorld(Transform self)
		{
			_self = self;
		}

		private bool Solid(RaycastHit h)
		{
			Collider collider = ((RaycastHit)(ref h)).collider;
			if ((Object)(object)collider == (Object)null || ((Component)collider).transform.IsChildOf(_self))
			{
				return false;
			}
			Rigidbody attachedRigidbody = collider.attachedRigidbody;
			if (!((Object)(object)attachedRigidbody == (Object)null) && !attachedRigidbody.isKinematic)
			{
				return attachedRigidbody.mass >= 1000f;
			}
			return true;
		}

		public bool Ground(Vector3 from, float down, float ceilingY, out Vector3 point, out Vector3 normal)
		{
			//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)
			//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_0024: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a0: 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)
			point = from;
			normal = Vector3.up;
			float num = float.MinValue;
			float