Decompiled source of ResoniteMario64 v1.0.0

plugins/ResoniteMario64/ResoniteMario64.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
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.Threading.Tasks;
using System.Timers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using BepuPhysics.Collidables;
using Elements.Assets;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.CommonAvatar;
using FrooxEngine.UIX;
using HarmonyLib;
using Renderite.Shared;
using ResoniteMario64.Mario64;
using ResoniteMario64.Mario64.Components;
using ResoniteMario64.Mario64.Components.Context;
using ResoniteMario64.Mario64.Components.Interfaces;
using ResoniteMario64.Mario64.Components.Objects;
using ResoniteMario64.Mario64.libsm64;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]
[assembly: AssemblyCompany("art0007i, NepuShiro")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8f0142aaaa5541eb206e414bb6e004da6295eb10")]
[assembly: AssemblyProduct("ResoniteMario64")]
[assembly: AssemblyTitle("ResoniteMario64")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/art0007i/ResoniteMario64")]
[assembly: SecurityPermission(8, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace ResoniteMario64
{
	public class Config
	{
		public static ConfigEntry<int> GameTickMs;

		public static ConfigEntry<int> MarioScaleFactor;

		public static ConfigEntry<int> MarioCollisionChecks;

		public static ConfigEntry<Uri> MarioUrl;

		public static ConfigEntry<bool> UseGamepad;

		public static ConfigEntry<bool> BlockDashWithMarios;

		public static ConfigEntry<Key> UnlockMovementKey;

		public static ConfigEntry<bool> UnlockMovementKeyToggle;

		public static ConfigEntry<bool> DisableAudio;

		public static ConfigEntry<bool> PlayRandomMusic;

		public static ConfigEntry<bool> PlayCapMusic;

		public static ConfigEntry<float> AudioVolume;

		public static ConfigEntry<bool> LocalAudio;

		public static ConfigEntry<bool> DeleteAfterDeath;

		public static ConfigEntry<float> MarioCullDistance;

		public static ConfigEntry<int> MaxMariosPerPerson;

		public static ConfigEntry<int> MaxMeshColliderTris;

		public static ConfigEntry<bool> DebugEnabled;

		public static ConfigEntry<bool> RenderSlotPublic;

		public static ConfigEntry<bool> LogColliderChanges;

		internal static bool ConfigInit(ConfigFile config)
		{
			try
			{
				GameTickMs = config.Bind<int>("Engine", "Game Tick Ms", 25, "How many Milliseconds should a game tick last. This will directly impact the speed of Mario's behavior.");
				MarioScaleFactor = config.Bind<int>("Engine", "Mario Scale Factor", 200, "The base scaling factor used to size Mario and his colliders. Lower values make Mario larger; higher values make him smaller.");
				MarioCollisionChecks = config.Bind<int>("Engine", "Mario Collision Checks", 10, "The number of evenly spaced points to check along Mario's body for collisions. Higher values increase accuracy but cost more performance.");
				MarioUrl = config.Bind<Uri>("Engine", "Mario Url", (Uri)null, "The URL for the Non-Modded Renderer for Mario - Null = Default Mario");
				UseGamepad = config.Bind<bool>("Controls", "Use Gamepad", false, "Whether to use gamepads for input or not.");
				BlockDashWithMarios = config.Bind<bool>("Controls", "Block Dash with Marios", true, "Whether to Block opening the dash with marios or not. !VR-Only!");
				UnlockMovementKey = config.Bind<Key>("Controls", "Unlock Movement Key", (Key)46, "The key to unlock movement when marios are present.");
				UnlockMovementKeyToggle = config.Bind<bool>("Controls", "Unlock Movement Key Toggle", true, "When true the unlock movement key will toggle, when false it needs to be held the entire time.");
				DisableAudio = config.Bind<bool>("Audio", "Disable Audio", false, "Whether to disable all Super Mario 64 Music/Sounds or not.");
				PlayRandomMusic = config.Bind<bool>("Audio", "Play Random Music", true, "Whether to play a random music when a mario joins or not.");
				PlayCapMusic = config.Bind<bool>("Audio", "Play Cap Music", true, "Whether to play the Cap music when a mario picks one up or not.");
				AudioVolume = config.Bind<float>("Audio", "Audio Volume", 0.1f, "The audio volume.");
				LocalAudio = config.Bind<bool>("Audio", "Local Audio", true, "Whether to play the Audio Locally or not.");
				DeleteAfterDeath = config.Bind<bool>("Performance", "Delete Mario After Death", true, "Whether to automatically delete our marios after 15 seconds of being dead or not.");
				MarioCullDistance = config.Bind<float>("Performance", "Mario Cull Distance", 15f, "The distance where it should stop using the Super Mario 64 Engine to handle other players Marios.");
				MaxMariosPerPerson = config.Bind<int>("Performance", "Max Marios Per Person", 5, "Max number of Marios per player that will be animated using the Super Mario 64 Engine.");
				MaxMeshColliderTris = config.Bind<int>("Performance", "Max Mesh Collider Tris", 50000, "Maximum total number of triangles of automatically generated from mesh colliders allowed.");
				DebugEnabled = config.Bind<bool>("Debug", "Debug Enabled", false, "Whether to enable debug mode or not.");
				RenderSlotPublic = config.Bind<bool>("Debug", "Render Slot Public", true, "When true the renderer slot will not be a local slot.");
				LogColliderChanges = config.Bind<bool>("Debug", "Log Collider Changes", false, "Whether to Log Collider changes or not.");
				return true;
			}
			catch (global::System.Exception message)
			{
				Logger.Fatal(message, "ConfigInit", 71);
				return false;
			}
		}
	}
	public static class Constants
	{
		public const string TempSlotName = "__TEMP";

		public const string ContextSlotName = "ResoniteMario64 Instance";

		public const string ConfigSlotName = "Config";

		public const string AudioSlotName = "Audio";

		public const string MarioContainersSlotName = "Mario Containers";

		public const string ContextSpaceName = "SM64Context";

		public const string MarioSpaceName = "Mario";

		public const string HostVarName = "Host";

		public const string ScaleVarName = "Scale";

		public const string WaterVarName = "WaterLevel";

		public const string GasVarName = "GasLevel";

		public const string JoystickVarName = "Joystick";

		public const string JumpVarName = "Jump";

		public const string PunchVarName = "Punch";

		public const string CrouchVarName = "Crouch";

		public const string IsShownVarName = "IsShown";

		public const string HealthPointsVarName = "HealthPoints";

		public const string ActionFlagsVarName = "ActionFlags";

		public const string StateFlagsVarName = "StateFlags";

		public const string ContextTag = "SM64 Context";

		public const string MarioTag = "SM64 Mario";

		public const string MarioContainersTag = "SM64 Mario Containers";

		public const string MarioContainerTag = "SM64 Mario Container";

		public const string MarioNonMRendererTag = "SM64 Non-Modded Renderer";

		public const string AudioTag = "SM64 Audio";

		public const string ConfigTag = "SM64 Config";

		public const string InputBlockTag = "SM64 InputBlock";
	}
	public static class Logger
	{
		private static ManualLogSource Log => Plugin.Log;

		private static string Format(object message, string caller, int line)
		{
			return $"[{caller}|{line}] {message?.ToString() ?? "null"}";
		}

		public static void Debug(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogDebug((object)Format(message, caller, line));
		}

		public static void Info(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogInfo((object)Format(message, caller, line));
		}

		public static void Msg(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogMessage((object)Format(message, caller, line));
		}

		public static void Warn(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogWarning((object)Format(message, caller, line));
		}

		public static void Error(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogError((object)Format(message, caller, line));
		}

		public static void Fatal(object message, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
		{
			Log.LogFatal((object)Format(message, caller, line));
		}
	}
	[ResonitePlugin("art0007i.ResoniteMario64", "ResoniteMario64", "1.0.0", "art0007i, NepuShiro", "https://github.com/art0007i/ResoniteMario64")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		internal static ManualLogSource Log;

		public static readonly string DllDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		public override void Load()
		{
			//IL_001d: 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)
			Log = ((BasePlugin)this).Log;
			try
			{
				if (!Config.ConfigInit(((BasePlugin)this).Config))
				{
					throw new InvalidOperationException("Config initialization failed.");
				}
				if (!Mario64Manager.Init())
				{
					throw new InvalidOperationException("Mario64Manager initialization failed.");
				}
				((BasePlugin)this).HarmonyInstance.PatchAll();
				Logger.Info("Plugin art0007i.ResoniteMario64 loaded successfully.", "Load", 36);
			}
			catch (global::System.Exception message)
			{
				Logger.Fatal("Failed to load ResoniteMario64.", "Load", 40);
				Logger.Fatal(message, "Load", 41);
			}
		}
	}
	public static class PluginMetadata
	{
		public const string GUID = "art0007i.ResoniteMario64";

		public const string NAME = "ResoniteMario64";

		public const string VERSION = "1.0.0";

		public const string AUTHORS = "art0007i, NepuShiro";

		public const string REPOSITORY_URL = "https://github.com/art0007i/ResoniteMario64";
	}
}
namespace ResoniteMario64.Mario64
{
	public static class ColliderShapeExtensions
	{
		public static MeshX GetColliderMesh(this Collider c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_008a: 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_009e: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_00fe: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_01bf: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			MeshX val = new MeshX();
			TriangleCollider val2 = (TriangleCollider)(object)((c is TriangleCollider) ? c : null);
			if (val2 == null)
			{
				CapsuleCollider val3 = (CapsuleCollider)(object)((c is CapsuleCollider) ? c : null);
				if (val3 == null)
				{
					ConeCollider val4 = (ConeCollider)(object)((c is ConeCollider) ? c : null);
					if (val4 == null)
					{
						CylinderCollider val5 = (CylinderCollider)(object)((c is CylinderCollider) ? c : null);
						if (val5 == null)
						{
							BoxCollider val6 = (BoxCollider)(object)((c is BoxCollider) ? c : null);
							if (val6 == null)
							{
								SphereCollider val7 = (SphereCollider)(object)((c is SphereCollider) ? c : null);
								if (val7 == null)
								{
									MeshCollider val8 = (MeshCollider)(object)((c is MeshCollider) ? c : null);
									if (val8 == null)
									{
										ConvexHullCollider val9 = (ConvexHullCollider)(object)((c is ConvexHullCollider) ? c : null);
										if (val9 != null)
										{
											if (((MeshBasedCollider<ConvexHull, ConvexHullData>)(object)val9).Mesh.IsAssetAvailable)
											{
												return ((SyncRef<IAssetProvider<Mesh>>)(object)((MeshBasedCollider<ConvexHull, ConvexHullData>)(object)val9).Mesh).Target.Asset.Data;
											}
											if (Utils.CheckDebug())
											{
												Logger.Warn($"- [{((object)val9).GetType()}] {((Component)val9).Slot.Name} ({((Worker)val9).ReferenceID}) Mesh is null or not readable", "GetColliderMesh", 79);
											}
										}
									}
									else
									{
										if (((MeshBasedCollider<Mesh, MeshColliderData>)(object)val8).Mesh.IsAssetAvailable)
										{
											return ((SyncRef<IAssetProvider<Mesh>>)(object)((MeshBasedCollider<Mesh, MeshColliderData>)(object)val8).Mesh).Target.Asset.Data;
										}
										if (Utils.CheckDebug())
										{
											Logger.Warn($"- [{((object)val8).GetType()}] {((Component)val8).Slot.Name} ({((Worker)val8).ReferenceID}) Mesh is null or not readable", "GetColliderMesh", 70);
										}
									}
								}
								else
								{
									((MeshXShape)new UVSphereCapsule(MeshX.op_Implicit(val), 8, 16, (Shading)3, false)
									{
										Radius = ((SyncField<float>)(object)val7.Radius).Value
									}).Update();
								}
							}
							else
							{
								((MeshXShape)new Box(MeshX.op_Implicit(val))
								{
									Size = ((SyncField<float3>)(object)val6.Size).Value
								}).Update();
							}
						}
						else
						{
							((MeshXShape)new ConicalFrustum(MeshX.op_Implicit(val), 8, true, true)
							{
								Radius = ((SyncField<float>)(object)val5.Radius).Value,
								Height = ((SyncField<float>)(object)val5.Height).Value
							}).Update();
						}
					}
					else
					{
						((MeshXShape)new ConicalFrustum(MeshX.op_Implicit(val), 8, true, true)
						{
							Radius = ((SyncField<float>)(object)val4.Radius).Value,
							RadiusTop = 0f,
							Height = ((SyncField<float>)(object)val4.Height).Value
						}).Update();
					}
				}
				else
				{
					((MeshXShape)new UVSphereCapsule(MeshX.op_Implicit(val), 8, 16, (Shading)3, true)
					{
						Radius = ((SyncField<float>)(object)val3.Radius).Value,
						Height = ((SyncField<float>)(object)val3.Height).Value
					}).Update();
				}
			}
			else
			{
				TriangleSubmesh val10 = val.AddSubmesh<TriangleSubmesh>();
				float3 value = ((SyncField<float3>)(object)val2.A).Value;
				float3 value2 = ((SyncField<float3>)(object)((Collider)val2).Offset).Value;
				float3 val11 = (ref value) + (ref value2);
				val.AddVertex(ref val11);
				value = ((SyncField<float3>)(object)val2.B).Value;
				value2 = ((SyncField<float3>)(object)((Collider)val2).Offset).Value;
				val11 = (ref value) + (ref value2);
				val.AddVertex(ref val11);
				value = ((SyncField<float3>)(object)val2.C).Value;
				value2 = ((SyncField<float3>)(object)((Collider)val2).Offset).Value;
				val11 = (ref value) + (ref value2);
				val.AddVertex(ref val11);
				val10.AddTriangle(0, 1, 2);
			}
			return val;
		}
	}
	public static class Mario64Manager
	{
		private const string LibName = "sm64.dll";

		private static readonly string LibPath = Path.Combine(Plugin.DllDirectory, "sm64.dll");

		private const string RomExpectedHash = "20b854b239203baf6c961b850a4a51a2";

		private const string RomFileName = "baserom.us.z64";

		private static string _romPath = Path.Combine(Plugin.DllDirectory, "baserom.us.z64");

		internal static byte[] RomBytes;

		internal static bool Init()
		{
			if (!ExtractNativeLibrary())
			{
				return false;
			}
			if (!LoadRom())
			{
				return false;
			}
			return true;
		}

		private static bool ExtractNativeLibrary()
		{
			//IL_00c2: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Logger.Info($"Copying {"sm64.dll"} to {LibPath} from embedded resources.", "ExtractNativeLibrary", 41);
				Stream manifestResourceStream = typeof(Mario64Manager).Assembly.GetManifestResourceStream("sm64.dll");
				try
				{
					if (manifestResourceStream == null)
					{
						throw new FileLoadException("Embedded resource sm64.dll not found in assembly.");
					}
					FileStream val = File.Open(LibPath, (FileMode)2, (FileAccess)2);
					try
					{
						manifestResourceStream.CopyTo((Stream)(object)val);
						return true;
					}
					finally
					{
						((global::System.IDisposable)val)?.Dispose();
					}
				}
				finally
				{
					((global::System.IDisposable)manifestResourceStream)?.Dispose();
				}
			}
			catch (IOException val2)
			{
				Logger.Fatal("Failed to copy native library.", "ExtractNativeLibrary", 56);
				Logger.Fatal(((global::System.Exception)val2).Message, "ExtractNativeLibrary", 57);
				return false;
			}
		}

		private static bool LoadRom()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string[] obj = new string[4]
				{
					_romPath,
					Path.Combine(Directory.GetCurrentDirectory(), "baserom.us.z64"),
					Path.Combine(Directory.GetCurrentDirectory(), "rml_libs", "baserom.us.z64"),
					Path.Combine(Directory.GetCurrentDirectory(), "rml_mods", "baserom.us.z64")
				};
				string text = null;
				string[] array = obj;
				foreach (string text2 in array)
				{
					Logger.Msg("Checking for ROM at " + text2, "LoadRom", 77);
					if (File.Exists(text2))
					{
						text = text2;
						break;
					}
					Logger.Debug("ROM not found at " + text2, "LoadRom", 84);
				}
				if (text == null)
				{
					throw new FileLoadException("Missing ROM: Download a \"Super Mario 64 [US].z64\" ROM (MD5 20b854b239203baf6c961b850a4a51a2)");
				}
				Logger.Info("Loading \"Super Mario 64 [US].z64\" ROM from " + text + "...", "LoadRom", 92);
				_romPath = text;
				FileStream val = File.OpenRead(_romPath);
				try
				{
					string text3 = Convert.ToHexStringLower(((HashAlgorithm)MD5.Create()).ComputeHash((Stream)(object)val));
					if (text3 != "20b854b239203baf6c961b850a4a51a2")
					{
						throw new FileLoadException($"Invalid ROM Hash: Found {text3}, expected {"20b854b239203baf6c961b850a4a51a2"}.");
					}
					RomBytes = File.ReadAllBytes(_romPath);
					return true;
				}
				finally
				{
					((global::System.IDisposable)val)?.Dispose();
				}
			}
			catch (global::System.Exception ex)
			{
				Logger.Fatal("Failed to load the Super Mario 64 [US] z64 ROM.", "LoadRom", 108);
				Logger.Fatal(ex.Message, "LoadRom", 109);
				return false;
			}
		}
	}
	public class Patches
	{
		[HarmonyPatch(typeof(UpdateManager), "RunUpdates")]
		private class WorldUpdatePatch
		{
			public static void Prefix(UpdateManager __instance)
			{
				if (SM64Context.Instance?.World == __instance.World)
				{
					SM64Context.Instance?.OnCommonUpdate();
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public class WorldStartRunningPatch
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static SlotChildEvent <>9__1_1;

				public static SlotChildEvent <>9__1_2;

				public static Predicate<Slot> <>9__2_1;

				public static Action<Slot> <>9__2_3;

				internal void <Postfix>b__1_1(Slot _, Slot child)
				{
					if (!(child.Name != "__TEMP"))
					{
						SM64Context.TempSlot = child;
					}
				}

				internal void <Postfix>b__1_2(Slot slot, Slot child)
				{
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Expected O, but got Unknown
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					<>c__DisplayClass1_1 CS$<>8__locals0 = new <>c__DisplayClass1_1
					{
						slot = slot
					};
					if (!(child.Name != "__TEMP"))
					{
						CS$<>8__locals0.slot.RunInUpdates((int)((Worker)CS$<>8__locals0.slot).LocalUser.AllocationID, (Action)delegate
						{
							SM64Context.TempSlot = CS$<>8__locals0.slot.FindChildOrAdd("__TEMP", false);
						});
					}
				}

				internal bool <WorldSubMethod>b__2_1(Slot x)
				{
					return x.Tag == "SM64 Context";
				}

				internal void <WorldSubMethod>b__2_3(Slot slot)
				{
					if (!(slot.Tag != "SM64 Mario"))
					{
						SM64Context.TryAddMario(slot, manual: false);
					}
				}
			}

			[CompilerGenerated]
			private sealed class <>c__DisplayClass1_1
			{
				public Slot slot;

				internal void <Postfix>b__3()
				{
					SM64Context.TempSlot = slot.FindChildOrAdd("__TEMP", false);
				}
			}

			private static readonly Dictionary<World, Action<World>> Subscriptions = new Dictionary<World, Action<World>>();

			public static void Postfix(World __instance)
			{
				//IL_008f: 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_009a: Expected O, but got Unknown
				//IL_00be: 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_00c9: Expected O, but got Unknown
				if (WorldExtensions.IsUserspace(__instance))
				{
					return;
				}
				Engine current = Engine.Current;
				if (((current != null) ? current.WorldManager : null) == null || Subscriptions.ContainsKey(__instance))
				{
					return;
				}
				Action<World> val = delegate(World world)
				{
					WorldSubMethod(world, __instance);
				};
				Subscriptions[__instance] = val;
				Engine.Current.WorldManager.WorldFocused += val;
				Slot rootSlot = __instance.RootSlot;
				object obj = <>c.<>9__1_1;
				if (obj == null)
				{
					SlotChildEvent val2 = delegate(Slot _, Slot child)
					{
						if (!(child.Name != "__TEMP"))
						{
							SM64Context.TempSlot = child;
						}
					};
					<>c.<>9__1_1 = val2;
					obj = (object)val2;
				}
				rootSlot.ChildAdded += (SlotChildEvent)obj;
				Slot rootSlot2 = __instance.RootSlot;
				object obj2 = <>c.<>9__1_2;
				if (obj2 == null)
				{
					SlotChildEvent val3 = delegate(Slot slot, Slot child)
					{
						//IL_003d: Unknown result type (might be due to invalid IL or missing references)
						//IL_0047: Expected O, but got Unknown
						//IL_0042: Unknown result type (might be due to invalid IL or missing references)
						Slot slot2 = slot;
						if (!(child.Name != "__TEMP"))
						{
							slot2.RunInUpdates((int)((Worker)slot2).LocalUser.AllocationID, (Action)delegate
							{
								SM64Context.TempSlot = slot2.FindChildOrAdd("__TEMP", false);
							});
						}
					};
					<>c.<>9__1_2 = val3;
					obj2 = (object)val3;
				}
				rootSlot2.ChildRemoved += (SlotChildEvent)obj2;
			}

			private static void WorldSubMethod(World world, World instance)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if (world != instance)
				{
					UnsubscribeWorldFocused(instance);
				}
				else
				{
					if ((int)world.Focus != 1)
					{
						return;
					}
					world.RunInUpdates(3, (Action)delegate
					{
						//IL_0060: Unknown result type (might be due to invalid IL or missing references)
						//IL_006a: Expected O, but got Unknown
						//IL_0065: Unknown result type (might be due to invalid IL or missing references)
						try
						{
							if (SM64Context.GetTempSlot(instance).FindChild((Predicate<Slot>)((Slot x) => x.Tag == "SM64 Context"), -1) != null && SM64Context.EnsureInstanceExists(instance, out var context))
							{
								context.World.RunInUpdates(3, (Action)delegate
								{
									Slot marioContainersSlot = context.MarioContainersSlot;
									if (marioContainersSlot != null)
									{
										marioContainersSlot.ForeachChild((Action<Slot>)delegate(Slot slot)
										{
											if (!(slot.Tag != "SM64 Mario"))
											{
												SM64Context.TryAddMario(slot, manual: false);
											}
										}, false);
									}
								});
							}
						}
						finally
						{
							UnsubscribeWorldFocused(instance);
						}
					});
				}
			}

			private static void UnsubscribeWorldFocused(World world)
			{
				Action<World> val = default(Action<World>);
				if (Subscriptions.TryGetValue(world, ref val))
				{
					Engine.Current.WorldManager.WorldFocused -= val;
					Subscriptions.Remove(world);
				}
			}
		}

		[HarmonyPatch(typeof(UserRoot))]
		private class UserRootPatch
		{
			private const string VariableName = "User/ResoniteMario64.HasInstance";

			[HarmonyPatch("OnStart")]
			[HarmonyPostfix]
			public static void OnStartPatch(UserRoot __instance)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected O, but got Unknown
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				((ComponentBase<Component>)(object)__instance).RunInUpdates(3, (Action)delegate
				{
					if (__instance.ActiveUser == ((Worker)__instance).LocalUser)
					{
						((SyncField<string>)(object)((DynamicVariableBase<bool>)(object)((ContainerWorker<Component>)(object)((Component)__instance).Slot).AttachComponent<DynamicValueVariable<bool>>(true, (Action<DynamicValueVariable<bool>>)null)).VariableName).Value = "User/ResoniteMario64.HasInstance";
					}
				});
			}

			[HarmonyPatch("OnCommonUpdate")]
			[HarmonyPostfix]
			public static void CommonUpdatePatch(UserRoot __instance)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.ActiveUser == ((Worker)__instance).LocalUser)
				{
					DynamicVariableHelper.WriteDynamicVariable<bool>(((Component)__instance).Slot, "User/ResoniteMario64.HasInstance", SM64Context.Instance != null);
				}
			}
		}

		[HarmonyPatch(typeof(Button))]
		private class ButtonPatches
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static Predicate<Slot> <>9__1_2;

				public static Action <>9__1_1;

				internal bool <RunPressed>b__1_2(Slot x)
				{
					return x.Name == "__TEMP";
				}

				internal void <RunPressed>b__1_1()
				{
					SM64Context.Instance?.Dispose();
				}
			}

			private static bool _spawnRunning;

			[HarmonyPatch("RunPressed")]
			[HarmonyPrefix]
			public static bool RunPressed(Button __instance)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Expected O, but got Unknown
				string tag = ((Component)__instance).Slot.Tag;
				if (!(tag == "SpawnMario"))
				{
					if (tag == "KillInstance")
					{
						if (SM64Context.Instance != null)
						{
							Button obj = __instance;
							object obj2 = <>c.<>9__1_1;
							if (obj2 == null)
							{
								Action val = delegate
								{
									SM64Context.Instance?.Dispose();
								};
								<>c.<>9__1_1 = val;
								obj2 = (object)val;
							}
							((ComponentBase<Component>)(object)obj).RunSynchronously((Action)obj2, false);
						}
						return false;
					}
					return true;
				}
				((ComponentBase<Component>)(object)__instance).RunSynchronously((Action)delegate
				{
					//IL_009f: 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: Expected O, but got Unknown
					//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
					string oldText = __instance.LabelText;
					Slot val2 = (((Worker)__instance).World.RootSlot.FindChild((Predicate<Slot>)((Slot x) => x.Name == "__TEMP"), -1) ?? ((Worker)__instance).World.RootSlot.AddSlot("__TEMP", false)).AddSlot(((Worker)__instance).LocalUser.UserName + "'s Mario", false);
					val2.GlobalPosition = ((Component)__instance).Slot.GlobalPosition;
					ValueUserOverride.OverrideForUser<string>(__instance.LabelTextField, ((Worker)__instance).LocalUser, SM64Context.TryAddMario(val2) ? "Mario Spawned!" : "Mario Spawn Failed!");
					if (!_spawnRunning)
					{
						_spawnRunning = true;
						((ComponentBase<Component>)(object)__instance).RunInSeconds(5f, (Action)delegate
						{
							ValueUserOverride.OverrideForUser<string>(__instance.LabelTextField, ((Worker)__instance).LocalUser, oldText);
							_spawnRunning = false;
						});
					}
				}, false);
				return false;
			}
		}

		[HarmonyPatch(typeof(Slot), "BuildInspectorUI")]
		private class SlotUiAddon
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static Predicate<Slot> <>9__0_0;

				public static Predicate<Slot> <>9__0_5;

				public static Action <>9__0_7;

				public static ButtonEventHandler <>9__0_2;

				public static Action <>9__0_8;

				public static ButtonEventHandler <>9__0_3;

				public static Predicate<Slot> <>9__0_9;

				public static ButtonEventHandler <>9__0_14;

				public static ButtonEventHandler <>9__0_15;

				internal bool <Postfix>b__0_0(Slot x)
				{
					return x.Tag == "SM64 Context";
				}

				internal bool <Postfix>b__0_5(Slot x)
				{
					return x.Name == "__TEMP";
				}

				internal void <Postfix>b__0_2(IButton b, ButtonEventData _)
				{
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Expected O, but got Unknown
					object obj = <>9__0_7;
					if (obj == null)
					{
						Action val = delegate
						{
							SM64Context.Instance?.ReloadAllColliders();
						};
						<>9__0_7 = val;
						obj = (object)val;
					}
					((IComponentBase)b).RunSynchronously((Action)obj, false);
				}

				internal void <Postfix>b__0_7()
				{
					SM64Context.Instance?.ReloadAllColliders();
				}

				internal void <Postfix>b__0_3(IButton b, ButtonEventData _)
				{
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Expected O, but got Unknown
					object obj = <>9__0_8;
					if (obj == null)
					{
						Action val = delegate
						{
							SM64Context.Instance?.Dispose();
						};
						<>9__0_8 = val;
						obj = (object)val;
					}
					((IComponentBase)b).RunSynchronously((Action)obj, false);
				}

				internal void <Postfix>b__0_8()
				{
					SM64Context.Instance?.Dispose();
				}

				internal bool <Postfix>b__0_9(Slot x)
				{
					return x.Tag == "SM64 Mario";
				}

				internal void <Postfix>b__0_14(IButton _, ButtonEventData _)
				{
					Interop.PlayRandomMusic();
				}

				internal void <Postfix>b__0_15(IButton _, ButtonEventData _)
				{
					Interop.StopMusic();
				}
			}

			public static void Postfix(Slot __instance, UIBuilder ui)
			{
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Expected O, but got Unknown
				//IL_00e3: 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_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_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_010f: Expected O, but got Unknown
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Expected O, but got Unknown
				//IL_0314: Unknown result type (might be due to invalid IL or missing references)
				//IL_0319: Unknown result type (might be due to invalid IL or missing references)
				//IL_034b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0350: Unknown result type (might be due to invalid IL or missing references)
				//IL_0335: Unknown result type (might be due to invalid IL or missing references)
				//IL_033a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0340: Expected O, but got Unknown
				//IL_036c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0371: Unknown result type (might be due to invalid IL or missing references)
				//IL_0377: Expected O, but got Unknown
				//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_020a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0214: Expected O, but got Unknown
				//IL_0246: Unknown result type (might be due to invalid IL or missing references)
				//IL_024b: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Expected O, but got Unknown
				//IL_0276: Unknown result type (might be due to invalid IL or missing references)
				//IL_027b: Unknown result type (might be due to invalid IL or missing references)
				//IL_028a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0294: Expected O, but got Unknown
				//IL_029a: Unknown result type (might be due to invalid IL or missing references)
				//IL_029f: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b8: Expected O, but got Unknown
				//IL_02be: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dc: Expected O, but got Unknown
				Slot val = ui.Root.GetComponentInParents<SceneInspector>((Predicate<SceneInspector>)null, true, false)?.ComponentView?.Target;
				if (((val != null) ? val.Tag : null) == "SM64 Context" || ((val != null) ? val.FindParent((Predicate<Slot>)((Slot x) => x.Tag == "SM64 Context"), -1) : null) == null)
				{
					return;
				}
				LocaleString val2 = LocaleString.op_Implicit("Spawn Mario");
				ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate(IButton b, ButtonEventData _)
				{
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_002c: Expected O, but got Unknown
					IButton b2 = b;
					Action val9 = default(Action);
					((IComponentBase)b2).RunSynchronously((Action)delegate
					{
						//IL_0090: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
						//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
						//IL_00de: Expected O, but got Unknown
						//IL_00e3: Expected O, but got Unknown
						Slot val10 = (((Worker)__instance).World.RootSlot.FindChild((Predicate<Slot>)((Slot x) => x.Name == "__TEMP"), -1) ?? ((Worker)__instance).World.RootSlot.AddSlot("__TEMP", false)).AddSlot(((Worker)__instance).LocalUser.UserName + "'s Mario", false);
						val10.GlobalPosition = __instance.GlobalPosition;
						b2.LabelText = (SM64Context.TryAddMario(val10) ? "Mario Spawned!" : "Mario Spawn Failed!");
						IButton obj11 = b2;
						Action obj12 = val9;
						if (obj12 == null)
						{
							Action val11 = delegate
							{
								b2.LabelText = "Spawn Mario";
							};
							Action val12 = val11;
							val9 = val11;
							obj12 = val12;
						}
						((IComponentBase)obj11).RunInSeconds(5f, obj12);
					}, false);
				};
				if (Interop.IsGlobalInit)
				{
					val2 = LocaleString.op_Implicit("Reload All Colliders");
					Button obj = ui.Button(ref val2);
					object obj2 = <>c.<>9__0_2;
					if (obj2 == null)
					{
						ButtonEventHandler val3 = delegate(IButton b, ButtonEventData _)
						{
							//IL_0015: Unknown result type (might be due to invalid IL or missing references)
							//IL_001a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0020: Expected O, but got Unknown
							object obj10 = <>c.<>9__0_7;
							if (obj10 == null)
							{
								Action val8 = delegate
								{
									SM64Context.Instance?.ReloadAllColliders();
								};
								<>c.<>9__0_7 = val8;
								obj10 = (object)val8;
							}
							((IComponentBase)b).RunSynchronously((Action)obj10, false);
						};
						<>c.<>9__0_2 = val3;
						obj2 = (object)val3;
					}
					obj.LocalPressed += (ButtonEventHandler)obj2;
				}
				val2 = LocaleString.op_Implicit("Destroy Mario64 Context");
				Button obj3 = ui.Button(ref val2);
				object obj4 = <>c.<>9__0_3;
				if (obj4 == null)
				{
					ButtonEventHandler val4 = delegate(IButton b, ButtonEventData _)
					{
						//IL_0015: Unknown result type (might be due to invalid IL or missing references)
						//IL_001a: Unknown result type (might be due to invalid IL or missing references)
						//IL_0020: Expected O, but got Unknown
						object obj9 = <>c.<>9__0_8;
						if (obj9 == null)
						{
							Action val7 = delegate
							{
								SM64Context.Instance?.Dispose();
							};
							<>c.<>9__0_8 = val7;
							obj9 = (object)val7;
						}
						((IComponentBase)b).RunSynchronously((Action)obj9, false);
					};
					<>c.<>9__0_3 = val4;
					obj4 = (object)val4;
				}
				obj3.LocalPressed += (ButtonEventHandler)obj4;
				if (SM64Context.Instance == null || !Interop.IsGlobalInit)
				{
					return;
				}
				try
				{
					SM64Mario mario = default(SM64Mario);
					if ((val.Tag == "SM64 Mario" || val.FindParent((Predicate<Slot>)((Slot x) => x.Tag == "SM64 Mario"), -1) != null) && SM64Context.Instance.AllMarios.TryGetValue(val, ref mario) && mario.IsLocal)
					{
						ui.Spacer(8f);
						foreach (SM64Constants.MarioCapType capType in global::System.Enum.GetValues(typeof(SM64Constants.MarioCapType)))
						{
							val2 = LocaleString.op_Implicit("Wear " + ((object)capType).ToString());
							ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate
							{
								mario.WearCap(capType, (capType == SM64Constants.MarioCapType.WingCap) ? 40f : 15f, !Config.DisableAudio.Value);
							};
						}
						ui.Spacer(8f);
						val2 = LocaleString.op_Implicit("Heal Mario");
						ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate
						{
							mario.Heal(1);
						};
						ui.Spacer(8f);
						val2 = LocaleString.op_Implicit("Damage Mario");
						ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate
						{
							//IL_0011: Unknown result type (might be due to invalid IL or missing references)
							mario.TakeDamage(mario.MarioSlot.GlobalPosition, 1u);
						};
						val2 = LocaleString.op_Implicit("Kill Mario");
						ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate
						{
							mario.SetHealthPoints(0f);
						};
						val2 = LocaleString.op_Implicit("Nuke Mario");
						ui.Button(ref val2).LocalPressed += (ButtonEventHandler)delegate
						{
							mario.SetMarioAsNuked(delete: true);
						};
						ui.Spacer(8f);
					}
					else
					{
						if (!(val.Tag == "SM64 Audio"))
						{
							return;
						}
						ui.Spacer(8f);
						val2 = LocaleString.op_Implicit("Play Random Music");
						Button obj5 = ui.Button(ref val2);
						object obj6 = <>c.<>9__0_14;
						if (obj6 == null)
						{
							ButtonEventHandler val5 = delegate
							{
								Interop.PlayRandomMusic();
							};
							<>c.<>9__0_14 = val5;
							obj6 = (object)val5;
						}
						obj5.LocalPressed += (ButtonEventHandler)obj6;
						val2 = LocaleString.op_Implicit("Stop Music");
						Button obj7 = ui.Button(ref val2);
						object obj8 = <>c.<>9__0_15;
						if (obj8 == null)
						{
							ButtonEventHandler val6 = delegate
							{
								Interop.StopMusic();
							};
							<>c.<>9__0_15 = val6;
							obj8 = (object)val6;
						}
						obj7.LocalPressed += (ButtonEventHandler)obj8;
						ui.Spacer(8f);
					}
				}
				catch (global::System.Exception message)
				{
					Logger.Error(message, "Postfix", 260);
				}
			}
		}
	}
	public static class Utils
	{
		public enum ColliderCategory
		{
			None,
			Static,
			Dynamic,
			WaterBox,
			Interactable
		}

		internal static readonly List<Collider> StaticSurfaces = new List<Collider>();

		public static readonly colorX VanishCapColor = new colorX(1f, 1f, 1f, 0.5f, (ColorProfile)1);

		public static void TransformAndGetSurfaces(List<SM64Surface> outSurfaces, MeshX mesh, SM64Constants.SM64SurfaceType surfaceType, SM64Constants.SM64TerrainType terrainType, int force, Func<float3, float3> transformFunc)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < mesh.SubmeshCount; i++)
			{
				Submesh submesh = mesh.GetSubmesh(i);
				float3[] vertices = Enumerable.ToArray<float3>(Enumerable.Select<Vertex, float3>((global::System.Collections.Generic.IEnumerable<Vertex>)(object)mesh.Vertices, (Func<Vertex, float3>)((Vertex v) => transformFunc.Invoke(((Vertex)(ref v)).Position))));
				Interop.CreateAndAppendSurfaces(outSurfaces, submesh.RawIndicies, vertices, surfaceType, terrainType, force);
			}
		}

		private static ColliderCategory GetColliderCategory(Collider col)
		{
			string text = ((Component)col).Slot.Tag ?? string.Empty;
			bool num = text.Contains("SM64 StaticCollider") || text.Contains("SM64 Collider");
			bool flag = text.Contains("SM64 DynamicCollider");
			bool flag2 = text.Contains("SM64 WaterBox");
			bool flag3 = text.Contains("SM64 Interactable");
			bool flag4 = ((ComponentBase<Component>)(object)col).Enabled && ((Component)col).Slot.IsActive;
			if ((num || ((ICollider)col).CollidesWithCharacters) && !flag && flag4)
			{
				return ColliderCategory.Static;
			}
			if (flag && flag4)
			{
				return ColliderCategory.Dynamic;
			}
			if (flag2 && flag4)
			{
				return ColliderCategory.WaterBox;
			}
			if (flag3 && ((ComponentBase<Component>)(object)col).Enabled)
			{
				return ColliderCategory.Interactable;
			}
			return ColliderCategory.None;
		}

		public static bool IsStaticCollider(Collider col)
		{
			return GetColliderCategory(col) == ColliderCategory.Static;
		}

		public static bool IsDynamicCollider(Collider col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (GetColliderCategory(col) == ColliderCategory.Dynamic)
			{
				return (int)((SyncField<ColliderType>)(object)col.Type).Value != 2;
			}
			return false;
		}

		public static bool IsWaterBox(Collider col)
		{
			return GetColliderCategory(col) == ColliderCategory.WaterBox;
		}

		public static bool IsInteractable(Collider col)
		{
			return GetColliderCategory(col) == ColliderCategory.Interactable;
		}

		internal static SM64Surface[] GetAllStaticSurfaces(World wld)
		{
			//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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			StaticSurfaces.Clear();
			List<SM64Surface> val = new List<SM64Surface>();
			List<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>> val2 = new List<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>();
			Enumerator<Collider> enumerator = wld.RootSlot.GetComponentsInChildren<Collider>((Predicate<Collider>)null, false, false, (Predicate<Slot>)null).GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Collider current = enumerator.Current;
					if (IsStaticCollider(current))
					{
						TryParseTagParts(((Component)current).Slot.Tag?.Split(',', (StringSplitOptions)0), out var surfaceType, out var terrainType, out var _, out var idx);
						MeshCollider val3 = (MeshCollider)(object)((current is MeshCollider) ? current : null);
						if (val3 != null)
						{
							val2.Add(new ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>(val3, surfaceType, terrainType, idx));
						}
						else
						{
							GetTransformedSurfaces(current, val, surfaceType, terrainType, idx);
						}
						StaticSurfaces.Add(current);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator).Dispose();
			}
			if (CheckDebug())
			{
				CollectionExtensions.Do<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>(Enumerable.Where<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>((global::System.Collections.Generic.IEnumerable<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>)val2, (Func<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>, bool>)InvalidCollider), (Action<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>)delegate(ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int> invalid)
				{
					//IL_0018: 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_0059: Unknown result type (might be due to invalid IL or missing references)
					//IL_005f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0077: 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)
					Logger.Warn($"- [{((object)invalid.Item1).GetType()}] {((Component)invalid.Item1).Slot.Name} ({((Worker)invalid.Item1).ReferenceID}) Mesh is {((((SyncRef<IAssetProvider<Mesh>>)(object)((MeshBasedCollider<Mesh, MeshColliderData>)(object)invalid.Item1).Mesh).Target == null) ? "null" : "non-readable")}", "GetAllStaticSurfaces", 100);
					StaticSurfaces.Remove((Collider)(object)invalid.Item1);
				});
			}
			val2.RemoveAll((Predicate<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>)InvalidCollider);
			val2.Sort((Comparison<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>>)((ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int> a, ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int> b) => ((MeshBasedCollider<Mesh, MeshColliderData>)(object)a.Item1).Mesh.Asset.Data.TotalTriangleCount.CompareTo(((MeshBasedCollider<Mesh, MeshColliderData>)(object)b.Item1).Mesh.Asset.Data.TotalTriangleCount)));
			int value = Config.MaxMeshColliderTris.Value;
			int num = 0;
			Enumerator<ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int>> enumerator2 = val2.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int> current2 = enumerator2.Current;
					MeshCollider item = current2.Item1;
					SM64Constants.SM64SurfaceType item2 = current2.Item2;
					SM64Constants.SM64TerrainType item3 = current2.Item3;
					int item4 = current2.Item4;
					int totalTriangleCount = ((MeshBasedCollider<Mesh, MeshColliderData>)(object)item).Mesh.Asset.Data.TotalTriangleCount;
					int num2 = num + totalTriangleCount;
					if (num2 > value)
					{
						if (CheckDebug())
						{
							Logger.Warn($"[{((object)item).GetType()}] {((Component)item).Slot.Name} ({((Worker)item).ReferenceID}) Mesh has too many triangles.", "GetAllStaticSurfaces", 121);
						}
						StaticSurfaces.Remove((Collider)(object)item);
					}
					else
					{
						GetTransformedSurfaces((Collider)(object)item, val, item2, item3, item4);
						num = num2;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2).Dispose();
			}
			SM64Context instance = SM64Context.Instance;
			List<Collider> val4 = ((instance != null) ? Enumerable.Except<Collider>((global::System.Collections.Generic.IEnumerable<Collider>)instance.StaticColliders.Keys, (global::System.Collections.Generic.IEnumerable<Collider>)StaticSurfaces).GetTempList() : null);
			if (val4 != null)
			{
				enumerator = val4.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						Collider current3 = enumerator.Current;
						instance.UnregisterStaticCollider(current3);
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator).Dispose();
				}
			}
			return val.ToArray();
			[CompilerGenerated]
			static bool InvalidCollider(ValueTuple<MeshCollider, SM64Constants.SM64SurfaceType, SM64Constants.SM64TerrainType, int> col)
			{
				//IL_0000: 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)
				if (((SyncRef<IAssetProvider<Mesh>>)(object)((MeshBasedCollider<Mesh, MeshColliderData>)(object)col.Item1).Mesh).Target != null)
				{
					return !((MeshBasedCollider<Mesh, MeshColliderData>)(object)col.Item1).Mesh.IsAssetAvailable;
				}
				return true;
			}
		}

		public static void GetTransformedSurfaces(Collider collider, List<SM64Surface> surfaces, SM64Constants.SM64SurfaceType surfaceType, SM64Constants.SM64TerrainType terrainType, int force)
		{
			TransformAndGetSurfaces(surfaces, collider.GetColliderMesh(), surfaceType, terrainType, force, delegate(float3 x)
			{
				//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_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_0028: Unknown result type (might be due to invalid IL or missing references)
				Slot slot = ((Component)collider).Slot;
				float3 val = Sync<float3>.op_Implicit(collider.Offset);
				float3 val2 = (ref x) + (ref val);
				return slot.LocalPointToGlobal(ref val2);
			});
		}

		public static void GetScaledSurfaces(Collider collider, List<SM64Surface> surfaces, SM64Constants.SM64SurfaceType surfaceType, SM64Constants.SM64TerrainType terrainType, int force)
		{
			TransformAndGetSurfaces(surfaces, collider.GetColliderMesh(), surfaceType, terrainType, force, delegate(float3 x)
			{
				//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_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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				float3 globalScale = ((Component)collider).Slot.GlobalScale;
				float3 val = Sync<float3>.op_Implicit(collider.Offset);
				float3 val2 = (ref x) + (ref val);
				return (ref globalScale) * (ref val2);
			});
		}

		public static void TryParseTagParts(string[] tagParts, out SM64Constants.SM64SurfaceType surfaceType, out SM64Constants.SM64TerrainType terrainType, out SM64Constants.SM64InteractableType interactableType, out int idx)
		{
			surfaceType = SM64Constants.SM64SurfaceType.Default;
			terrainType = SM64Constants.SM64TerrainType.Grass;
			interactableType = SM64Constants.SM64InteractableType.None;
			idx = -1;
			if (tagParts == null)
			{
				return;
			}
			SM64Constants.SM64SurfaceType sM64SurfaceType = default(SM64Constants.SM64SurfaceType);
			SM64Constants.SM64TerrainType sM64TerrainType = default(SM64Constants.SM64TerrainType);
			SM64Constants.SM64InteractableType sM64InteractableType = default(SM64Constants.SM64InteractableType);
			int num2 = default(int);
			int num3 = default(int);
			int num4 = default(int);
			int num5 = default(int);
			for (int i = 0; i < tagParts.Length; i++)
			{
				string text = tagParts[i].Trim();
				if (text.StartsWith("SurfaceType_", (StringComparison)5))
				{
					if (global::System.Enum.TryParse<SM64Constants.SM64SurfaceType>(text.Substring("SurfaceType_".Length), true, ref sM64SurfaceType))
					{
						surfaceType = sM64SurfaceType;
					}
				}
				else if (text.StartsWith("TerrainType_", (StringComparison)5))
				{
					if (global::System.Enum.TryParse<SM64Constants.SM64TerrainType>(text.Substring("TerrainType_".Length), true, ref sM64TerrainType))
					{
						terrainType = sM64TerrainType;
					}
				}
				else if (text.StartsWith("InteractableType_", (StringComparison)5))
				{
					string text2 = text.Substring("InteractableType_".Length);
					int num = text2.Length;
					while (num > 0 && char.IsDigit(text2[num - 1]))
					{
						num--;
					}
					string text3 = text2.Substring(0, num);
					string text4 = text2.Substring(num);
					if (global::System.Enum.TryParse<SM64Constants.SM64InteractableType>(text3, true, ref sM64InteractableType))
					{
						interactableType = sM64InteractableType;
						if (int.TryParse(text4, ref num2))
						{
							idx = num2;
						}
					}
				}
				else if (text.StartsWith("Force_", (StringComparison)5))
				{
					string text5 = text.Substring("Force_".Length);
					string[] array = text5.Split('.', (StringSplitOptions)0);
					if (array.Length == 2 && int.TryParse(array[0], ref num3) && int.TryParse(array[1], ref num4))
					{
						idx = (num3 << 8) | num4;
					}
					else if (int.TryParse(text5, ref num5))
					{
						idx = num5;
					}
				}
			}
		}

		public static bool CheckDebug()
		{
			if (0 == 0)
			{
				return Config.DebugEnabled.Value;
			}
			return true;
		}

		public static Dictionary<TKey, TValue> GetTempDictionary<TKey, TValue>(this Dictionary<TKey, TValue> source)
		{
			return new Dictionary<TKey, TValue>((IDictionary<TKey, TValue>)(object)source);
		}

		public static List<T> GetTempList<T>(this List<T> source)
		{
			return new List<T>((global::System.Collections.Generic.IEnumerable<T>)source);
		}

		public static List<T> GetTempList<T>(this global::System.Collections.Generic.IEnumerable<T> source)
		{
			return new List<T>(source);
		}

		public static List<TValue> GetFilteredSortedList<TKey, TValue, TSortKey>(this Dictionary<TKey, TValue> source, Func<TValue, bool> filter = null, Func<TValue, TSortKey> sortKeySelector = null, bool ascending = true)
		{
			global::System.Collections.Generic.IEnumerable<TValue> enumerable = (global::System.Collections.Generic.IEnumerable<TValue>)source.Values;
			if (filter != null)
			{
				enumerable = Enumerable.Where<TValue>(enumerable, filter);
			}
			if (sortKeySelector != null)
			{
				enumerable = (global::System.Collections.Generic.IEnumerable<TValue>)(ascending ? Enumerable.OrderBy<TValue, TSortKey>(enumerable, sortKeySelector) : Enumerable.OrderByDescending<TValue, TSortKey>(enumerable, sortKeySelector));
			}
			return Enumerable.ToList<TValue>(enumerable);
		}

		public static floatQ LookAt(this Slot target, float3 targetPoint)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			float3 val = target.Parent.GlobalPointToLocal(ref targetPoint);
			float3 localPosition = target.LocalPosition;
			float3 val2 = (ref val) - (ref localPosition);
			float3 up = float3.Up;
			return floatQ.LookRotation(ref val2, ref up);
		}

		public static bool HasCapType(uint flags, SM64Constants.MarioCapType capType)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			return capType switch
			{
				SM64Constants.MarioCapType.VanishCap => (flags & 2) != 0, 
				SM64Constants.MarioCapType.MetalCap => (flags & 4) != 0, 
				SM64Constants.MarioCapType.WingCap => (flags & 8) != 0, 
				SM64Constants.MarioCapType.NormalCap => (flags & 1) != 0, 
				_ => throw new ArgumentOutOfRangeException("capType", (object)capType, (string)null), 
			};
		}

		public static User GetAllocatingUser(this Slot slot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			World world = ((Worker)slot).World;
			RefID referenceID = ((Worker)slot).ReferenceID;
			return world.GetUserByAllocationID(((RefID)(ref referenceID)).User);
		}
	}
}
namespace ResoniteMario64.Mario64.libsm64
{
	public static class MarioExtensions
	{
		public static float3 ToMarioRotation(this float3 rot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			return new float3(FixAngle(0f - rot.x), FixAngle(rot.y), FixAngle(rot.z));
		}

		public static float3 FromMarioRotation(this float3 rot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			return new float3(FixAngle(0f - rot.x), FixAngle(rot.y), FixAngle(rot.z));
		}

		public static float3 ToMarioPosition(this float3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			float3 val = Interop.ScaleFactor * (ref pos);
			float3 val2 = new float3(-1f, 1f, 1f);
			return (ref val) * (ref val2);
		}

		public static float3 FromMarioPosition(this float3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			float3 val = (ref pos) / Interop.ScaleFactor;
			float3 val2 = new float3(-1f, 1f, 1f);
			return (ref val) * (ref val2);
		}

		public static float ToMarioFloat(this float value)
		{
			return Interop.ScaleFactor * value;
		}

		public static float3 ToMarioFloat(this float3 value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Interop.ScaleFactor * (ref value);
		}

		public static float FromMarioFloat(this float value)
		{
			return value / Interop.ScaleFactor;
		}

		public static float3 FromMarioFloat(this float3 value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return (ref value) / Interop.ScaleFactor;
		}

		private static float FixAngle(float a)
		{
			return Fmod(a + 180f, 360f) - 180f;
		}

		private static float Fmod(float a, float b)
		{
			return a - b * MathX.Floor(a / b);
		}
	}
	public static class Interop
	{
		[UnmanagedFunctionPointer(/*Could not decode attribute arguments.*/)]
		private delegate void SM64DebugPrintFunctionPtr(string message);

		private delegate void SM64PlaySoundFunctionPtr(uint soundBits, float[] pos);

		private const int SM64TextureWidth = 704;

		private const int SM64TextureHeight = 64;

		public const int SM64GeoMaxTriangles = 1024;

		public const float SM64HealthPerHealthPoint = 256f;

		private const byte HealPointMultiplier = 4;

		private const byte SecondsMultiplier = 40;

		public const int SM64LevelResetValue = -10000;

		private const float SM64MaxVertexDistance = 23170f;

		public const float SM64Deg2Angle = 182.04459f;

		public static bool IsGlobalInit;

		public static float ScaleFactor
		{
			get
			{
				SM64Context instance = SM64Context.Instance;
				bool? obj;
				float result = default(float);
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					DynamicVariableSpace contextVariableSpace = instance.ContextVariableSpace;
					obj = ((contextVariableSpace != null) ? new bool?(contextVariableSpace.TryReadValue<float>("Scale", ref result)) : null);
				}
				bool? flag = obj;
				if (!flag.GetValueOrDefault())
				{
					return Config.MarioScaleFactor.Value;
				}
				return result;
			}
		}

		[DllImport("sm64")]
		private static extern void sm64_register_debug_print_function(nint debugPrintFunctionPtr);

		[DllImport("sm64")]
		private static extern void sm64_register_play_sound_function(nint playSoundFunction);

		[DllImport("sm64")]
		private static extern void sm64_global_init(nint rom, nint outTexture);

		[DllImport("sm64")]
		private static extern void sm64_global_terminate();

		[DllImport("sm64")]
		private static extern void sm64_audio_init(nint rom);

		[DllImport("sm64")]
		private static extern uint sm64_audio_tick(uint numQueuedSamples, uint numDesiredSamples, nint audioBuffer);

		[DllImport("sm64")]
		private static extern void sm64_seq_player_play_sequence(byte player, byte seqId, ushort arg2);

		[DllImport("sm64")]
		private static extern void sm64_play_music(byte player, ushort seqArgs, ushort fadeTimer);

		[DllImport("sm64")]
		private static extern void sm64_stop_background_music(ushort seqId);

		[DllImport("sm64")]
		private static extern void sm64_fadeout_background_music(ushort arg0, ushort fadeOut);

		[DllImport("sm64")]
		private static extern ushort sm64_get_current_background_music();

		[DllImport("sm64")]
		private static extern void sm64_play_sound(int soundBits, nint pos);

		[DllImport("sm64")]
		private static extern void sm64_play_sound_global(int soundBits);

		[DllImport("sm64")]
		private static extern void sm64_set_sound_volume(float vol);

		[DllImport("sm64")]
		private static extern uint sm64_mario_create(float x, float y, float z);

		[DllImport("sm64")]
		private static extern void sm64_mario_tick(uint marioId, ref SM64MarioInputs inputs, ref SM64MarioState outState, ref SM64MarioGeometryBuffers outBuffers);

		[DllImport("sm64")]
		private static extern void sm64_mario_delete(uint marioId);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_action(uint marioId, uint action);

		[DllImport("sm64", EntryPoint = "sm64_set_mario_action")]
		private static extern void sm64_set_mario_action_with_arg(uint marioId, uint action, uint actionArg);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_state(uint marioId, uint flags);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_health(uint marioId, ushort health);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_invincibility(uint marioId, short timer);

		[DllImport("sm64")]
		private static extern void sm64_mario_take_damage(uint marioId, uint damage, uint subtype, float x, float y, float z);

		[DllImport("sm64")]
		private static extern void sm64_mario_heal(uint marioId, byte healCounter);

		[DllImport("sm64")]
		private static extern void sm64_mario_kill(uint marioId);

		[DllImport("sm64")]
		private static extern void sm64_mario_interact_cap(uint marioId, uint capFlag, ushort capTime, byte playMusic);

		[DllImport("sm64")]
		private static extern void sm64_mario_extend_cap(uint marioId, ushort capTime);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_animation(uint marioId, ushort animId);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_anim_frame(uint marioId, short frame);

		[DllImport("sm64")]
		[return: MarshalAs(3)]
		private static extern bool sm64_mario_attack(uint marioId, float x, float y, float z, float hitboxHeight);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_position(uint marioId, float x, float y, float z);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_angle(uint marioId, float x, float y, float z);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_faceangle(uint marioId, float y);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_velocity(uint marioId, float x, float y, float z);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_forward_velocity(uint marioId, float vel);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_water_level(uint marioId, int level);

		[DllImport("sm64")]
		private static extern void sm64_set_mario_gas_level(uint marioId, int level);

		[DllImport("sm64")]
		private static extern void sm64_static_surfaces_load(SM64Surface[] surfaces, ulong numSurfaces);

		[DllImport("sm64")]
		private static extern uint sm64_surface_object_create(ref SM64SurfaceObject surfaceObject);

		[DllImport("sm64")]
		private static extern void sm64_surface_object_move(uint objectId, ref SM64ObjectTransform transform);

		[DllImport("sm64")]
		private static extern void sm64_surface_object_delete(uint objectId);

		[DllImport("sm64")]
		private static extern int sm64_surface_find_wall_collision(ref float x, ref float y, ref float z, float offsetY, float radius);

		[DllImport("sm64")]
		private static extern int sm64_surface_find_wall_collisions(ref nint colData);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_ceil(float x, float y, float z, out nint ceil);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_floor(float x, float y, float z, out nint floor);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_floor_height(float x, float y, float z);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_floor_height_and_data(float x, float y, float z, out nint floorGeo);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_water_level(float x, float z);

		[DllImport("sm64")]
		private static extern float sm64_surface_find_poison_gas_level(float x, float z);

		public static void GlobalInit(byte[] rom)
		{
			//IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			GCHandle val = GCHandle.Alloc((object)rom, (GCHandleType)3);
			GCHandle val2 = GCHandle.Alloc((object)new byte[180224], (GCHandleType)3);
			try
			{
				sm64_global_init(((GCHandle)(ref val)).AddrOfPinnedObject(), ((GCHandle)(ref val2)).AddrOfPinnedObject());
				sm64_audio_init(((GCHandle)(ref val)).AddrOfPinnedObject());
			}
			finally
			{
				((GCHandle)(ref val)).Free();
				((GCHandle)(ref val2)).Free();
			}
			IsGlobalInit = true;
		}

		public static void GlobalTerminate()
		{
			StopMusic();
			sm64_global_terminate();
			IsGlobalInit = false;
		}

		public static bool IsMusicPlaying()
		{
			return sm64_get_current_background_music() != 65535;
		}

		public static bool IsMusicPlaying(SM64Constants.MusicSequence music)
		{
			return (uint)sm64_get_current_background_music() == (uint)music;
		}

		public static void PlayMusic(SM64Constants.MusicSequence music)
		{
			StopMusic();
			sm64_play_music(0, (ushort)music, 0);
		}

		public static void PlayMusic(byte player, ushort seqArgs, ushort fadeTimer)
		{
			sm64_play_music(player, seqArgs, fadeTimer);
		}

		public static void PlayRandomMusic()
		{
			StopMusic();
			sm64_play_music(0, SM64Constants.Musics[RandomX.Range(0, SM64Constants.Musics.Length)], 0);
		}

		public static void StopMusic()
		{
			while (true)
			{
				ushort num = sm64_get_current_background_music();
				if (num != 65535)
				{
					sm64_stop_background_music(num);
					continue;
				}
				break;
			}
		}

		public static void FadeoutBackgroundMusic(ushort fadeOut)
		{
			ushort num = sm64_get_current_background_music();
			if (num != 65535)
			{
				sm64_fadeout_background_music(num, fadeOut);
			}
		}

		public static void StaticSurfacesLoad(SM64Surface[] surfaces)
		{
			Logger.Debug($"Reloading all static collider surfaces - Total Polygons: {surfaces.Length}", "StaticSurfacesLoad", 318);
			sm64_static_surfaces_load(surfaces, (ulong)surfaces.Length);
		}

		public static uint MarioCreate(float3 marioPos)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			return sm64_mario_create(marioPos.x, marioPos.y, marioPos.z);
		}

		public static SM64MarioState MarioTick(uint marioId, SM64MarioInputs inputs, float3[] positionBuffer, float3[] normalBuffer, float3[] colorBuffer, float2[] uvBuffer, out ushort numTrianglesUsed)
		{
			//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_0012: 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_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_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)
			SM64MarioState outState = default(SM64MarioState);
			GCHandle val = GCHandle.Alloc((object)positionBuffer, (GCHandleType)3);
			GCHandle val2 = GCHandle.Alloc((object)normalBuffer, (GCHandleType)3);
			GCHandle val3 = GCHandle.Alloc((object)colorBuffer, (GCHandleType)3);
			GCHandle val4 = GCHandle.Alloc((object)uvBuffer, (GCHandleType)3);
			try
			{
				SM64MarioGeometryBuffers sM64MarioGeometryBuffers = default(SM64MarioGeometryBuffers);
				sM64MarioGeometryBuffers.position = ((GCHandle)(ref val)).AddrOfPinnedObject();
				sM64MarioGeometryBuffers.normal = ((GCHandle)(ref val2)).AddrOfPinnedObject();
				sM64MarioGeometryBuffers.color = ((GCHandle)(ref val3)).AddrOfPinnedObject();
				sM64MarioGeometryBuffers.uv = ((GCHandle)(ref val4)).AddrOfPinnedObject();
				SM64MarioGeometryBuffers outBuffers = sM64MarioGeometryBuffers;
				sm64_mario_tick(marioId, ref inputs, ref outState, ref outBuffers);
				numTrianglesUsed = outBuffers.numTrianglesUsed;
				return outState;
			}
			finally
			{
				((GCHandle)(ref val)).Free();
				((GCHandle)(ref val2)).Free();
				((GCHandle)(ref val3)).Free();
				((GCHandle)(ref val4)).Free();
			}
		}

		public static uint AudioTick(short[] audioBuffer, uint numDesiredSamples, uint numQueuedSamples = 0u)
		{
			//IL_0002: 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)
			GCHandle val = GCHandle.Alloc((object)audioBuffer, (GCHandleType)3);
			try
			{
				return sm64_audio_tick(numQueuedSamples, numDesiredSamples, ((GCHandle)(ref val)).AddrOfPinnedObject());
			}
			finally
			{
				((GCHandle)(ref val)).Free();
			}
		}

		public static void PlaySoundGlobal(SM64Constants.Sounds soundKey)
		{
			sm64_play_sound_global((int)SM64Constants.SoundBank[soundKey]);
		}

		public static void PlaySound(SM64Constants.Sounds soundKey, float3 frooxPosition)
		{
			//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_0006: 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_0018: 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_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)
			float3 val = frooxPosition.ToMarioPosition();
			GCHandle val2 = GCHandle.Alloc((object)new float[3] { val.x, val.y, val.z }, (GCHandleType)3);
			try
			{
				sm64_play_sound((int)SM64Constants.SoundBank[soundKey], ((GCHandle)(ref val2)).AddrOfPinnedObject());
			}
			finally
			{
				((GCHandle)(ref val2)).Free();
			}
		}

		public static void MarioDelete(uint marioId)
		{
			sm64_mario_delete(marioId);
		}

		public static bool MarioAttack(uint marioId, float3 frooxPosition, float hitboxHeight)
		{
			//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_0006: 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_000e: 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)
			float3 val = frooxPosition.ToMarioPosition();
			return sm64_mario_attack(marioId, val.x, val.y, val.z, hitboxHeight.ToMarioFloat());
		}

		public static void MarioTakeDamage(uint marioId, float3 frooxPosition, uint damage, uint subtype = 0u)
		{
			//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_0006: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			float3 val = frooxPosition.ToMarioPosition();
			sm64_mario_take_damage(marioId, damage, subtype, val.x, val.y, val.z);
		}

		public unsafe static void MarioSetVelocity(uint marioId, SM64MarioState previousState, SM64MarioState currentState)
		{
			sm64_set_mario_velocity(marioId, currentState.Position[0] - previousState.Position[0], currentState.Position[1] - previousState.Position[1], currentState.Position[2] - previousState.Position[2]);
		}

		public static void MarioSetVelocity(uint marioId, float3 frooxVelocity)
		{
			//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_0006: 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_000e: 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)
			float3 val = frooxVelocity.ToMarioPosition();
			sm64_set_mario_velocity(marioId, val.x, val.y, val.z);
		}

		public static void MarioSetForwardVelocity(uint marioId, float frooxVelocity)
		{
			sm64_set_mario_forward_velocity(marioId, frooxVelocity * ScaleFactor);
		}

		public static void CreateAndAppendSurfaces(List<SM64Surface> outSurfaces, int[] triangles, float3[] vertices, SM64Constants.SM64SurfaceType surfaceType, SM64Constants.SM64TerrainType terrainType, int force)
		{
			//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_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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0038: 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_004c: 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_005f: 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_006c: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c3: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_00f7: 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_0107: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_0162: 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_017c: 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_018c: 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_0190: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			float3 val4 = default(float3);
			float3 val5 = default(float3);
			float3 val6 = default(float3);
			float3 val7 = default(float3);
			float3 val8 = default(float3);
			float3 val9 = default(float3);
			for (int i = 0; i < triangles.Length; i += 3)
			{
				float3 val = vertices[triangles[i]];
				float3 val2 = vertices[triangles[i + 1]];
				float3 val3 = vertices[triangles[i + 2]];
				((float3)(ref val4))..ctor(0f - val.x, val.y, val.z);
				((float3)(ref val5))..ctor(0f - val2.x, val2.y, val2.z);
				((float3)(ref val6))..ctor(0f - val3.x, val3.y, val3.z);
				((float3)(ref val7))..ctor(val5.x - val4.x, val5.y - val4.y, val5.z - val4.z);
				((float3)(ref val8))..ctor(val6.x - val4.x, val6.y - val4.y, val6.z - val4.z);
				((float3)(ref val9))..ctor(val7.y * val8.z - val7.z * val8.y, val7.z * val8.x - val7.x * val8.z, val7.x * val8.y - val7.y * val8.x);
				if (!(val9.x * val9.x + val9.y * val9.y + val9.z * val9.z <= 1E-06f))
				{
					if (val9.y < 0f)
					{
						float3 val10 = val6;
						val6 = val5;
						val5 = val10;
					}
					SM64Surface sM64Surface = default(SM64Surface);
					sM64Surface.Force = (short)((force != -1) ? force : 0);
					sM64Surface.Type = (short)surfaceType;
					sM64Surface.Terrain = (ushort)terrainType;
					sM64Surface.v0x = (int)ClampToSm64(ScaleFactor * val4.x);
					sM64Surface.v0y = (int)ClampToSm64(ScaleFactor * val4.y);
					sM64Surface.v0z = (int)ClampToSm64(ScaleFactor * val4.z);
					sM64Surface.v1x = (int)ClampToSm64(ScaleFactor * val5.x);
					sM64Surface.v1y = (int)ClampToSm64(ScaleFactor * val5.y);
					sM64Surface.v1z = (int)ClampToSm64(ScaleFactor * val5.z);
					sM64Surface.v2x = (int)ClampToSm64(ScaleFactor * val6.x);
					sM64Surface.v2y = (int)ClampToSm64(ScaleFactor * val6.y);
					sM64Surface.v2z = (int)ClampToSm64(ScaleFactor * val6.z);
					SM64Surface sM64Surface2 = sM64Surface;
					outSurfaces.Add(sM64Surface2);
				}
			}
		}

		private static float ClampToSm64(float value)
		{
			if (!(value > 23170f))
			{
				if (value < -23170f)
				{
					return -23170f;
				}
				return value;
			}
			return 23170f;
		}

		public static void SetWaterLevel(uint marioId, float waterLevel)
		{
			sm64_set_mario_water_level(marioId, (int)waterLevel.ToMarioFloat());
		}

		public static void SetGasLevel(uint marioId, float gasLevel)
		{
			sm64_set_mario_gas_level(marioId, (int)gasLevel.ToMarioFloat());
		}

		public static float FindFloor(float3 pos, out SM64SurfaceCollisionData data)
		{
			//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_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_000d: 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)
			float3 val = pos.ToMarioPosition();
			nint floor;
			float value = sm64_surface_find_floor(val.x, val.y, val.z, out floor);
			data = ((floor == (nint)global::System.IntPtr.Zero) ? default(SM64SurfaceCollisionData) : Marshal.PtrToStructure<SM64SurfaceCollisionData>((global::System.IntPtr)floor));
			return value.FromMarioFloat();
		}

		public static float FindFloorHeight(float3 pos)
		{
			//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_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_000d: 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)
			float3 val = pos.ToMarioPosition();
			return sm64_surface_find_floor_height(val.x, val.y, val.z).FromMarioFloat();
		}

		public static float FindFloorHeightAndData(float3 pos, out SM64FloorCollisionData data)
		{
			//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_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_000d: 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)
			float3 val = pos.ToMarioPosition();
			nint floorGeo;
			float value = sm64_surface_find_floor_height_and_data(val.x, val.y, val.z, out floorGeo);
			data = ((floorGeo == (nint)global::System.IntPtr.Zero) ? default(SM64FloorCollisionData) : Marshal.PtrToStructure<SM64FloorCollisionData>((global::System.IntPtr)floorGeo));
			return value.FromMarioFloat();
		}

		public static float FindCeil(float3 pos, out SM64SurfaceCollisionData data)
		{
			//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_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_000d: 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)
			float3 val = pos.ToMarioPosition();
			nint ceil;
			float value = sm64_surface_find_ceil(val.x, val.y, val.z, out ceil);
			data = ((ceil == (nint)global::System.IntPtr.Zero) ? default(SM64SurfaceCollisionData) : Marshal.PtrToStructure<SM64SurfaceCollisionData>((global::System.IntPtr)ceil));
			return value.FromMarioFloat();
		}

		public static float FindWaterLevel(float3 pos)
		{
			//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_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_000d: Unknown result type (might be due to invalid IL or missing references)
			float3 val = pos.ToMarioPosition();
			return sm64_surface_find_water_level(val.x, val.z).FromMarioFloat();
		}

		public static float FindPoisonGasLevel(float3 pos)
		{
			//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_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_000d: Unknown result type (might be due to invalid IL or missing references)
			float3 val = pos.ToMarioPosition();
			return sm64_surface_find_poison_gas_level(val.x, val.z).FromMarioFloat();
		}

		public static uint SurfaceObjectCreate(float3 position, floatQ rotation, SM64Surface[] surfaces)
		{
			//IL_0002: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			GCHandle val = GCHandle.Alloc((object)surfaces, (GCHandleType)3);
			try
			{
				SM64ObjectTransform transform = SM64ObjectTransform.FromFrooxWorld(position, rotation);
				SM64SurfaceObject sM64SurfaceObject = default(SM64SurfaceObject);
				sM64SurfaceObject.transform = transform;
				sM64SurfaceObject.surfaceCount = (uint)surfaces.Length;
				sM64SurfaceObject.surfaces = ((GCHandle)(ref val)).AddrOfPinnedObject();
				SM64SurfaceObject surfaceObject = sM64SurfaceObject;
				return sm64_surface_object_create(ref surfaceObject);
			}
			finally
			{
				((GCHandle)(ref val)).Free();
			}
		}

		public static void SurfaceObjectMove(uint id, float3 position, floatQ rotation)
		{
			//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)
			SM64ObjectTransform transform = SM64ObjectTransform.FromFrooxWorld(position, rotation);
			sm64_surface_object_move(id, ref transform);
		}

		public static void SurfaceObjectDelete(uint id)
		{
			sm64_surface_object_delete(id);
		}

		public static void MarioCap(uint marioId, SM64Constants.StateFlag stateFlag, float durationSeconds, bool playCapMusic)
		{
			sm64_mario_interact_cap(marioId, (uint)stateFlag, (ushort)(durationSeconds * 40f), playCapMusic ? ((byte)1) : ((byte)0));
		}

		public static void MarioCap(uint marioId, uint flag, float durationSeconds, bool playCapMusic)
		{
			sm64_mario_interact_cap(marioId, flag, (ushort)(durationSeconds * 40f), playCapMusic ? ((byte)1) : ((byte)0));
		}

		public static void MarioCapExtend(uint marioId, float durationSeconds)
		{
			sm64_mario_extend_cap(marioId, (ushort)(durationSeconds * 40f));
		}

		public static void MarioSetPosition(uint marioId, float3 pos)
		{
			//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_0006: 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_000e: 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)
			float3 val = pos.ToMarioPosition();
			sm64_set_mario_position(marioId, val.x, val.y, val.z);
		}

		public static void MarioSetFaceAngle(uint marioId, floatQ rot)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			float num = ((floatQ)(ref rot)).EulerAngles.y;
			if (num > 180f)
			{
				num -= 360f;
			}
			sm64_set_mario_faceangle(marioId, -(float)Math.PI / 180f * num);
		}

		public static void MarioSetRotation(uint marioId, floatQ rotation)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			float3 val = ((floatQ)(ref rotation)).EulerAngles.ToMarioRotation();
			sm64_set_mario_angle(marioId, val.x, val.y, val.z);
		}

		public static void MarioSetHealthPoints(uint marioId, float healthPoints)
		{
			sm64_set_mario_health(marioId, (ushort)(healthPoints * 256f));
		}

		public static void MarioSetInvincibility(uint marioId, short timer)
		{
			sm64_set_mario_invincibility(marioId, timer);
		}

		public static void MarioHeal(uint marioId, byte healthPoints)
		{
			sm64_mario_heal(marioId, (byte)(healthPoints * 4));
		}

		public static void MarioKill(uint marioId)
		{
			sm64_mario_kill(marioId);
		}

		public static void MarioSetAction(uint marioId, SM64Constants.ActionFlag actionFlag)
		{
			sm64_set_mario_action(marioId, (uint)actionFlag);
		}

		public static void MarioSetAction(uint marioId, uint actionFlags)
		{
			sm64_set_mario_action(marioId, actionFlags);
		}

		public static void MarioSetAction(uint marioId, SM64Constants.ActionFlag actionFlag, uint actionArg)
		{
			sm64_set_mario_action_with_arg(marioId, (uint)actionFlag, actionArg);
		}

		public static void MarioSetState(uint marioId, SM64Constants.StateFlag stateFlag)
		{
			sm64_set_mario_state(marioId, (uint)stateFlag);
		}

		public static void MarioSetState(uint marioId, uint stateFlags)
		{
			sm64_set_mario_state(marioId, stateFlags);
		}

		public static void MarioSetAnimation(uint marioId, ushort animId)
		{
			sm64_set_mario_animation(marioId, animId);
		}

		public static void MarioSetAnimFrame(uint marioId, short frame)
		{
			sm64_set_mario_anim_frame(marioId, frame);
		}
	}
	public struct SM64Surface
	{
		public short Type;

		public short Force;

		public ushort Terrain;

		public int v0x;

		public int v0y;

		public int v0z;

		public int v1x;

		public int v1y;

		public int v1z;

		public int v2x;

		public int v2y;

		public int v2z;
	}
	public struct SM64MarioInputs
	{
		public float camLookX;

		public float camLookZ;

		public float stickX;

		public float stickY;

		public byte buttonA;

		public byte buttonB;

		public byte buttonZ;
	}
	public struct SM64MarioState
	{
		[FixedBuffer(typeof(float), 3)]
		public unsafe fixed float Position[3];

		[FixedBuffer(typeof(float), 3)]
		public unsafe fixed float Velocity[3];

		public float FacingAngle;

		public short Health;

		public uint ActionFlags;

		public uint StateFlags;

		public uint ParticleFlags;

		public short InvincibleTimer;

		public unsafe float3 ScaledPosition => MarioExtensions.FromMarioFloat(new float3(0f - Position[0], Position[1], Position[2]));

		public floatQ ScaledRotation => floatQ.Euler(0f, MathX.Repeat(-57.29578f * FacingAngle + 180f, 360f) - 180f, 0f);

		public float HealthPoints => (float)Health / 256f;

		public bool IsDead
		{
			get
			{
				if (!((float)Health < 256f))
				{
					return (ActionFlags & 0x21312) == 135954;
				}
				return true;
			}
		}

		public bool IsAttacking => (ActionFlags & 0x800000) != 0;

		public bool IsFirstPerson => IsFlyingOrSwimming;

		public bool IsFlyingOrSwimming => (ActionFlags & 0x10000000) != 0;

		public bool IsSwimming => (ActionFlags & 0x2000) != 0;

		public bool IsFlying => (ActionFlags & 0x10880899) == 277350553;

		public bool IsTeleporting => (StateFlags & 0x80) != 0;
	}
	public struct SM64MarioGeometryBuffers
	{
		public nint position;

		public nint normal;

		public nint color;

		public nint uv;

		public ushort numTrianglesUsed;
	}
	public struct SM64ObjectTransform
	{
		[FixedBuffer(typeof(float), 3)]
		public unsafe fixed float Position[3];

		[FixedBuffer(typeof(float), 3)]
		public unsafe fixed float EulerRotation[3];

		public unsafe static SM64ObjectTransform FromFrooxWorld(float3 position, floatQ rotation)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0055: 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_007d: 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)
			SM64ObjectTransform result = default(SM64ObjectTransform);
			float3 val = position.ToMarioPosition();
			float3 v