Decompiled source of LethalMario64 v0.6.2

LethalMario64.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalMario64")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalMario64")]
[assembly: AssemblyTitle("LethalMario64")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 LethalMario64
{
	internal class CollisionStreamer
	{
		private struct Tracked
		{
			public Collider collider;

			public Matrix4x4 matrix;
		}

		private class CachedTris
		{
			public Matrix4x4 matrix;

			public Vector3[] world;

			public Dictionary<long, List<int>> cells;

			public List<int> always;

			public int[] seenStamp;

			public int stamp;
		}

		private const float HalfExtent = 24f;

		private const float ReloadDistance = 9f;

		private const float DirtyCheckInterval = 0.3f;

		private const float ShipLoadDistance = 60f;

		private const int NoisyScore = 30;

		private const int GridMinTriangles = 2000;

		private const float GridCell = 16f;

		private readonly List<Vector3> gridScratch = new List<Vector3>(16384);

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

		private readonly List<Tracked> trackedStatic = new List<Tracked>();

		private readonly List<Tracked> trackedShip = new List<Tracked>();

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

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

		private readonly List<Native.Surface> staticSurfaces = new List<Native.Surface>(8192);

		private readonly List<Native.Surface> shipSurfaces = new List<Native.Surface>(16384);

		private readonly Collider[] overlap = (Collider[])(object)new Collider[4096];

		private Vector3 loadCenter;

		private bool loaded;

		private bool staticDirty;

		private bool shipDirty;

		private float nextDirtyCheck;

		private float nextTriggerLog;

		private uint shipObject;

		private bool hasShipObject;

		private bool shipWanted;

		private Transform ship;

		private Vector3 lastShipWorld;

		public float LastStaticReload;

		public float LastShipReload;

		public int ShipTriangles;

		private static int cachedMask;

		private static int cachedMaskLayer = -1;

		private static readonly HashSet<string> loggedMeshes = new HashSet<string>();

		private static readonly int[] BoxFaces = new int[36]
		{
			0, 1, 3, 0, 3, 2, 4, 6, 7, 4,
			7, 5, 0, 4, 5, 0, 5, 1, 2, 3,
			7, 2, 7, 6, 0, 2, 6, 0, 6, 4,
			1, 5, 7, 1, 7, 3
		};

		private const float MaxEdgeSM = 2000f;

		private const short SurfaceDefault = 0;

		private const short SurfaceBurning = 1;

		public bool CarryingMario;

		public bool Loaded => loaded;

		public bool HasShip => hasShipObject;

		internal static int PlayerMask
		{
			get
			{
				PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
				if ((Object)(object)val == (Object)null)
				{
					if (!((Object)(object)StartOfRound.Instance != (Object)null))
					{
						return -1;
					}
					return StartOfRound.Instance.allPlayersCollideWithMask;
				}
				int layer = ((Component)val).gameObject.layer;
				if (layer != cachedMaskLayer)
				{
					int num = 0;
					for (int i = 0; i < 32; i++)
					{
						if (!Physics.GetIgnoreLayerCollision(layer, i))
						{
							num |= 1 << i;
						}
					}
					cachedMask = num;
					cachedMaskLayer = layer;
					Plugin.Log.LogDebug((object)("Player collision layers: " + LayerList(num)));
				}
				return cachedMask;
			}
		}

		private static long CellKey(int x, int z)
		{
			return ((long)x << 32) ^ (uint)z;
		}

		private static void BuildGrid(CachedTris ct)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00c5: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			int num = ct.world.Length / 3;
			if (num < 2000)
			{
				return;
			}
			ct.cells = new Dictionary<long, List<int>>();
			ct.always = new List<int>();
			ct.seenStamp = new int[num];
			for (int i = 0; i < num; i++)
			{
				Vector3 val = ct.world[3 * i];
				Vector3 val2 = ct.world[3 * i + 1];
				Vector3 val3 = ct.world[3 * i + 2];
				int num2 = Mathf.FloorToInt(Mathf.Min(val.x, Mathf.Min(val2.x, val3.x)) / 16f);
				int num3 = Mathf.FloorToInt(Mathf.Max(val.x, Mathf.Max(val2.x, val3.x)) / 16f);
				int num4 = Mathf.FloorToInt(Mathf.Min(val.z, Mathf.Min(val2.z, val3.z)) / 16f);
				int num5 = Mathf.FloorToInt(Mathf.Max(val.z, Mathf.Max(val2.z, val3.z)) / 16f);
				if ((long)(num3 - num2 + 1) * (long)(num5 - num4 + 1) > 256)
				{
					ct.always.Add(i);
					continue;
				}
				for (int j = num2; j <= num3; j++)
				{
					for (int k = num4; k <= num5; k++)
					{
						long key = CellKey(j, k);
						if (!ct.cells.TryGetValue(key, out var value))
						{
							value = (ct.cells[key] = new List<int>());
						}
						value.Add(i);
					}
				}
			}
		}

		private Vector3[] Candidates(CachedTris ct, Bounds region)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if (ct.cells == null)
			{
				return ct.world;
			}
			ct.stamp++;
			gridScratch.Clear();
			int num = Mathf.FloorToInt(((Bounds)(ref region)).min.x / 16f);
			int num2 = Mathf.FloorToInt(((Bounds)(ref region)).max.x / 16f);
			int num3 = Mathf.FloorToInt(((Bounds)(ref region)).min.z / 16f);
			int num4 = Mathf.FloorToInt(((Bounds)(ref region)).max.z / 16f);
			for (int i = num; i <= num2; i++)
			{
				for (int j = num3; j <= num4; j++)
				{
					if (!ct.cells.TryGetValue(CellKey(i, j), out var value))
					{
						continue;
					}
					foreach (int item in value)
					{
						if (ct.seenStamp[item] != ct.stamp)
						{
							ct.seenStamp[item] = ct.stamp;
							gridScratch.Add(ct.world[3 * item]);
							gridScratch.Add(ct.world[3 * item + 1]);
							gridScratch.Add(ct.world[3 * item + 2]);
						}
					}
				}
			}
			foreach (int alway in ct.always)
			{
				gridScratch.Add(ct.world[3 * alway]);
				gridScratch.Add(ct.world[3 * alway + 1]);
				gridScratch.Add(ct.world[3 * alway + 2]);
			}
			return gridScratch.ToArray();
		}

		public void MarkDirty()
		{
			staticDirty = true;
			shipDirty = true;
		}

		public unsafe void Clear()
		{
			if (loaded && SM64Context.Ready)
			{
				Native.sm64_static_surfaces_load(null, 0u);
			}
			DeleteShip();
			shipWanted = false;
			trackedStatic.Clear();
			trackedShip.Clear();
			cache.Clear();
			moveCounts.Clear();
			noisy.Clear();
			loaded = false;
		}

		public void Update(Vector3 focus)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_009f: 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_00df: 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)
			ship = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null);
			if (loaded && Time.time >= nextDirtyCheck)
			{
				nextDirtyCheck = Time.time + 0.3f;
				if (Moved(trackedStatic, shipRelative: false))
				{
					staticDirty = true;
				}
				if (Moved(trackedShip, shipRelative: true))
				{
					shipDirty = true;
				}
			}
			Vector3 val = focus - loadCenter;
			Vector2 val2 = new Vector2(val.x, val.z);
			bool flag = ((Vector2)(ref val2)).magnitude > 9f || Mathf.Abs(val.y) > 9f;
			if (!loaded || flag || staticDirty)
			{
				ReloadStatic(focus);
			}
			bool flag2 = (Object)(object)ship != (Object)null && Vector3.Distance(focus, ship.position) < 60f;
			if (flag2 != shipWanted || (flag2 && shipDirty))
			{
				shipWanted = flag2;
				ReloadShip();
			}
			MoveShip();
		}

		private unsafe void ReloadStatic(Vector3 focus)
		{
			//IL_001a: 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_0020: 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)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0099: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			LastStaticReload = Time.time;
			staticDirty = false;
			loaded = true;
			loadCenter = focus;
			SM64Context.SetOrigin(new Vector3(Mathf.Round(focus.x), Mathf.Round(focus.y), Mathf.Round(focus.z)));
			RebaseShip();
			Bounds val = default(Bounds);
			((Bounds)(ref val))..ctor(focus, Vector3.one * 24f * 2f);
			int playerMask = PlayerMask;
			staticSurfaces.Clear();
			trackedStatic.Clear();
			int num = Physics.OverlapBoxNonAlloc(focus, Vector3.one * 24f, overlap, Quaternion.identity, playerMask, (QueryTriggerInteraction)1);
			int meshes = 0;
			int boxes = 0;
			int num2 = 0;
			int approx = 0;
			for (int i = 0; i < num; i++)
			{
				Collider val2 = overlap[i];
				if (!Usable(val2) || noisy.Contains(((Object)val2).GetInstanceID()) || ((Object)(object)ship != (Object)null && ((Component)val2).transform.IsChildOf(ship)))
				{
					continue;
				}
				TerrainCollider val3 = (TerrainCollider)(object)((val2 is TerrainCollider) ? val2 : null);
				if (val3 != null)
				{
					AddTerrain(val3, val, TerrainFor(val2));
					num2++;
				}
				else
				{
					CachedTris cachedTris = Triangles(val2, ref meshes, ref boxes, ref approx);
					if (cachedTris == null)
					{
						continue;
					}
					AddTriangles(Candidates(cachedTris, val), staticSurfaces, val, null, TerrainFor(val2), (short)(IsLava(val2) ? 1 : 0));
				}
				trackedStatic.Add(new Tracked
				{
					collider = val2,
					matrix = ((Component)val2).transform.localToWorldMatrix
				});
			}
			AddLavaVolumes(focus, val);
			Native.Surface[] array = staticSurfaces.ToArray();
			fixed (Native.Surface* surfaces = array)
			{
				Native.sm64_static_surfaces_load(surfaces, (uint)array.Length);
			}
			Plugin.Log.LogDebug((object)($"Collision reload: {array.Length} static tris from {trackedStatic.Count} colliders " + $"(new: mesh {meshes}, box {boxes}, terrain {num2}, approx {approx})."));
		}

		private unsafe void ReloadShip()
		{
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			shipDirty = false;
			DeleteShip();
			trackedShip.Clear();
			if (!shipWanted || (Object)(object)ship == (Object)null)
			{
				return;
			}
			shipSurfaces.Clear();
			int playerMask = PlayerMask;
			int meshes = 0;
			int boxes = 0;
			int approx = 0;
			Collider[] componentsInChildren = ((Component)ship).GetComponentsInChildren<Collider>();
			foreach (Collider val in componentsInChildren)
			{
				if (((1 << ((Component)val).gameObject.layer) & playerMask) != 0 && ((Component)val).gameObject.activeInHierarchy && Usable(val) && !noisy.Contains(((Object)val).GetInstanceID()))
				{
					CachedTris cachedTris = Triangles(val, ref meshes, ref boxes, ref approx);
					if (cachedTris != null)
					{
						AddTriangles(cachedTris.world, shipSurfaces, null, ship.position, TerrainFor(val), 0);
						trackedShip.Add(new Tracked
						{
							collider = val,
							matrix = ship.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix
						});
					}
				}
			}
			if (shipSurfaces.Count != 0)
			{
				Native.Surface[] array = shipSurfaces.ToArray();
				fixed (Native.Surface* surfaces = array)
				{
					Native.SurfaceObject surfaceObject = new Native.SurfaceObject
					{
						transform = ShipTransform(),
						surfaceCount = (uint)array.Length,
						surfaces = surfaces
					};
					shipObject = Native.sm64_surface_object_create(&surfaceObject);
					hasShipObject = true;
					lastShipWorld = ship.position;
				}
				ShipTriangles = array.Length;
				LastShipReload = Time.time;
				Plugin.Log.LogDebug((object)$"Ship collision: {array.Length} tris from {trackedShip.Count} colliders.");
			}
		}

		private static string LayerList(int mask)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < 32; i++)
			{
				if ((mask & (1 << i)) != 0)
				{
					list.Add(string.IsNullOrEmpty(LayerMask.LayerToName(i)) ? i.ToString() : LayerMask.LayerToName(i));
				}
			}
			return string.Join(", ", list);
		}

		internal static bool Usable(Collider c)
		{
			if ((Object)(object)c == (Object)null || !c.enabled || c.isTrigger || c is CharacterController)
			{
				return false;
			}
			Rigidbody attachedRigidbody = c.attachedRigidbody;
			if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.isKinematic)
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<PlayerControllerB>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<GrabbableObject>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<EnemyAI>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<DeadBodyInfo>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)c).GetComponentInParent<UnlockableSuit>() != (Object)null)
			{
				return false;
			}
			return true;
		}

		private static bool IsLava(Collider c)
		{
			string name = ((Object)c).name;
			if (name.IndexOf("lava", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("magma", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return ((Component)c).CompareTag("Lava");
			}
			return true;
		}

		private void AddLavaVolumes(Vector3 focus, Bounds region)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapBoxNonAlloc(focus, Vector3.one * 24f, overlap, Quaternion.identity, -1, (QueryTriggerInteraction)2);
			Vector3 val2 = default(Vector3);
			Vector3 val3 = default(Vector3);
			Vector3 val4 = default(Vector3);
			Vector3 val5 = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				Collider val = overlap[i];
				if (!((Object)(object)val == (Object)null) && val.enabled && val.isTrigger && IsLava(val))
				{
					Bounds bounds = val.bounds;
					float y = ((Bounds)(ref bounds)).max.y;
					((Vector3)(ref val2))..ctor(((Bounds)(ref bounds)).min.x, y, ((Bounds)(ref bounds)).min.z);
					((Vector3)(ref val3))..ctor(((Bounds)(ref bounds)).min.x, y, ((Bounds)(ref bounds)).max.z);
					((Vector3)(ref val4))..ctor(((Bounds)(ref bounds)).max.x, y, ((Bounds)(ref bounds)).max.z);
					((Vector3)(ref val5))..ctor(((Bounds)(ref bounds)).max.x, y, ((Bounds)(ref bounds)).min.z);
					AddTriangles((Vector3[])(object)new Vector3[6] { val2, val3, val4, val2, val4, val5 }, staticSurfaces, region, null, 1, 1);
				}
			}
		}

		private static ushort TerrainFor(Collider c)
		{
			switch (((Component)c).tag)
			{
			case "Grass":
				return 0;
			case "Snow":
				return 2;
			case "Gravel":
			case "Sand":
				return 3;
			case "Wood":
			case "Carpet":
				return 4;
			case "Puddle":
				return 5;
			default:
				return 1;
			}
		}

		private CachedTris Triangles(Collider c, ref int meshes, ref int boxes, ref int approx)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 localToWorldMatrix = ((Component)c).transform.localToWorldMatrix;
			int instanceID = ((Object)c).GetInstanceID();
			if (cache.TryGetValue(instanceID, out var value) && value.matrix == localToWorldMatrix)
			{
				return value;
			}
			Vector3[] array = null;
			MeshCollider val = (MeshCollider)(object)((c is MeshCollider) ? c : null);
			Bounds bounds;
			if (val == null)
			{
				BoxCollider val2 = (BoxCollider)(object)((c is BoxCollider) ? c : null);
				if (val2 == null)
				{
					goto IL_0191;
				}
				array = BoxTris(val2.center, val2.size * 0.5f, localToWorldMatrix);
				boxes++;
			}
			else
			{
				if (!((Object)(object)val.sharedMesh != (Object)null))
				{
					goto IL_0191;
				}
				MeshData data;
				switch (MeshData.TryGet(val.sharedMesh, out data))
				{
				case MeshData.State.Pending:
					return null;
				case MeshData.State.Ready:
				{
					array = (Vector3[])(object)new Vector3[data.Triangles.Length];
					for (int i = 0; i < array.Length; i++)
					{
						array[i] = ((Component)c).transform.TransformPoint(data.Vertices[data.Triangles[i]]);
					}
					FixWinding(array, localToWorldMatrix, ((Object)val.sharedMesh).name);
					meshes++;
					break;
				}
				default:
				{
					bounds = c.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					object array2;
					if (!(size.x < 6f) || !(size.y < 6f) || !(size.z < 6f))
					{
						array2 = new Vector3[0];
					}
					else
					{
						bounds = c.bounds;
						Vector3 center = ((Bounds)(ref bounds)).center;
						bounds = c.bounds;
						array2 = BoxTris(center, ((Bounds)(ref bounds)).extents, Matrix4x4.identity);
					}
					array = (Vector3[])array2;
					approx++;
					break;
				}
				}
			}
			goto IL_01c2;
			IL_01c2:
			CachedTris cachedTris = new CachedTris
			{
				matrix = localToWorldMatrix,
				world = array
			};
			BuildGrid(cachedTris);
			cache[instanceID] = cachedTris;
			return cachedTris;
			IL_0191:
			bounds = c.bounds;
			Vector3 center2 = ((Bounds)(ref bounds)).center;
			bounds = c.bounds;
			array = BoxTris(center2, ((Bounds)(ref bounds)).extents, Matrix4x4.identity);
			approx++;
			goto IL_01c2;
		}

		private static void FixWinding(Vector3[] tris, Matrix4x4 m, string meshName)
		{
			//IL_002e: 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_0045: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ((Matrix4x4)(ref m)).determinant < 0f;
			if (flag)
			{
				Flip(tris);
			}
			float num = 0f;
			float num2 = 0f;
			for (int i = 0; i + 2 < tris.Length; i += 3)
			{
				Vector3 val = Vector3.Cross(tris[i + 1] - tris[i], tris[i + 2] - tris[i]);
				num += val.y;
				num2 += ((Vector3)(ref val)).magnitude;
			}
			float num3 = ((num2 > 0f) ? (num / num2) : 0f);
			bool flag2 = num3 < -0.3f;
			if (flag2)
			{
				Flip(tris);
			}
			if (loggedMeshes.Add(meshName))
			{
				Plugin.Log.LogDebug((object)string.Format("Mesh '{0}': {1} tris, facing {2:F2}{3}{4}.", meshName, tris.Length / 3, num3, flag ? ", mirrored" : "", flag2 ? ", flipped (was upside down)" : ""));
			}
		}

		private static void Flip(Vector3[] tris)
		{
			//IL_001b: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			for (int i = 0; i + 2 < tris.Length; i += 3)
			{
				ref Vector3 reference = ref tris[i + 1];
				ref Vector3 reference2 = ref tris[i + 2];
				Vector3 val = tris[i + 2];
				Vector3 val2 = tris[i + 1];
				reference = val;
				reference2 = val2;
			}
		}

		private static Vector3[] BoxTris(Vector3 center, Vector3 ext, Matrix4x4 m)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_002e: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			for (int i = 0; i < 8; i++)
			{
				Vector3 val = center + new Vector3(((i & 4) != 0) ? ext.x : (0f - ext.x), ((i & 2) != 0) ? ext.y : (0f - ext.y), ((i & 1) != 0) ? ext.z : (0f - ext.z));
				array[i] = ((Matrix4x4)(ref m)).MultiplyPoint3x4(val);
			}
			Vector3 val2 = ((Matrix4x4)(ref m)).MultiplyPoint3x4(center);
			Vector3[] array2 = (Vector3[])(object)new Vector3[36];
			for (int j = 0; j < 36; j += 3)
			{
				Vector3 val3 = array[BoxFaces[j]];
				Vector3 val4 = array[BoxFaces[j + 1]];
				Vector3 val5 = array[BoxFaces[j + 2]];
				if (Vector3.Dot(Vector3.Cross(val4 - val3, val5 - val3), (val3 + val4 + val5) / 3f - val2) < 0f)
				{
					Vector3 val6 = val5;
					Vector3 val7 = val4;
					val4 = val6;
					val5 = val7;
				}
				array2[j] = val3;
				array2[j + 1] = val4;
				array2[j + 2] = val5;
			}
			return array2;
		}

		private void AddTerrain(TerrainCollider tc, Bounds region, ushort terrainType)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			TerrainData td = tc.terrainData;
			if ((Object)(object)td == (Object)null)
			{
				return;
			}
			Vector3 origin = ((Component)tc).transform.position;
			Vector3 sc = td.heightmapScale;
			int heightmapResolution = td.heightmapResolution;
			int num = Mathf.Clamp(Mathf.FloorToInt((((Bounds)(ref region)).min.x - origin.x) / sc.x), 0, heightmapResolution - 1);
			int num2 = Mathf.Clamp(Mathf.CeilToInt((((Bounds)(ref region)).max.x - origin.x) / sc.x), 0, heightmapResolution - 1);
			int num3 = Mathf.Clamp(Mathf.FloorToInt((((Bounds)(ref region)).min.z - origin.z) / sc.z), 0, heightmapResolution - 1);
			int num4 = Mathf.Clamp(Mathf.CeilToInt((((Bounds)(ref region)).max.z - origin.z) / sc.z), 0, heightmapResolution - 1);
			if (num2 <= num || num4 <= num3)
			{
				return;
			}
			int num5 = (((num2 - num) * (num4 - num3) <= 40000) ? 1 : 2);
			List<Vector3> list = new List<Vector3>();
			for (int i = num; i < num2; i += num5)
			{
				for (int j = num3; j < num4; j += num5)
				{
					int i2 = Mathf.Min(i + num5, heightmapResolution - 1);
					int j2 = Mathf.Min(j + num5, heightmapResolution - 1);
					Vector3 item = P(i, j);
					Vector3 item2 = P(i, j2);
					Vector3 item3 = P(i2, j2);
					Vector3 item4 = P(i2, j);
					list.Add(item);
					list.Add(item2);
					list.Add(item3);
					list.Add(item);
					list.Add(item3);
					list.Add(item4);
				}
			}
			AddTriangles(list.ToArray(), staticSurfaces, null, null, terrainType, 0);
			Vector3 P(int num6, int num7)
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				return new Vector3(origin.x + (float)num6 * sc.x, origin.y + td.GetHeight(num6, num7), origin.z + (float)num7 * sc.z);
			}
		}

		private static void AddTriangles(Vector3[] world, List<Native.Surface> into, Bounds? region, Vector3? relativeTo, ushort terrain, short type = 0)
		{
			//IL_001a: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			float scale = SM64Context.Scale;
			Vector3 o = (Vector3)(((??)relativeTo) ?? SM64Context.Origin);
			float num = 2000f / scale;
			for (int i = 0; i + 2 < world.Length; i += 3)
			{
				Emit(world[i], world[i + 1], world[i + 2], into, region, o, scale, terrain, num * num, 0, type);
			}
		}

		private static void Emit(Vector3 a, Vector3 b, Vector3 c, List<Native.Surface> into, Bounds? region, Vector3 o, float s, ushort terrain, float maxEdgeSq, int depth, short type)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00d5: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_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)
			//IL_0022: 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_0026: 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_0031: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0158: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (region.HasValue)
			{
				Bounds value = region.Value;
				Vector3 val = Vector3.Min(a, Vector3.Min(b, c));
				Vector3 val2 = Vector3.Max(a, Vector3.Max(b, c));
				if (val2.x < ((Bounds)(ref value)).min.x || val.x > ((Bounds)(ref value)).max.x || val2.y < ((Bounds)(ref value)).min.y || val.y > ((Bounds)(ref value)).max.y || val2.z < ((Bounds)(ref value)).min.z || val.z > ((Bounds)(ref value)).max.z)
				{
					return;
				}
			}
			Vector3 val3 = b - a;
			float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
			val3 = c - b;
			float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude;
			val3 = a - c;
			float sqrMagnitude3 = ((Vector3)(ref val3)).sqrMagnitude;
			if (Mathf.Max(sqrMagnitude, Mathf.Max(sqrMagnitude2, sqrMagnitude3)) > maxEdgeSq && depth < 24)
			{
				if (sqrMagnitude >= sqrMagnitude2 && sqrMagnitude >= sqrMagnitude3)
				{
					Vector3 val4 = (a + b) * 0.5f;
					Emit(a, val4, c, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
					Emit(val4, b, c, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
				}
				else if (sqrMagnitude2 >= sqrMagnitude3)
				{
					Vector3 val5 = (b + c) * 0.5f;
					Emit(a, b, val5, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
					Emit(a, val5, c, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
				}
				else
				{
					Vector3 val6 = (c + a) * 0.5f;
					Emit(a, b, val6, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
					Emit(val6, b, c, into, region, o, s, terrain, maxEdgeSq, depth + 1, type);
				}
				return;
			}
			Vector3Int val7 = ToSMInt(a, o, s);
			Vector3Int val8 = ToSMInt(c, o, s);
			Vector3Int val9 = ToSMInt(b, o, s);
			Vector3 val10 = Vector3.Cross(Vector3Int.op_Implicit(val8 - val7), Vector3Int.op_Implicit(val9 - val7));
			if (!(((Vector3)(ref val10)).sqrMagnitude < 1f))
			{
				into.Add(new Native.Surface
				{
					type = type,
					force = 0,
					terrain = terrain,
					v0x = ((Vector3Int)(ref val7)).x,
					v0y = ((Vector3Int)(ref val7)).y,
					v0z = ((Vector3Int)(ref val7)).z,
					v1x = ((Vector3Int)(ref val8)).x,
					v1y = ((Vector3Int)(ref val8)).y,
					v1z = ((Vector3Int)(ref val8)).z,
					v2x = ((Vector3Int)(ref val9)).x,
					v2y = ((Vector3Int)(ref val9)).y,
					v2z = ((Vector3Int)(ref val9)).z
				});
			}
		}

		private static Vector3Int ToSMInt(Vector3 u, Vector3 origin, float s)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0029: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3Int(Mathf.RoundToInt((0f - (u.x - origin.x)) * s), Mathf.RoundToInt((u.y - origin.y) * s), Mathf.RoundToInt((u.z - origin.z) * s));
		}

		private Native.ObjectTransform ShipTransform()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = SM64Context.ToSM(ship.position);
			return new Native.ObjectTransform
			{
				px = val.x,
				py = val.y,
				pz = val.z
			};
		}

		private unsafe void MoveShip()
		{
			//IL_0049: 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)
			if (hasShipObject && !((Object)(object)ship == (Object)null))
			{
				Native.ObjectTransform objectTransform = ShipTransform();
				Native.sm64_surface_object_move(shipObject, &objectTransform);
				if (CarryingMario)
				{
					Native.sm64_surface_object_move(shipObject, &objectTransform);
				}
				lastShipWorld = ship.position;
			}
		}

		private unsafe void RebaseShip()
		{
			//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_0014: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (hasShipObject)
			{
				Vector3 val = SM64Context.ToSM(lastShipWorld);
				Native.ObjectTransform objectTransform = new Native.ObjectTransform
				{
					px = val.x,
					py = val.y,
					pz = val.z
				};
				Native.sm64_surface_object_move(shipObject, &objectTransform);
			}
		}

		private void DeleteShip()
		{
			if (hasShipObject && SM64Context.Ready)
			{
				Native.sm64_surface_object_delete(shipObject);
			}
			hasShipObject = false;
		}

		private bool Moved(List<Tracked> list, bool shipRelative)
		{
			//IL_0074: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			for (int num = list.Count - 1; num >= 0; num--)
			{
				Tracked tracked = list[num];
				Collider collider = tracked.collider;
				if ((Object)(object)collider == (Object)null)
				{
					flag = true;
					list.RemoveAt(num);
				}
				else
				{
					int instanceID = ((Object)collider).GetInstanceID();
					bool flag2 = !collider.enabled || !((Component)collider).gameObject.activeInHierarchy;
					if (!flag2)
					{
						flag2 = !Approximately((shipRelative && (Object)(object)ship != (Object)null) ? (ship.worldToLocalMatrix * ((Component)collider).transform.localToWorldMatrix) : ((Component)collider).transform.localToWorldMatrix, tracked.matrix);
					}
					moveCounts.TryGetValue(instanceID, out var value);
					if (!flag2)
					{
						if (value > 0)
						{
							moveCounts[instanceID] = value - 1;
						}
					}
					else
					{
						value += 2;
						moveCounts[instanceID] = value;
						if (value >= 30)
						{
							noisy.Add(instanceID);
							list.RemoveAt(num);
							ManualLogSource log = Plugin.Log;
							string name = ((Object)collider).name;
							string name2 = ((Object)((Component)collider).transform.root).name;
							Bounds bounds = collider.bounds;
							log.LogDebug((object)$"Treating constantly-moving collider '{name}' ({name2}, size {((Bounds)(ref bounds)).size}) as non-solid.");
							flag = true;
						}
						else
						{
							if (!flag && Time.time >= nextTriggerLog)
							{
								nextTriggerLog = Time.time + 2f;
								Plugin.Log.LogDebug((object)((shipRelative ? "Ship" : "Level") + " collision rebuild triggered by '" + ((Object)collider).name + "' (" + ((Object)((Component)collider).transform.root).name + ")."));
							}
							flag = true;
						}
					}
				}
			}
			return flag;
		}

		private static bool Approximately(Matrix4x4 a, Matrix4x4 b)
		{
			for (int i = 0; i < 16; i++)
			{
				if (Mathf.Abs(((Matrix4x4)(ref a))[i] - ((Matrix4x4)(ref b))[i]) > 0.001f)
				{
					return false;
				}
			}
			return true;
		}
	}
	internal static class LocalMario
	{
		private static MarioInstance mario;

		private static float nextCreateAttempt;

		private static float orbitYaw;

		private static float orbitPitch = 15f;

		private static bool firstPerson;

		private static int zoomIndex = 1;

		private static readonly float[] ZoomLevels = new float[3] { 0.6f, 1f, 1.6f };

		private static float yawSnapRemaining;

		private static float lastLookTime;

		private static bool cameraMoved;

		private static Vector3 savedCameraPos;

		private static float nextRotationSync;

		private static bool gameDisabledMove;

		private static Vector3 lastAppliedPos;

		private static bool applied;

		private static float suppressHealthDamageUntil;

		private static int lostHealthUnits;

		private static float nextNoise;

		private static readonly List<Renderer> hiddenRenderers = new List<Renderer>();

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

		private static readonly Collider[] hitBuffer = (Collider[])(object)new Collider[64];

		private static readonly FieldRef<PlayerControllerB, float> CameraUp = AccessTools.FieldRefAccess<PlayerControllerB, float>("cameraUp");

		private static readonly MethodInfo RotationRpc = AccessTools.Method(typeof(PlayerControllerB), "UpdatePlayerRotationServerRpc", (Type[])null, (Type[])null);

		private static InputAction moveAction;

		private static InputAction jumpAction;

		private static InputAction crouchAction;

		private static InputAction activateAction;

		private static InputAction lookAction;

		private static Vector3 lastShipTickPos;

		private static float lastShipMoveTime = -10f;

		private static bool haveShipTickPos;

		private static Vector3 safeLocal;

		private static bool safeOnShip;

		private static bool haveSafe;

		private static float nextSafeSample;

		private static float nextUnstuck;

		private static readonly RaycastHit[] groundHits = (RaycastHit[])(object)new RaycastHit[32];

		private static readonly Collider[] headroomHits = (Collider[])(object)new Collider[32];

		private static Vector3 lastShipFramePos;

		private const uint MARIO_WING_CAP = 8u;

		private const uint MARIO_CAP_ON_HEAD = 16u;

		private static QuicksandTrigger[] waterTriggers = (QuicksandTrigger[])(object)new QuicksandTrigger[0];

		private static float nextWaterScan;

		public static bool Active { get; private set; }

		public static bool Suspended { get; private set; }

		public static PlayerControllerB Player { get; private set; }

		private static Transform Ship
		{
			get
			{
				if (!((Object)(object)StartOfRound.Instance != (Object)null))
				{
					return null;
				}
				return StartOfRound.Instance.elevatorTransform;
			}
		}

		public static bool IsMarioSuit(PlayerControllerB p)
		{
			List<UnlockableItem> list = StartOfRound.Instance?.unlockablesList?.unlockables;
			if (list == null || p.currentSuitID < 0 || p.currentSuitID >= list.Count)
			{
				return false;
			}
			return list[p.currentSuitID].unlockableName?.StartsWith(Plugin.SuitName.Value, StringComparison.OrdinalIgnoreCase) ?? false;
		}

		private static bool ShouldBeSuspended(PlayerControllerB p)
		{
			if (!p.inSpecialInteractAnimation && !p.isClimbingLadder && !p.inTerminalMenu && !p.jetpackControls && !p.inVehicleAnimation)
			{
				return p.isFreeCamera;
			}
			return true;
		}

		public static void RefreshActive()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			bool flag = (Object)(object)localPlayerController != (Object)null && !SM64Context.Failed && IsMarioSuit(localPlayerController) && localPlayerController.isPlayerControlled && !localPlayerController.isPlayerDead;
			if (Active && (!flag || (Object)(object)localPlayerController != (Object)(object)Player))
			{
				Deactivate((Object)(object)Player != (Object)null && Player.isPlayerControlled && !Player.isPlayerDead);
			}
			if (!Active && flag && Time.time >= nextCreateAttempt)
			{
				Activate(localPlayerController);
			}
			if (!Active)
			{
				return;
			}
			bool flag2 = ShouldBeSuspended(Player);
			if (flag2 != Suspended)
			{
				Suspended = flag2;
				if (flag2)
				{
					NormalizeFirstPersonCamera();
					return;
				}
				orbitYaw = ((Component)Player).transform.eulerAngles.y;
				Snap(((Component)Player).transform.position);
			}
		}

		private static void Activate(PlayerControllerB p)
		{
			//IL_0045: 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)
			//IL_005a: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			nextCreateAttempt = Time.time + 1f;
			if (SM64Context.EnsureInit(((Object)(object)p.thisPlayerModel != (Object)null) ? ((Renderer)p.thisPlayerModel).sharedMaterial : null))
			{
				Player = p;
				CacheInputActions();
				Vector3 position = ((Component)p).transform.position;
				SM64Context.Collision.Clear();
				SM64Context.Collision.Update(position);
				MarioInstance marioInstance = new MarioInstance(position + Vector3.up * 0.05f, "Mario (local)");
				if (!marioInstance.Valid)
				{
					Plugin.Log.LogWarning((object)"Couldn't spawn Mario here (no floor under the player yet). Retrying...");
					marioInstance.Destroy();
					SM64Context.Collision.Clear();
					Player = null;
					return;
				}
				mario = marioInstance;
				SM64Context.Instances.Add(mario);
				mario.Visible = true;
				ApplySavedSkin();
				Native.sm64_set_mario_faceangle(mario.Id, SM64Context.YawToSM(((Component)p).transform.eulerAngles.y));
				Native.sm64_play_sound_global(604799105);
				orbitYaw = ((Component)p).transform.eulerAngles.y;
				orbitPitch = 15f;
				lostHealthUnits = 0;
				applied = false;
				Suspended = ShouldBeSuspended(p);
				Active = true;
				HideEmployee();
				Plugin.Log.LogInfo((object)"It's-a me, Mario!");
			}
		}

		public static void Deactivate(bool restoreModel)
		{
			if (!Active)
			{
				return;
			}
			SetFirstPerson(on: false);
			Active = false;
			Suspended = false;
			if (mario != null)
			{
				SM64Context.Instances.Remove(mario);
				mario.Destroy();
				mario = null;
			}
			SM64Context.Collision.Clear();
			MarioNet.SendStopped();
			if ((Object)(object)Player != (Object)null)
			{
				GrabbableObject currentlyHeldObjectServer = Player.currentlyHeldObjectServer;
				if ((Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)currentlyHeldObjectServer.parentObject == (Object)(object)Player.serverItemHolder)
				{
					currentlyHeldObjectServer.parentObject = Player.localItemHolder;
				}
				NormalizeFirstPersonCamera();
				if (restoreModel)
				{
					foreach (Renderer hiddenRenderer in hiddenRenderers)
					{
						if ((Object)(object)hiddenRenderer != (Object)null)
						{
							hiddenRenderer.enabled = true;
						}
					}
				}
			}
			hiddenRenderers.Clear();
			Player = null;
		}

		private static void CacheInputActions()
		{
			InputActionAsset actions = InputSystem.actions;
			moveAction = actions.FindAction("Move", false);
			jumpAction = actions.FindAction("Jump", false);
			crouchAction = actions.FindAction("Crouch", false);
			activateAction = actions.FindAction("ActivateItem", false);
			lookAction = actions.FindAction("Look", false);
		}

		private static void HideEmployee()
		{
			hiddenRenderers.Clear();
			Hide((Renderer)(object)Player.thisPlayerModel);
			Hide((Renderer)(object)Player.thisPlayerModelLOD1);
			Hide((Renderer)(object)Player.thisPlayerModelLOD2);
			Hide((Renderer)(object)Player.thisPlayerModelArms);
			if ((Object)(object)Player.localVisor != (Object)null)
			{
				Renderer[] componentsInChildren = ((Component)Player.localVisor).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Hide(componentsInChildren[i]);
				}
			}
			static void Hide(Renderer r)
			{
				if (!((Object)(object)r == (Object)null) && r.enabled)
				{
					r.enabled = false;
					hiddenRenderers.Add(r);
				}
			}
		}

		private static void KeepEmployeeHidden()
		{
			if ((Object)(object)Player.thisPlayerModel != (Object)null)
			{
				((Renderer)Player.thisPlayerModel).enabled = false;
			}
			if ((Object)(object)Player.thisPlayerModelLOD1 != (Object)null)
			{
				((Renderer)Player.thisPlayerModelLOD1).enabled = false;
			}
			if ((Object)(object)Player.thisPlayerModelLOD2 != (Object)null)
			{
				((Renderer)Player.thisPlayerModelLOD2).enabled = false;
			}
			if ((Object)(object)Player.thisPlayerModelArms != (Object)null)
			{
				((Renderer)Player.thisPlayerModelArms).enabled = false;
			}
		}

		private static void NormalizeFirstPersonCamera()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB player = Player;
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.gameplayCamera == (Object)null))
			{
				float y = ((Component)player.gameplayCamera).transform.eulerAngles.y;
				float num = Mathf.Clamp(Mathf.DeltaAngle(0f, ((Component)player.gameplayCamera).transform.eulerAngles.x), -80f, 60f);
				player.thisPlayerBody.eulerAngles = new Vector3(0f, y, 0f);
				((Component)player.gameplayCamera).transform.localEulerAngles = new Vector3(num, 0f, 0f);
				CameraUp.Invoke(player) = num;
			}
		}

		public static void Tick()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || mario == null || (Object)(object)Player == (Object)null)
			{
				return;
			}
			if (Suspended)
			{
				Vector3 position = ((Component)Player).transform.position;
				SM64Context.Collision.Update(position);
				Vector3 val = SM64Context.ToSM(position);
				Native.sm64_set_mario_position(mario.Id, val.x, val.y, val.z);
				Native.sm64_set_mario_velocity(mario.Id, 0f, 0f, 0f);
				Native.sm64_set_mario_forward_velocity(mario.Id, 0f);
				Native.sm64_set_mario_faceangle(mario.Id, SM64Context.YawToSM(((Component)Player).transform.eulerAngles.y));
				mario.Tick(default(Native.MarioInputs));
				Native.sm64_set_mario_health(mario.Id, 2176);
				MarioNet.SendLocalState(Player, mario);
				return;
			}
			CarryWithShip();
			SM64Context.Collision.Update(mario.WorldPos);
			UpdateWaterLevel();
			ApplyCapCostume();
			Native.MarioInputs inputs = ReadInputs();
			if (firstPerson)
			{
				if (inputs.buttonA != 0 || inputs.buttonB != 0 || (mario.State.action & 0x800) != 0)
				{
					SetFirstPerson(on: false);
				}
				else
				{
					Native.sm64_set_mario_faceangle(mario.Id, SM64Context.YawToSM(orbitYaw));
				}
				inputs.stickX = (inputs.stickY = 0f);
				inputs.buttonA = (inputs.buttonB = (inputs.buttonZ = 0));
			}
			mario.Tick(inputs);
			CatchFloorClip();
			RememberSafeGround();
			HandleHealth();
			HandleAttacks();
			MakeNoise();
			MarioNet.SendLocalState(Player, mario);
		}

		private static void CatchFloorClip()
		{
			//IL_0005: 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_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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_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_0050: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			Vector3 prevWorldPos = mario.PrevWorldPos;
			Vector3 worldPos = mario.WorldPos;
			float num = prevWorldPos.y - worldPos.y;
			if (num <= 0.001f)
			{
				return;
			}
			int playerMask = CollisionStreamer.PlayerMask;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(new Vector3(worldPos.x, prevWorldPos.y + 0.3f, worldPos.z), Vector3.down, ref val, num + 0.3f, playerMask, (QueryTriggerInteraction)1) && !(((RaycastHit)(ref val)).normal.y < 0.5f) && !(((RaycastHit)(ref val)).point.y < worldPos.y + 0.2f) && CollisionStreamer.Usable(((RaycastHit)(ref val)).collider))
			{
				Transform ship = Ship;
				if (!((Object)(object)ship != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(ship) || !(Time.time - lastShipMoveTime < 0.5f))
				{
					CollisionStreamer collision = SM64Context.Collision;
					Plugin.Log.LogWarning((object)("Caught Mario falling through '" + ((Object)((RaycastHit)(ref val)).collider).name + "' (" + ((Object)((Component)((RaycastHit)(ref val)).collider).transform.root).name + "); putting him back on top. " + $"[action 0x{mario.State.action:X8}, fell {((RaycastHit)(ref val)).point.y - worldPos.y:F2} m (tick drop {num:F2}), vel y {mario.State.vy:F1}, " + $"inShip {Player.isInElevator}, carrying {collision.CarryingMario}, shipObj {collision.HasShip} ({collision.ShipTriangles} tris, rebuilt {Time.time - collision.LastShipReload:F1}s ago), " + $"static reload {Time.time - collision.LastStaticReload:F1}s ago]"));
					Vector3 val2 = SM64Context.ToSM(((RaycastHit)(ref val)).point);
					Native.sm64_set_mario_position(mario.Id, val2.x, val2.y, val2.z);
					Native.sm64_set_mario_velocity(mario.Id, 0f, 0f, 0f);
					mario.State.px = val2.x;
					mario.State.py = val2.y;
					mario.State.pz = val2.z;
					mario.WorldPos = ((RaycastHit)(ref val)).point;
					SM64Context.Collision.MarkDirty();
				}
			}
		}

		private static void CarryWithShip()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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)
			Transform ship = Ship;
			bool flag = (Object)(object)ship != (Object)null && Player.isInElevator;
			SM64Context.Collision.CarryingMario = flag;
			if ((Object)(object)ship == (Object)null)
			{
				haveShipTickPos = false;
				return;
			}
			Vector3 delta = ship.position - lastShipTickPos;
			if (haveShipTickPos && ((Vector3)(ref delta)).sqrMagnitude > 1E-08f)
			{
				lastShipMoveTime = Time.time;
			}
			if (flag && haveShipTickPos && ((Vector3)(ref delta)).sqrMagnitude > 1E-08f)
			{
				mario.Translate(delta);
			}
			lastShipTickPos = ship.position;
			haveShipTickPos = true;
		}

		private static Vector3 ShipMotionSinceTick()
		{
			//IL_0022: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			Transform ship = Ship;
			if ((Object)(object)ship == (Object)null || !haveShipTickPos || !SM64Context.Collision.CarryingMario)
			{
				return Vector3.zero;
			}
			return ship.position - lastShipTickPos;
		}

		private static void RememberSafeGround()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			if (!(Time.time < nextSafeSample) && (mario.State.action & 0x800) == 0)
			{
				nextSafeSample = Time.time + 0.5f;
				Vector3 worldPos = mario.WorldPos;
				if (FindGround(mask: CollisionStreamer.PlayerMask, from: worldPos + Vector3.up * 0.5f, dist: 1f, point: out var point))
				{
					Transform ship = Ship;
					safeOnShip = (Object)(object)ship != (Object)null && Player.isInElevator;
					safeLocal = (safeOnShip ? ship.InverseTransformPoint(point) : point);
					haveSafe = true;
				}
			}
		}

		private static void CheckUnstuckKey()
		{
			//IL_0028: 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)
			if (Keyboard.current != null && !(Time.time < nextUnstuck) && Enum.TryParse<Key>(Plugin.UnstuckKey.Value, ignoreCase: true, out Key result) && (int)result != 0 && ((ButtonControl)Keyboard.current[result]).wasPressedThisFrame && !Player.isTypingChat && !Player.inTerminalMenu && (!((Object)(object)Player.quickMenuManager != (Object)null) || !Player.quickMenuManager.isMenuOpen))
			{
				nextUnstuck = Time.time + 1f;
				Unstuck();
			}
		}

		public static void Unstuck()
		{
			//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_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)
			//IL_0035: 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_004e: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || mario == null)
			{
				return;
			}
			int playerMask = CollisionStreamer.PlayerMask;
			Vector3 worldPos = mario.WorldPos;
			Vector3? val = null;
			string text = null;
			if (FindGround(worldPos + Vector3.up * 1.5f, 40f, playerMask, out var point) && HasHeadroom(point, playerMask))
			{
				val = point;
				text = "floor below";
			}
			if (!val.HasValue)
			{
				for (float num = 0.6f; num <= 3.01f; num += 0.6f)
				{
					if (val.HasValue)
					{
						break;
					}
					for (int i = 0; i < 8; i++)
					{
						if (val.HasValue)
						{
							break;
						}
						if (FindGround(worldPos + Quaternion.Euler(0f, (float)i * 45f, 0f) * Vector3.forward * num + Vector3.up * 1.5f, 4f, playerMask, out var point2) && HasHeadroom(point2, playerMask) && !Physics.Linecast(worldPos + Vector3.up * 0.8f, point2 + Vector3.up * 0.8f, playerMask, (QueryTriggerInteraction)1))
						{
							val = point2;
							text = $"open floor {num:F1} m away";
						}
					}
				}
			}
			if (!val.HasValue && haveSafe)
			{
				Transform ship = Ship;
				if (!safeOnShip)
				{
					val = safeLocal;
					text = "last safe spot";
				}
				else if ((Object)(object)ship != (Object)null)
				{
					val = ship.TransformPoint(safeLocal);
					text = "last safe spot (ship)";
				}
			}
			if (!val.HasValue)
			{
				Transform[] array = StartOfRound.Instance?.playerSpawnPositions;
				int num2 = (int)Player.playerClientId;
				if (array != null && num2 < array.Length && (Object)(object)array[num2] != (Object)null)
				{
					val = array[num2].position;
					text = "ship spawn";
				}
			}
			if (!val.HasValue)
			{
				val = worldPos;
			}
			LogNearbyColliders(worldPos, playerMask);
			Plugin.Log.LogInfo((object)string.Format("Unstuck: rebuilding collision, moving Mario to {0} ({1}).", text ?? "where he is", val.Value));
			SM64Context.Collision.Clear();
			((Component)Player).transform.position = val.Value;
			Physics.SyncTransforms();
			Snap(val.Value);
			Native.sm64_set_mario_action(mario.Id, 205521409u);
		}

		private static bool FindGround(Vector3 from, float dist, int mask, out Vector3 point)
		{
			//IL_0001: 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_0008: 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)
			//IL_0030: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			point = default(Vector3);
			int num = Physics.RaycastNonAlloc(from, Vector3.down, groundHits, dist, mask, (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = groundHits[i];
				if (!(((RaycastHit)(ref val)).normal.y < 0.5f) && !(((RaycastHit)(ref val)).distance >= num2) && CollisionStreamer.Usable(((RaycastHit)(ref val)).collider))
				{
					num2 = ((RaycastHit)(ref val)).distance;
					point = ((RaycastHit)(ref val)).point;
				}
			}
			return num2 < float.MaxValue;
		}

		private static void LogNearbyColliders(Vector3 pos, int mask)
		{
			//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_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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			Transform ship = Ship;
			int num = Physics.OverlapSphereNonAlloc(pos + Vector3.up * 0.8f, 1.5f, headroomHits, mask, (QueryTriggerInteraction)1);
			StringBuilder stringBuilder = new StringBuilder($"Stuck at {pos}, nearby solids:");
			for (int i = 0; i < num; i++)
			{
				Collider val = headroomHits[i];
				if (CollisionStreamer.Usable(val))
				{
					bool flag = (Object)(object)ship != (Object)null && ((Component)val).transform.IsChildOf(ship);
					object[] obj = new object[7]
					{
						((Object)val).name,
						((object)val).GetType().Name,
						((Object)((Component)val).transform.root).name,
						flag ? " (ship)" : "",
						LayerMask.LayerToName(((Component)val).gameObject.layer),
						null,
						null
					};
					Bounds bounds = val.bounds;
					obj[5] = ((Bounds)(ref bounds)).center;
					bounds = val.bounds;
					obj[6] = ((Bounds)(ref bounds)).size;
					stringBuilder.Append(string.Format("\n  - '{0}' [{1}] root '{2}'{3} layer {4} bounds {5} size {6}", obj));
				}
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static bool HasHeadroom(Vector3 floor, int mask)
		{
			//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_0011: 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_001c: 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_0022: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			float marioScaleFactor = SM64Context.MarioScaleFactor;
			int num = Physics.OverlapCapsuleNonAlloc(floor + Vector3.up * 0.4f * marioScaleFactor, floor + Vector3.up * 1.4f * marioScaleFactor, 0.3f * marioScaleFactor, headroomHits, mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (CollisionStreamer.Usable(headroomHits[i]))
				{
					return false;
				}
			}
			return true;
		}

		private static Native.MarioInputs ReadInputs()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB player = Player;
			Native.MarioInputs result = default(Native.MarioInputs);
			Vector3 val = Quaternion.Euler(0f, orbitYaw, 0f) * Vector3.forward;
			result.camLookX = 0f - val.x;
			result.camLookZ = val.z;
			if (gameDisabledMove || player.isTypingChat || ((Object)(object)player.quickMenuManager != (Object)null && player.quickMenuManager.isMenuOpen) || player.inSpecialMenu)
			{
				return result;
			}
			Vector2 val2 = ((moveAction != null) ? moveAction.ReadValue<Vector2>() : Vector2.zero);
			if (((Vector2)(ref val2)).sqrMagnitude > 1f)
			{
				((Vector2)(ref val2)).Normalize();
			}
			result.stickX = val2.x;
			result.stickY = 0f - val2.y;
			bool flag = jumpAction != null && jumpAction.IsPressed();
			bool flag2 = Plugin.LeftClickIsB.Value && activateAction != null && activateAction.IsPressed() && !player.isHoldingObject;
			if (!flag2 && Keyboard.current != null && Enum.TryParse<Key>(Plugin.BKey.Value, ignoreCase: true, out Key result2) && (int)result2 != 0)
			{
				flag2 = ((ButtonControl)Keyboard.current[result2]).isPressed;
			}
			bool flag3 = crouchAction != null && crouchAction.IsPressed();
			result.buttonA = (byte)(flag ? 1u : 0u);
			result.buttonB = (byte)(flag2 ? 1u : 0u);
			result.buttonZ = (byte)(flag3 ? 1u : 0u);
			return result;
		}

		private static void HandleHealth()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			int num = 2176 - mario.State.health;
			if (num <= 0)
			{
				return;
			}
			Native.sm64_set_mario_health(mario.Id, 2176);
			if (Time.time < suppressHealthDamageUntil)
			{
				lostHealthUnits = 0;
				return;
			}
			lostHealthUnits += num;
			int num2 = lostHealthUnits / 256;
			if (num2 > 0)
			{
				lostHealthUnits %= 256;
				Player.DamagePlayer(num2 * Plugin.FallDamagePerWedge.Value, true, true, (CauseOfDeath)2, 0, true, Vector3.zero);
			}
		}

		public static void OnDamaged(int damage, bool fallDamage, Vector3 force)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (!(!Active || Suspended || mario == null || fallDamage) && damage > 0 && !Player.isPlayerDead)
			{
				suppressHealthDamageUntil = Time.time + 2f;
				Vector3 val = Quaternion.Euler(0f, mario.Yaw, 0f) * Vector3.forward;
				Vector3 val2 = ((((Vector3)(ref force)).sqrMagnitude > 0.01f) ? ((Vector3)(ref force)).normalized : (-val));
				Vector3 val3 = SM64Context.ToSM(mario.WorldPos - val2);
				uint damage2 = (uint)Mathf.Clamp(damage / 20, 1, 3);
				Native.sm64_mario_take_damage(mario.Id, damage2, 0u, val3.x, val3.y, val3.z);
			}
		}

		private static void HandleAttacks()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			float marioScaleFactor = SM64Context.MarioScaleFactor;
			Vector3 worldPos = mario.WorldPos;
			Vector3 val = worldPos + Vector3.up * 0.8f * marioScaleFactor;
			int num = Physics.OverlapSphereNonAlloc(val, 2.2f * marioScaleFactor, hitBuffer, -1, (QueryTriggerInteraction)2);
			uint action = mario.State.action;
			int num2 = ((action != 8390825 && action != 8389180) ? 1 : 2);
			Vector2 val4 = default(Vector2);
			for (int i = 0; i < num; i++)
			{
				Collider val2 = hitBuffer[i];
				IHittable component = ((Component)val2).GetComponent<IHittable>();
				if (component == null)
				{
					continue;
				}
				EnemyAICollisionDetect component2 = ((Component)val2).GetComponent<EnemyAICollisionDetect>();
				int instanceID;
				if (component2 != null)
				{
					if ((Object)(object)component2.mainScript == (Object)null || component2.mainScript.isEnemyDead)
					{
						continue;
					}
					instanceID = ((Object)component2.mainScript).GetInstanceID();
				}
				else
				{
					PlayerControllerB component3 = ((Component)val2).GetComponent<PlayerControllerB>();
					if (component3 != null)
					{
						if ((Object)(object)component3 == (Object)(object)Player || !Plugin.MarioCanHurtPlayers.Value || component3.isPlayerDead)
						{
							continue;
						}
						instanceID = ((Object)component3).GetInstanceID();
					}
					else
					{
						instanceID = ((Object)val2).GetInstanceID();
					}
				}
				if (hitCooldown.TryGetValue(instanceID, out var value) && Time.time < value)
				{
					continue;
				}
				Bounds bounds = val2.bounds;
				Vector3 val3 = ((Bounds)(ref bounds)).ClosestPoint(val);
				((Vector2)(ref val4))..ctor(val3.x - worldPos.x, val3.z - worldPos.z);
				if (((Vector2)(ref val4)).magnitude > 0.9f * marioScaleFactor || val3.y < worldPos.y - 0.4f * marioScaleFactor || val3.y > worldPos.y + 1.9f * marioScaleFactor)
				{
					continue;
				}
				Vector3 val5 = SM64Context.ToSM(new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).center.z));
				if (Native.sm64_mario_attack(mario.Id, val5.x, val5.y, val5.z, ((Bounds)(ref bounds)).size.y * SM64Context.Scale))
				{
					hitCooldown[instanceID] = Time.time + 0.45f;
					Vector3 val6 = new Vector3(val4.x, 0f, val4.y);
					Vector3 normalized = ((Vector3)(ref val6)).normalized;
					try
					{
						component.Hit(num2, normalized, Player, true, -1);
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Hit failed: " + ex.Message));
					}
				}
			}
		}

		private static void MakeNoise()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.time < nextNoise) && !((Object)(object)RoundManager.Instance == (Object)null))
			{
				bool num = (mario.State.action & 0x800) == 0;
				float num2 = Mathf.Abs(mario.State.forwardVelocity);
				if (num && !(num2 < 8f))
				{
					nextNoise = Time.time + 0.35f;
					bool flag = Player.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed;
					RoundManager.Instance.PlayAudibleNoise(((Component)Player).transform.position, (num2 > 24f) ? 22f : 15f, 0.5f, 0, flag, 0);
				}
			}
		}

		public static void OnOriginShift(Vector3 deltaSM)
		{
			//IL_0020: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			if (Active && mario != null)
			{
				mario.State.px += deltaSM.x;
				mario.State.py += deltaSM.y;
				mario.State.pz += deltaSM.z;
				Native.sm64_set_mario_position(mario.Id, mario.State.px, mario.State.py, mario.State.pz);
			}
		}

		public static void Snap(Vector3 pos)
		{
			//IL_001e: 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_002f: 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_0039: 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_0049: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid I