Decompiled source of Gungeon Go Vroom v1.6.0

GungeonGoVroom.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BraveDynamicTree;
using Dungeonator;
using Gunfiguration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using Pathfinding;
using SGUI;
using UnityEngine;
using tk2dRuntime.TileMap;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GGV
{
	internal static class GGVDebug
	{
		[Conditional("DEBUG")]
		internal static void Log(string text)
		{
			Console.WriteLine("[GGV]: " + text);
		}

		[Conditional("DEBUG")]
		internal static void LogPatch(string text)
		{
			Console.WriteLine("[GGV]: " + text);
		}

		[Conditional("DEBUG")]
		internal static void Warn(string text)
		{
			ETGModConsole.Log((object)("<color=#ffffaaff>" + text + "</color>"), false);
		}
	}
	internal static class Dissect
	{
		internal static void DumpComponents(this GameObject g)
		{
			Component[] components = g.GetComponents(typeof(object));
			foreach (Component val in components)
			{
				ETGModConsole.Log((object)("  " + ((object)val).GetType().Name), false);
			}
		}

		internal static void DumpFieldsAndProperties<T>(T o)
		{
			FieldInfo[] fields = typeof(T).GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				Console.WriteLine($"field {fieldInfo.Name} = {fieldInfo.GetValue(o)}");
			}
			foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(o))
			{
				Console.WriteLine(" prop {0} = {1}", property.Name, property.GetValue(o));
			}
		}

		internal static void CompareFieldsAndProperties<T>(T o1, T o2)
		{
			FieldInfo[] fields = typeof(T).GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					if (fieldInfo.GetValue(o1) == null)
					{
						if (fieldInfo.GetValue(o2) != null)
						{
							goto IL_0068;
						}
					}
					else if (fieldInfo.GetValue(o2) == null || !fieldInfo.GetValue(o1).Equals(fieldInfo.GetValue(o2)))
					{
						goto IL_0068;
					}
					goto end_IL_001b;
					IL_0068:
					Console.WriteLine($"field {fieldInfo.Name} = {fieldInfo.GetValue(o1)} -> {fieldInfo.GetValue(o2)}");
					end_IL_001b:;
				}
				catch (Exception)
				{
					Console.WriteLine(" prop {0} = {1} -> {2}", fieldInfo.Name, "ERROR", "ERROR");
				}
			}
			foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(o1))
			{
				try
				{
					if (property.GetValue(o1) == null)
					{
						if (property.GetValue(o2) != null)
						{
							goto IL_0136;
						}
					}
					else if (property.GetValue(o2) == null || !property.GetValue(o1).Equals(property.GetValue(o2)))
					{
						goto IL_0136;
					}
					goto end_IL_00e4;
					IL_0136:
					Console.WriteLine(" prop {0} = {1} -> {2}", property.Name, property.GetValue(o1), property.GetValue(o2));
					end_IL_00e4:;
				}
				catch (Exception)
				{
					Console.WriteLine(" prop {0} = {1} -> {2}", property.Name, "ERROR", "ERROR");
				}
			}
			Console.WriteLine("");
		}

		internal static void DumpILInstruction(this Instruction c)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ETGModConsole.Log((object)("  " + ETGMod.ToStringSafe((object)c)), false);
			}
			catch (Exception)
			{
				try
				{
					ILLabel val = null;
					if (val == null)
					{
						ILPatternMatchingExt.MatchBr(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBeq(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBge(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBgeUn(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBgt(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBgtUn(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBle(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBleUn(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBlt(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBltUn(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBrfalse(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBrtrue(c, ref val);
					}
					if (val == null)
					{
						ILPatternMatchingExt.MatchBneUn(c, ref val);
					}
					if (val != null)
					{
						string[] obj = new string[6]
						{
							"  IL_",
							c.Offset.ToString("x4"),
							": ",
							null,
							null,
							null
						};
						OpCode opCode = c.OpCode;
						obj[3] = ((OpCode)(ref opCode)).Name;
						obj[4] = " IL_";
						obj[5] = val.Target.Offset.ToString("x4");
						ETGModConsole.Log((object)string.Concat(obj), false);
					}
					else
					{
						ETGModConsole.Log((object)"[UNKNOWN INSTRUCTION]", false);
					}
				}
				catch (Exception)
				{
					ETGModConsole.Log((object)"  <error>", false);
				}
			}
		}

		internal static void DumpIL(this ILCursor cursor, string key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<Instruction> enumerator = cursor.Instrs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					enumerator.Current.DumpILInstruction();
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}
	}
	[HarmonyPatch]
	internal static class Patches
	{
		[HarmonyPatch]
		private static class OptimiseIntVectorPointcastPatch
		{
			private static bool _collideWithTriggers;

			private static int _rayMask;

			private static CollisionLayer? _sourceLayer;

			private static IntVector2 _point;

			private static ICollidableObject _tempResult;

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_POINTCAST)
				{
					return false;
				}
				return true;
			}

			private static MethodBase TargetMethod()
			{
				return typeof(PhysicsEngine).GetMethod("Pointcast", new Type[8]
				{
					typeof(IntVector2),
					typeof(SpeculativeRigidbody).MakeByRefType(),
					typeof(bool),
					typeof(bool),
					typeof(int),
					typeof(CollisionLayer?),
					typeof(bool),
					typeof(SpeculativeRigidbody[])
				});
			}

			private static bool CollideWithRigidBodyStatic(SpeculativeRigidbody rigidbody)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)rigidbody) || !((Behaviour)rigidbody).enabled)
				{
					return true;
				}
				List<PixelCollider> pixelColliders = rigidbody.GetPixelColliders();
				for (int i = 0; i < pixelColliders.Count; i++)
				{
					PixelCollider val = pixelColliders[i];
					if ((_collideWithTriggers || !val.IsTrigger) && val.CanCollideWith(_rayMask, _sourceLayer) && val.ContainsPixel(_point))
					{
						_tempResult = (ICollidableObject)(object)rigidbody;
						return false;
					}
				}
				return true;
			}

			private static bool Prefix(PhysicsEngine __instance, ref bool __result, IntVector2 point, out SpeculativeRigidbody result, bool collideWithTiles, bool collideWithRigidbodies, int rayMask, CollisionLayer? sourceLayer, bool collideWithTriggers, params SpeculativeRigidbody[] ignoreList)
			{
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: 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_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_012a: 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)
				if (collideWithTiles && Object.op_Implicit((Object)(object)__instance.TileMap))
				{
					int num = default(int);
					int num2 = default(int);
					__instance.TileMap.GetTileAtPosition(Vector2.op_Implicit(PhysicsEngine.PixelToUnit(point)), ref num, ref num2);
					int tileMapLayerByName = BraveUtility.GetTileMapLayerByName("Collision Layer", __instance.TileMap);
					Tile tile = __instance.GetTile(num, num2, __instance.TileMap, tileMapLayerByName, "Collision Layer", GameManager.Instance.Dungeon.data);
					if (tile != null)
					{
						List<PixelCollider> pixelColliders = tile.GetPixelColliders();
						for (int i = 0; i < pixelColliders.Count; i++)
						{
							PixelCollider val = pixelColliders[i];
							if ((collideWithTriggers || !val.IsTrigger) && val.CanCollideWith(rayMask, sourceLayer) && val.ContainsPixel(point))
							{
								result = null;
								__result = true;
								return false;
							}
						}
					}
				}
				if (collideWithRigidbodies)
				{
					_tempResult = null;
					_collideWithTriggers = collideWithTriggers;
					_rayMask = rayMask;
					_sourceLayer = sourceLayer;
					_point = point;
					b2AABB safeB2AABB = PhysicsEngine.GetSafeB2AABB(point, point);
					__instance.m_rigidbodyTree.Query(safeB2AABB, (Func<SpeculativeRigidbody, bool>)CollideWithRigidBodyStatic);
					if (__instance.CollidesWithProjectiles(rayMask, sourceLayer))
					{
						__instance.m_projectileTree.Query(safeB2AABB, (Func<SpeculativeRigidbody, bool>)CollideWithRigidBodyStatic);
					}
					ICollidableObject tempResult = _tempResult;
					result = (SpeculativeRigidbody)(object)((tempResult is SpeculativeRigidbody) ? tempResult : null);
					__result = (Object)(object)result != (Object)null;
					return false;
				}
				result = null;
				__result = false;
				return false;
			}
		}

		[HarmonyPatch]
		private static class DungeonHandleAmbientPitVFXPatch
		{
			[CompilerGenerated]
			private sealed class <HandleAmbientPitVFXFast>d__2 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public Dungeon self;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <HandleAmbientPitVFXFast>d__2(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_004c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0058: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Invalid comparison between Unknown and I4
					//IL_00de: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f2: 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_0106: Unknown result type (might be due to invalid IL or missing references)
					//IL_0115: Unknown result type (might be due to invalid IL or missing references)
					//IL_014d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0157: Invalid comparison between Unknown and I4
					//IL_0166: Unknown result type (might be due to invalid IL or missing references)
					//IL_016d: Invalid comparison between Unknown and I4
					//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c2: Invalid comparison between Unknown and I4
					//IL_0198: Unknown result type (might be due to invalid IL or missing references)
					//IL_019e: Invalid comparison between Unknown and I4
					//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
					//IL_01e7: Invalid comparison between Unknown and I4
					//IL_020c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0211: Unknown result type (might be due to invalid IL or missing references)
					//IL_0213: Unknown result type (might be due to invalid IL or missing references)
					//IL_022a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0241: Unknown result type (might be due to invalid IL or missing references)
					//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
					//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
					//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
					//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
					//IL_02db: Unknown result type (might be due to invalid IL or missing references)
					//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
					//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
					//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
					//IL_030b: Unknown result type (might be due to invalid IL or missing references)
					//IL_030d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0399: Unknown result type (might be due to invalid IL or missing references)
					//IL_039f: Invalid comparison between Unknown and I4
					//IL_034c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0352: Invalid comparison between Unknown and I4
					//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
					//IL_0354: Unknown result type (might be due to invalid IL or missing references)
					//IL_0356: Unknown result type (might be due to invalid IL or missing references)
					//IL_0416: Unknown result type (might be due to invalid IL or missing references)
					//IL_041b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0424: Unknown result type (might be due to invalid IL or missing references)
					//IL_042e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0433: Unknown result type (might be due to invalid IL or missing references)
					//IL_0435: Unknown result type (might be due to invalid IL or missing references)
					//IL_045d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0462: Unknown result type (might be due to invalid IL or missing references)
					//IL_0467: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						self.m_ambientVFXProcessingActive = true;
						break;
					case 1:
						<>1__state = -1;
						break;
					case 2:
						<>1__state = -1;
						break;
					case 3:
						<>1__state = -1;
						break;
					case 4:
						<>1__state = -1;
						break;
					}
					if (self.m_ambientVFXProcessingActive)
					{
						if (GameManager.Instance.IsLoadingLevel || (int)GameManager.Options.ShaderQuality == 0 || (int)GameManager.Options.ShaderQuality == 3)
						{
							<>2__current = null;
							<>1__state = 1;
							return true;
						}
						DungeonData data = self.data;
						if (data == null)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						CameraController mainCameraController = GameManager.Instance.MainCameraController;
						if (!Object.op_Implicit((Object)(object)mainCameraController))
						{
							<>2__current = null;
							<>1__state = 3;
							return true;
						}
						CellData[][] cellData = data.cellData;
						IntVector2 val = Vector2Extensions.ToIntVector2(mainCameraController.MinVisiblePoint, (VectorConversions)0);
						IntVector2 val2 = Vector2Extensions.ToIntVector2(mainCameraController.MaxVisiblePoint, (VectorConversions)1);
						int num = Mathf.Max(val.x, 3);
						int num2 = Mathf.Max(val.y, 3);
						int num3 = Mathf.Min(val2.x, data.m_width - 3 - 1);
						int num4 = Mathf.Min(val2.y, data.m_height - 3 - 1);
						bool flag = (int)self.tileIndices.tilesetId == 128;
						bool flag2 = (int)self.tileIndices.tilesetId == 64;
						for (int i = num; i <= num3; i++)
						{
							for (int j = num2; j <= num4; j++)
							{
								if (flag)
								{
									CellData val3 = cellData[i][j + 2];
									if (val3 == null || (int)val3.type != 4)
									{
										j += 2;
										continue;
									}
								}
								CellData val4 = cellData[i][j + 1];
								if (val4 == null || (int)val4.type != 4)
								{
									j++;
									continue;
								}
								CellData val5 = cellData[i][j];
								if (val5 == null || (int)val5.type != 4 || val5.fallingPrevented)
								{
									continue;
								}
								CellData val6 = cellData[i][j - 1];
								if (val6 == null)
								{
									continue;
								}
								CellVisualData cellVisualData = val5.cellVisualData;
								if (cellVisualData.precludeAllTileDrawing)
								{
									continue;
								}
								DungeonMaterial val7 = self.roomMaterialDefinitions[cellVisualData.roomVisualTypeIndex];
								if ((Object)(object)val7 == (Object)null)
								{
									continue;
								}
								if (!cellVisualData.HasTriggeredPitVFX)
								{
									cellVisualData.HasTriggeredPitVFX = true;
									cellVisualData.PitVFXCooldown = Random.Range(1f, val7.PitVFXMaxCooldown / 2f);
									cellVisualData.PitParticleCooldown = Random.Range(0f, 1f);
								}
								if (flag || (flag2 && val7.usesFacewallGrids))
								{
									cellVisualData.PitParticleCooldown -= BraveTime.DeltaTime;
									if (cellVisualData.PitParticleCooldown <= 0f)
									{
										Vector3 val8 = Vector2Extensions.ToVector3ZisY(BraveUtility.RandomVector2(((IntVector2)(ref val5.position)).ToVector2(), ((IntVector2)(ref val5.position)).ToVector2() + Vector2.one), 0f);
										cellVisualData.PitParticleCooldown = Random.Range(0.35f, 0.95f);
										if (flag2)
										{
											GlobalSparksDoer.DoSingleParticle(val8, Vector3.zero, (float?)null, (float?)0.375f, (Color?)null, (SparksType)4);
										}
										else
										{
											RoomHandler parentRoom = val5.parentRoom;
											if (parentRoom != null && (int)parentRoom.area.PrototypeRoomCategory != 3)
											{
												GlobalSparksDoer.DoSingleParticle(val8, Vector3.up, (float?)null, (float?)null, (Color?)null, (SparksType)1);
											}
										}
									}
								}
								if (!val7.UsePitAmbientVFX || val7.AmbientPitVFX == null || (int)val6.type != 4)
								{
									continue;
								}
								if (cellVisualData.PitVFXCooldown > 0f)
								{
									cellVisualData.PitVFXCooldown -= BraveTime.DeltaTime;
									continue;
								}
								cellVisualData.PitVFXCooldown = Random.Range(val7.PitVFXMinCooldown, val7.PitVFXMaxCooldown);
								if (!(Random.value >= val7.ChanceToSpawnPitVFXOnCooldown))
								{
									GameObject obj = val7.AmbientPitVFX[Random.Range(0, val7.AmbientPitVFX.Count)];
									Vector3 position = obj.transform.position;
									SpawnManager.SpawnVFX(obj, Vector2Extensions.ToVector3ZisY(((IntVector2)(ref val5.position)).ToVector2(), 0f) + position + new Vector3(Random.Range(0.25f, 0.75f), Random.Range(0.25f, 0.75f), 2f), Quaternion.identity);
								}
							}
						}
						<>2__current = null;
						<>1__state = 4;
						return true;
					}
					self.m_ambientVFXProcessingActive = false;
					return false;
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_PIT_VFX)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Dungeon), "HandleAmbientPitVFX")]
			private static IEnumerator Postfix(IEnumerator orig, Dungeon __instance)
			{
				return HandleAmbientPitVFXFast(__instance);
			}

			private static IEnumerator HandleAmbientPitVFXFast(Dungeon self)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <HandleAmbientPitVFXFast>d__2(0)
				{
					self = self
				};
			}
		}

		[HarmonyPatch]
		private static class DungeonWidthAndHeightPatches
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_DUNGEON_DIMS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(DungeonData), "ClearCachedCellData")]
			[HarmonyPostfix]
			private static void ClearCachedCellData(DungeonData __instance)
			{
				__instance.m_width = __instance.cellData.Length;
				__instance.m_height = __instance.cellData[0].Length;
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void ClearCachedCellData(DungeonData __instance, CellData[][] data)
			{
				__instance.m_width = __instance.cellData.Length;
				__instance.m_height = __instance.cellData[0].Length;
			}

			[HarmonyPatch(typeof(DungeonData), "CheckInBounds", new Type[]
			{
				typeof(int),
				typeof(int)
			})]
			[HarmonyPatch(typeof(DungeonData), "CheckInBounds", new Type[] { typeof(IntVector2) })]
			[HarmonyPatch(typeof(DungeonData), "CheckInBounds", new Type[]
			{
				typeof(IntVector2),
				typeof(int)
			})]
			[HarmonyPatch(typeof(DungeonData), "CheckInBoundsAndValid", new Type[]
			{
				typeof(int),
				typeof(int)
			})]
			[HarmonyPatch(typeof(DungeonData), "CheckInBoundsAndValid", new Type[] { typeof(IntVector2) })]
			[HarmonyPatch(typeof(DungeonData), "FloodFillDungeonExterior")]
			[HarmonyPatch(typeof(DungeonData), "GenerateInterestingVisuals")]
			[HarmonyPatch(typeof(DungeonData), "CheckIntegrity")]
			[HarmonyPatch(typeof(DungeonData), "ExciseElbows")]
			[HarmonyPatch(typeof(DungeonData), "PostGenerationCleanup")]
			[HarmonyPatch(typeof(DungeonData), "GetRoomVisualTypeAtPosition", new Type[]
			{
				typeof(int),
				typeof(int)
			})]
			[HarmonyPatch(typeof(Minimap), "InitializeMinimap")]
			[HarmonyPatch(typeof(TileSpriteClipper), "ClipToTileBounds")]
			[HarmonyPatch(typeof(TK2DInteriorDecorator), "PlaceLightDecoration")]
			[HarmonyPatch(typeof(PhysicsEngine), "LateUpdate")]
			[HarmonyPatch(typeof(OcclusionLayer), "GetRValueForCell")]
			[HarmonyPatch(typeof(OcclusionLayer), "GetGValueForCell")]
			[HarmonyPatch(typeof(OcclusionLayer), "GetCellOcclusion")]
			[HarmonyPatch(typeof(RoomHandler), "StampCell", new Type[]
			{
				typeof(int),
				typeof(int),
				typeof(bool)
			})]
			[HarmonyPatch(typeof(RoomHandler), "StampCellAsExit")]
			[HarmonyILManipulator]
			private static void DungeonDataWidthAndHeightPatchesIL(ILContext il, MethodBase original)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				_ = original.DeclaringType;
				int num = 0;
				while (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCallOrCallvirt<DungeonData>(instr, "get_Width")
				}))
				{
					num++;
					val.Remove();
					val.Emit(OpCodes.Ldfld, typeof(DungeonData).GetField("m_width", BindingFlags.Instance | BindingFlags.NonPublic));
				}
				val.Index = 0;
				while (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCallOrCallvirt<DungeonData>(instr, "get_Height")
				}))
				{
					num++;
					val.Remove();
					val.Emit(OpCodes.Ldfld, typeof(DungeonData).GetField("m_height", BindingFlags.Instance | BindingFlags.NonPublic));
				}
			}
		}

		[HarmonyPatch]
		private static class MathOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_MATH)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(BraveMathCollege), "ClosestPointOnRectangle")]
			[HarmonyPrefix]
			private static bool FastClosestPointOnRectanglePatch(Vector2 point, Vector2 origin, Vector2 dimensions, ref Vector2 __result)
			{
				//IL_0000: 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_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//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_018b: 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_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0180: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_0153: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: 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)
				float x = point.x;
				float y = point.y;
				float x2 = origin.x;
				float num = x2 + dimensions.x;
				float y2 = origin.y;
				float num2 = y2 + dimensions.y;
				if (x <= x2)
				{
					__result = new Vector2(x2, (y < y2) ? y2 : ((y > num2) ? num2 : y));
				}
				else if (x >= num)
				{
					__result = new Vector2(num, (y < y2) ? y2 : ((y > num2) ? num2 : y));
				}
				else if (y <= y2)
				{
					__result = new Vector2((x < x2) ? x2 : ((x > num) ? num : x), y2);
				}
				else if (y >= num2)
				{
					__result = new Vector2((x < x2) ? x2 : ((x > num) ? num : x), num2);
				}
				else
				{
					float num3 = 0.5f * (x2 + num);
					float num4 = 0.5f * (y2 + num2);
					if (x < num3)
					{
						if (y < num4)
						{
							if (x - x2 < y - y2)
							{
								__result = new Vector2(x2, y);
							}
							else
							{
								__result = new Vector2(x, y2);
							}
						}
						else if (x - x2 < num2 - y)
						{
							__result = new Vector2(x2, y);
						}
						else
						{
							__result = new Vector2(x, num2);
						}
					}
					else if (y < num4)
					{
						if (num - x < y - y2)
						{
							__result = new Vector2(num, y);
						}
						else
						{
							__result = new Vector2(x, y2);
						}
					}
					else if (num - x < num2 - y)
					{
						__result = new Vector2(num, y);
					}
					else
					{
						__result = new Vector2(x, num2);
					}
				}
				return false;
			}

			[HarmonyPatch(typeof(PixelCollider), "TransformPixel")]
			[HarmonyPrefix]
			private static bool FastTransformPixelPatch(PixelCollider __instance, Vector2 pixel, Vector2 pivot, float rotation, Vector2 scale, ref Vector2 __result)
			{
				//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_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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				float num = pixel.x - pivot.x;
				float num2 = pixel.y - pivot.y;
				float num3 = rotation * ((float)Math.PI / 180f);
				float num4 = Mathf.Cos(num3);
				float num5 = Mathf.Sin(num3);
				__result = new Vector2((num * num4 - num2 * num5) * scale.x + pivot.x, (num * num5 + num2 * num4) * scale.y + pivot.y);
				return false;
			}

			[HarmonyPatch(typeof(b2AABB), "Combine", new Type[] { typeof(b2AABB) })]
			[HarmonyPrefix]
			private static bool Fastb2AABBCombine(ref b2AABB __instance, b2AABB aabb)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: 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_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: 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_00cf: 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)
				__instance.lowerBound.x = ((__instance.lowerBound.x < aabb.lowerBound.x) ? __instance.lowerBound.x : aabb.lowerBound.x);
				__instance.lowerBound.y = ((__instance.lowerBound.y < aabb.lowerBound.y) ? __instance.lowerBound.y : aabb.lowerBound.y);
				__instance.upperBound.x = ((__instance.upperBound.x > aabb.upperBound.x) ? __instance.upperBound.x : aabb.upperBound.x);
				__instance.upperBound.y = ((__instance.upperBound.y > aabb.upperBound.y) ? __instance.upperBound.y : aabb.upperBound.y);
				return false;
			}

			[HarmonyPatch(typeof(b2AABB), "Combine", new Type[]
			{
				typeof(b2AABB),
				typeof(b2AABB)
			})]
			[HarmonyPrefix]
			private static bool Fastb2AABBCombine(ref b2AABB __instance, b2AABB aabb1, b2AABB aabb2)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_002c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				__instance.lowerBound.x = ((aabb1.lowerBound.x < aabb2.lowerBound.x) ? aabb1.lowerBound.x : aabb2.lowerBound.x);
				__instance.lowerBound.y = ((aabb1.lowerBound.y < aabb2.lowerBound.y) ? aabb1.lowerBound.y : aabb2.lowerBound.y);
				__instance.upperBound.x = ((aabb1.upperBound.x > aabb2.upperBound.x) ? aabb1.upperBound.x : aabb2.upperBound.x);
				__instance.upperBound.y = ((aabb1.upperBound.y > aabb2.upperBound.y) ? aabb1.upperBound.y : aabb2.upperBound.y);
				return false;
			}
		}

		[HarmonyPatch]
		private static class DepthCheckOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_DEPTH_CHECKS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(tk2dBaseSprite), "UpdateZDepthInternal")]
			[HarmonyPrefix]
			private static bool FastUpdateZDepthInternal(tk2dBaseSprite __instance, float targetZValue, float currentYValue)
			{
				//IL_000d: 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_0013: 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)
				__instance.IsZDepthDirty = false;
				Vector3 position = __instance.m_transform.position;
				if (position.z != targetZValue)
				{
					position.z = targetZValue;
					__instance.m_transform.position = position;
				}
				if (__instance.attachedRenderers == null || __instance.attachedRenderers.Count <= 0)
				{
					return false;
				}
				bool isPerpendicular = __instance.IsPerpendicular;
				for (int i = 0; i < __instance.attachedRenderers.Count; i++)
				{
					tk2dBaseSprite val = __instance.attachedRenderers[i];
					if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val.attachParent != (Object)(object)__instance)
					{
						__instance.attachedRenderers.RemoveAt(i--);
						continue;
					}
					val.UpdateZDepthAttached(targetZValue, currentYValue, isPerpendicular);
					if (!val.independentOrientation && isPerpendicular != val.IsPerpendicular)
					{
						val.IsPerpendicular = isPerpendicular;
					}
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class GUIHitTestOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				return false;
			}

			[HarmonyPatch(typeof(dfGUIManager), "HitTest")]
			[HarmonyPrefix]
			private static bool HitTestPatch(dfGUIManager __instance, Vector2 screenPosition, ref dfControl __result)
			{
				__result = null;
				if (GameManager.HasInstance && !GameManager.Instance.IsPaused && (!Object.op_Implicit((Object)(object)Minimap.m_instance) || !Minimap.Instance.m_isFullscreen) && !Foyer.DoIntroSequence && !Foyer.DoMainMenu)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class ProjectileSpawnOptimizations
		{
			private static HashSet<GameObject> _ProcessedProjPrefabs = new HashSet<GameObject>();

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_PROJ_STATUS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(SpawnManager), "SpawnProjectile", new Type[]
			{
				typeof(GameObject),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(bool)
			})]
			[HarmonyPrefix]
			private static void SpawnManagerSpawnProjectilePatch(SpawnManager __instance, GameObject prefab, Vector3 position, Quaternion rotation, bool ignoresPools)
			{
				if (_ProcessedProjPrefabs.Contains(prefab))
				{
					return;
				}
				Projectile component = prefab.GetComponent<Projectile>();
				if (component != null)
				{
					if (!component.AppliesPoison)
					{
						component.healthEffect = null;
					}
					if (!component.AppliesSpeedModifier)
					{
						component.speedEffect = null;
					}
					if (!component.AppliesCharm)
					{
						component.charmEffect = null;
					}
					if (!component.AppliesFreeze)
					{
						component.freezeEffect = null;
					}
					if (!component.AppliesCheese)
					{
						component.cheeseEffect = null;
					}
					if (!component.AppliesBleed)
					{
						component.bleedEffect = null;
					}
					if (!component.AppliesFire)
					{
						component.fireEffect = null;
					}
					if (!component.baseData.UsesCustomAccelerationCurve)
					{
						component.baseData.AccelerationCurve = null;
					}
					_ProcessedProjPrefabs.Add(prefab);
				}
			}
		}

		[HarmonyPatch]
		private static class dfGUIEventOptimizations
		{
			private static readonly FieldInfo[] _NoFieldInfo = new FieldInfo[0];

			private static readonly Dictionary<Type, FieldInfo[]> _CachedFields = new Dictionary<Type, FieldInfo[]>();

			private static readonly BindingFlags _FieldFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_GUI_EVENTS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(dfReflectionExtensions), "GetAllFields")]
			[HarmonyPrefix]
			private static bool dfReflectionExtensionsGetAllFieldsPatch(Type type, ref FieldInfo[] __result)
			{
				if ((object)type == null)
				{
					__result = _NoFieldInfo;
					return false;
				}
				if (_CachedFields.TryGetValue(type, out var value))
				{
					__result = value;
					return false;
				}
				FieldInfo[] array2 = (_CachedFields[type] = (from f in type.GetFields(_FieldFlags).Concat(dfReflectionExtensions.GetAllFields(dfReflectionExtensions.GetBaseType(type)))
					where !f.IsDefined(typeof(HideInInspector), inherit: true)
					select f).ToArray());
				__result = array2;
				return false;
			}
		}

		[HarmonyPatch]
		private static class ItemLookupOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_ITEM_LOOKUPS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(PlayerController), "HasPassiveItem")]
			[HarmonyPrefix]
			private static bool PlayerControllerHasPassiveItemPatch(PlayerController __instance, int pickupId, ref bool __result)
			{
				for (int num = __instance.passiveItems.Count - 1; num >= 0; num--)
				{
					if (((PickupObject)__instance.passiveItems[num]).PickupObjectId == pickupId)
					{
						__result = true;
						return false;
					}
				}
				__result = false;
				return false;
			}

			[HarmonyPatch(typeof(PlayerController), "HasActiveItem")]
			[HarmonyPrefix]
			private static bool PlayerControllerHasActiveItemPatch(PlayerController __instance, int pickupId, ref bool __result)
			{
				for (int num = __instance.activeItems.Count - 1; num >= 0; num--)
				{
					if (((PickupObject)__instance.activeItems[num]).PickupObjectId == pickupId)
					{
						__result = true;
						return false;
					}
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch]
		private static class LightCullingOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_LIGHT_CULL)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Pixelator), "LightCulled")]
			[HarmonyPrefix]
			private static bool PixelatorLightCulledPatch(Pixelator __instance, Vector2 lightPosition, Vector2 cameraPosition, float lightRange, float orthoSize, float aspect, ref bool __result)
			{
				//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_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)
				float num = lightPosition.x - cameraPosition.x;
				float num2 = lightPosition.y - cameraPosition.y;
				float num3 = lightRange + orthoSize * __instance.LightCullFactor * aspect;
				__result = num * num + num2 * num2 > num3 * num3;
				return false;
			}
		}

		[HarmonyPatch]
		private static class FloodFillOptimizations
		{
			private static readonly Stack<IntVector2> _FloodFillStack = new Stack<IntVector2>();

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_FLOOD_FILL)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(DungeonData), "FloodFillDungeonExterior")]
			[HarmonyPrefix]
			private static bool FloodFillDungeonExteriorPatch(DungeonData __instance)
			{
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_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_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Invalid comparison between Unknown and I4
				int width = __instance.m_width;
				int height = __instance.m_height;
				int num = Mathf.CeilToInt((float)(width * height) / 64f);
				if (num > _Bitfield.Length)
				{
					Array.Resize(ref _Bitfield, num);
				}
				for (int num2 = num - 1; num2 >= 0; num2--)
				{
					_Bitfield[num2] = 0uL;
				}
				CellData[][] cellData = __instance.cellData;
				if (cellData[0][0] != null)
				{
					cellData[0][0].isRoomInternal = false;
				}
				_Bitfield[0] = 1uL;
				_FloodFillStack.Push(IntVector2.Zero);
				while (_FloodFillStack.Count > 0)
				{
					IntVector2 val = _FloodFillStack.Pop();
					for (int i = 0; i < IntVector2.Cardinals.Length; i++)
					{
						IntVector2 val2 = val + IntVector2.Cardinals[i];
						int x = val2.x;
						int y = val2.y;
						if (x < 0 || y < 0 || x >= width || y >= height)
						{
							continue;
						}
						int num3 = y * width + x;
						int num4 = Mathf.FloorToInt((float)num3 / 64f);
						ulong num5 = (ulong)(1L << num3 % 64);
						if ((_Bitfield[num4] & num5) == num5)
						{
							continue;
						}
						_Bitfield[num4] |= num5;
						CellData val3 = cellData[x][y];
						if (val3 != null)
						{
							if (((int)val3.type != 1 || val3.breakable) && !val3.isExitCell)
							{
								continue;
							}
							val3.isRoomInternal = false;
						}
						_FloodFillStack.Push(val2);
					}
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class GUINumberOptimizations
		{
			private const int _MAX_CACHED_NUMBER = 100000;

			private static readonly Dictionary<int, string> _CachedNumberStrings = new Dictionary<int, string>();

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_NUMBERS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(SGUIIMBackend), "NextComponentName")]
			[HarmonyILManipulator]
			private static void SGUIIMBackendNextComponentNamePatch(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCall<int>(instr, "ToString")
				}))
				{
					val.Remove();
					val.CallPrivate(typeof(GUINumberOptimizations), "CachedStringForNumber");
				}
			}

			private static string CachedStringForNumber(ref int n)
			{
				if (n > 100000)
				{
					return n.ToString();
				}
				if (_CachedNumberStrings.TryGetValue(n, out var value))
				{
					return value;
				}
				return _CachedNumberStrings[n] = n.ToString();
			}
		}

		[HarmonyPatch]
		private static class TitleScreenOptimizations
		{
			private static bool _CheckForPlayer;

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_TITLE_SCREEN)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPrefix]
			private static bool PrimaryPlayerPatch(GameManager __instance, ref PlayerController __result)
			{
				if (!_CheckForPlayer && !Object.op_Implicit((Object)(object)__instance.m_player) && !GameManager.Instance.IsLoadingLevel && (Foyer.DoIntroSequence || Foyer.DoMainMenu))
				{
					__result = null;
					return false;
				}
				_CheckForPlayer = false;
				return true;
			}

			[HarmonyPatch(typeof(PlayerController), "Start")]
			[HarmonyPostfix]
			private static void PrimaryPlayerPatch(PlayerController __instance)
			{
				_CheckForPlayer = true;
				_ = GameManager.Instance.PrimaryPlayer;
			}
		}

		[HarmonyPatch]
		private static class SpriteChunkOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_CHUNK_CHECKS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPrefix]
			private static bool SpriteChunkIrrelevantToGameplayPatch(SpriteChunk __instance, ref bool __result)
			{
				DungeonData data = GameManager.Instance.Dungeon.data;
				int num = data.m_width - 1;
				int num2 = data.m_height - 1;
				int currentCellXOffset = RenderMeshBuilder.CurrentCellXOffset;
				int currentCellYOffset = RenderMeshBuilder.CurrentCellYOffset;
				int num3 = __instance.startX + currentCellXOffset;
				if (num3 < 0)
				{
					num3 = 0;
				}
				int num4 = __instance.startY + currentCellYOffset;
				if (num4 < 0)
				{
					num4 = 0;
				}
				int num5 = __instance.endX + currentCellXOffset;
				if (num5 > num)
				{
					num5 = num;
				}
				int num6 = __instance.endY + currentCellYOffset;
				if (num6 > num2)
				{
					num6 = num2;
				}
				CellData[][] cellData = data.cellData;
				for (int i = num3; i < num5; i++)
				{
					for (int j = num4; j < num6; j++)
					{
						CellData val = cellData[i][j];
						if (val != null && val.distanceFromNearestRoom <= 15f)
						{
							__result = false;
							return false;
						}
					}
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch]
		private static class PathingOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_PATH_RECALC)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Pathfinder), "RecalculateClearances", new Type[]
			{
				typeof(int),
				typeof(int),
				typeof(int),
				typeof(int)
			})]
			[HarmonyPrefix]
			private static bool RecalculateClearancesPatch(Pathfinder __instance, int minX, int minY, int maxX, int maxY)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Invalid comparison between Unknown and I4
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Invalid comparison between Unknown and I4
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Invalid comparison between Unknown and I4
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Invalid comparison between Unknown and I4
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Invalid comparison between Unknown and I4
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0200: Invalid comparison between Unknown and I4
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0153: Invalid comparison between Unknown and I4
				//IL_0207: Unknown result type (might be due to invalid IL or missing references)
				//IL_020d: Invalid comparison between Unknown and I4
				//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ee: Invalid comparison between Unknown and I4
				//IL_0260: Unknown result type (might be due to invalid IL or missing references)
				//IL_0266: Invalid comparison between Unknown and I4
				//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f8: Invalid comparison between Unknown and I4
				//IL_026a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0270: Invalid comparison between Unknown and I4
				PathNode[] nodes = __instance.m_nodes;
				int width = __instance.m_width;
				int height = __instance.m_height;
				int num = maxX + maxY * width;
				CellData cellData = nodes[num].CellData;
				if (cellData == null || cellData.isOccupied || (int)cellData.type == 1 || ((int)cellData.type == 4 && !cellData.fallingPrevented))
				{
					nodes[num].SquareClearance = 0;
				}
				else
				{
					nodes[num].SquareClearance = 1;
				}
				for (int num2 = maxX - 1; num2 >= minX; num2--)
				{
					int num3 = num2 + maxY * width;
					_ = ref nodes[num3];
					int num4 = nodes[num3 + 1].SquareClearance + 1;
					int num5 = 0;
					while (true)
					{
						if (num5 < num4)
						{
							int num6 = maxY + num5;
							if (num6 == height)
							{
								break;
							}
							CellData cellData2 = nodes[num2 + num6 * width].CellData;
							if (cellData2 == null || cellData2.isOccupied || (int)cellData2.type == 1 || ((int)cellData2.type == 4 && !cellData2.fallingPrevented))
							{
								break;
							}
							num5++;
							continue;
						}
						int num7 = num2 + num4;
						if (num7 > width)
						{
							num7 = width;
						}
						for (int i = num2; i < num7; i++)
						{
							CellData cellData3 = nodes[i + (maxY + num4 - 1) * width].CellData;
							if (cellData3 == null || cellData3.isOccupied || (int)cellData3.type == 1 || ((int)cellData3.type == 4 && !cellData3.fallingPrevented))
							{
								num5--;
								break;
							}
						}
						break;
					}
					nodes[num3].SquareClearance = num5;
				}
				for (int num8 = maxY - 1; num8 >= minY; num8--)
				{
					int num9 = maxX + num8 * width;
					_ = ref nodes[num9];
					int num10 = nodes[num9 + width].SquareClearance + 1;
					int num11 = 0;
					while (true)
					{
						if (num11 < num10)
						{
							int num12 = maxX + num11;
							if (num12 == width)
							{
								break;
							}
							CellData cellData4 = nodes[num12 + num8 * width].CellData;
							if (cellData4 == null || cellData4.isOccupied || (int)cellData4.type == 1 || ((int)cellData4.type == 4 && !cellData4.fallingPrevented))
							{
								break;
							}
							num11++;
							continue;
						}
						int num13 = num8 + num10;
						if (num13 > height)
						{
							num13 = height;
						}
						for (int j = num8; j < num13; j++)
						{
							CellData cellData5 = nodes[maxX + num10 - 1 + j * width].CellData;
							if (cellData5 == null || cellData5.isOccupied || (int)cellData5.type == 1 || ((int)cellData5.type == 4 && !cellData5.fallingPrevented))
							{
								num11--;
								break;
							}
						}
						break;
					}
					nodes[num9].SquareClearance = num11;
				}
				for (int num14 = maxX - 1; num14 >= minX; num14--)
				{
					for (int num15 = maxY - 1; num15 >= minY; num15--)
					{
						int num16 = num14 + num15 * width;
						CellData cellData6 = nodes[num16].CellData;
						if (cellData6 == null || cellData6.isOccupied || (int)cellData6.type == 1 || ((int)cellData6.type == 4 && !cellData6.fallingPrevented))
						{
							nodes[num16].SquareClearance = 0;
						}
						else
						{
							int num17 = nodes[num16 + width + 1].SquareClearance;
							int squareClearance = nodes[num16 + 1].SquareClearance;
							if (squareClearance < num17)
							{
								num17 = squareClearance;
							}
							int squareClearance2 = nodes[num16 + width].SquareClearance;
							if (squareClearance2 < num17)
							{
								num17 = squareClearance2;
							}
							int num18 = 1 + num17;
							int num19 = maxX - num14 + 1;
							int num20 = maxY - num15 + 1;
							int num21 = ((num19 > num20) ? num19 : num20);
							nodes[num16].SquareClearance = ((num18 < num21) ? num18 : num21);
						}
					}
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class SpriteVisiblityOptimizations
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_VIS_CHECKS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(tk2dSpriteAnimator), "LateUpdate")]
			[HarmonyILManipulator]
			private static void tk2dSpriteAnimatorLateUpdatePatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCall<tk2dSpriteAnimator>(instr, "HandleVisibilityCheck")
				}))
				{
					val.Remove();
					val.CallPrivate(typeof(SpriteVisiblityOptimizations), "FastHandleVisibilityCheck");
				}
			}

			private static void FastHandleVisibilityCheck(tk2dSpriteAnimator animator)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				if (animator.alwaysUpdateOffscreen || !tk2dSpriteAnimator.InDungeonScene)
				{
					animator.m_isCurrentlyVisible = true;
					return;
				}
				Vector3 position = ((BraveBehaviour)animator).transform.position;
				float num = position.x - tk2dSpriteAnimator.CameraPositionThisFrame.x;
				float num2 = position.y - tk2dSpriteAnimator.CameraPositionThisFrame.y;
				animator.m_isCurrentlyVisible = num * num + num2 * num2 * 2.89f < 420f + animator.AdditionalCameraVisibilityRadius * animator.AdditionalCameraVisibilityRadius;
			}
		}

		[HarmonyPatch]
		private static class FastPauseMenu
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.OPT_PAUSE)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Pixelator), "OnRenderImage")]
			[HarmonyPrefix]
			private static bool PixelatorOnRenderImagePatch(Pixelator __instance, RenderTexture source, RenderTexture target)
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if (!GameManager.HasInstance || !GameManager.Instance.IsPaused || GameManager.Instance.PreventPausing)
				{
					return true;
				}
				if (Object.op_Implicit((Object)(object)__instance.m_bloomer) && ((Behaviour)__instance.m_bloomer).enabled)
				{
					((Behaviour)__instance.m_bloomer).enabled = false;
				}
				float num = Screen.height;
				Rect rect = __instance.m_camera.rect;
				float a = Mathf.Max(1f, Mathf.Min(20f, num * ((Rect)(ref rect)).height / 270f));
				float a2 = Pixelator.Instance.ScaleTileScale / 3f * GameUIRoot.GameUIScalar;
				if (!a.Approximately(__instance.ScaleTileScale))
				{
					__instance.CheckSize();
				}
				else if (!a2.Approximately(GameUIRoot.Instance.m_manager.UIScale))
				{
					__instance.CheckSize();
				}
				BraveCameraUtility.MaintainCameraAspect(__instance.m_camera);
				Graphics.Blit((Texture)(object)Pixelator.m_smallBlackTexture, target);
				return false;
			}

			[HarmonyPatch(typeof(tk2dSpriteAnimator), "LateUpdate")]
			[HarmonyPatch(typeof(AIAnimator), "Update")]
			[HarmonyPatch(typeof(EmbersController), "Update")]
			[HarmonyPatch(typeof(PlayerHandController), "LateUpdate")]
			[HarmonyPatch(typeof(ShadowSystem), "LateUpdate")]
			[HarmonyPatch(typeof(KnockbackDoer), "Update")]
			[HarmonyPatch(typeof(GameUIBossHealthController), "LateUpdate")]
			[HarmonyPatch(typeof(CameraController), "LateUpdate")]
			[HarmonyILManipulator]
			private static void DontUpdateWhilePausedPatchIL(ILContext il)
			{
				//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_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: 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_0051: 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_005e: 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_006b: 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_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				ILLabel val2 = val.DefineLabel();
				FieldInfo field = typeof(GameManager).GetField("mr_manager", BindingFlags.Static | BindingFlags.NonPublic);
				val.Emit(OpCodes.Ldsfld, field);
				val.Emit(OpCodes.Call, (MethodBase)typeof(Object).GetMethod("op_Implicit"));
				val.Emit(OpCodes.Brfalse, (object)val2);
				val.Emit(OpCodes.Ldsfld, field);
				val.Emit(OpCodes.Ldfld, typeof(GameManager).GetField("m_paused", BindingFlags.Instance | BindingFlags.NonPublic));
				val.Emit(OpCodes.Brfalse, (object)val2);
				val.Emit(OpCodes.Ret);
				val.MarkLabel(val2);
			}

			private static bool CheckIfPaused()
			{
				if (GameManager.HasInstance)
				{
					return GameManager.Instance.IsPaused;
				}
				return false;
			}

			[HarmonyPatch(typeof(GameManager), "Update")]
			[HarmonyILManipulator]
			private static void GameManagerUpdatePatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 0),
					(Instruction instr) => ILPatternMatchingExt.MatchStloc(instr, 1)
				}))
				{
					int index = val.Index + 1;
					val.Index = index;
					val.CallPrivate(typeof(FastPauseMenu), "IntMaxIfPaused");
				}
			}

			private static int IntMaxIfPaused(int orig)
			{
				if (!GameManager.HasInstance || !GameManager.Instance.IsPaused)
				{
					return orig;
				}
				return int.MaxValue;
			}
		}

		[HarmonyPatch]
		private static class RoomShuffleOffByOneFix
		{
			[CompilerGenerated]
			private sealed class <TargetMethods>d__1 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private MethodBase <>2__current;

				private int <>l__initialThreadId;

				private MethodInfo <genShuffle>5__2;

				private MethodInfo <standardShuffle>5__3;

				MethodBase IEnumerator<MethodBase>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <TargetMethods>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<genShuffle>5__2 = null;
					<standardShuffle>5__3 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<genShuffle>5__2 = typeof(BraveUtility).GetMethod("GenerationShuffle", BindingFlags.Static | BindingFlags.Public);
						<>2__current = <genShuffle>5__2.MakeGenericMethod(typeof(int));
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<>2__current = <genShuffle>5__2.MakeGenericMethod(typeof(IntVector2));
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -1;
						<>2__current = <genShuffle>5__2.MakeGenericMethod(typeof(Tuple<RuntimeRoomExitData, RuntimeRoomExitData>));
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -1;
						<>2__current = <genShuffle>5__2.MakeGenericMethod(typeof(PrototypeRoomExit));
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -1;
						<standardShuffle>5__3 = typeof(BraveUtility).GetMethod("Shuffle", BindingFlags.Static | BindingFlags.Public);
						<>2__current = <standardShuffle>5__3.MakeGenericMethod(typeof(int));
						<>1__state = 5;
						return true;
					case 5:
						<>1__state = -1;
						<>2__current = <standardShuffle>5__3.MakeGenericMethod(typeof(IntVector2));
						<>1__state = 6;
						return true;
					case 6:
						<>1__state = -1;
						<>2__current = <standardShuffle>5__3.MakeGenericMethod(typeof(AIActor));
						<>1__state = 7;
						return true;
					case 7:
						<>1__state = -1;
						<>2__current = <standardShuffle>5__3.MakeGenericMethod(typeof(IPaydayItem));
						<>1__state = 8;
						return true;
					case 8:
						<>1__state = -1;
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
				{
					if (<>1__state == -2 && <>l__initialThreadId == Thread.CurrentThread.ManagedThreadId)
					{
						<>1__state = 0;
						return this;
					}
					return new <TargetMethods>d__1(0);
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<MethodBase>)this).GetEnumerator();
				}
			}

			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_SHUFFLE)
				{
					return false;
				}
				return true;
			}

			private static IEnumerable<MethodBase> TargetMethods()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <TargetMethods>d__1(-2);
			}

			[HarmonyILManipulator]
			private static void GenerationShuffleFixIL(ILContext il)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0040: 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_0085: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdloc(instr, 0)
				}))
				{
					val.Emit(OpCodes.Ldc_I4_1);
					val.Emit(OpCodes.Add);
					ILLabel forLabel = null;
					if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
					{
						(Instruction instr) => ILPatternMatchingExt.MatchBgt(instr, ref forLabel)
					}))
					{
						val.Remove();
						val.Emit(OpCodes.Bge, (object)forLabel);
					}
				}
			}
		}

		[HarmonyPatch]
		private static class DuctTapeFix
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_DUCT_TAPE)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Gun), "CopyStateFrom")]
			[HarmonyPostfix]
			private static void DuctTapeSaveLoadPatch(Gun __instance, Gun other)
			{
				__instance.DuctTapeMergedGunIDs = other.DuctTapeMergedGunIDs;
			}
		}

		[HarmonyPatch]
		private static class QuickRestartFixes
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_QUICK_RESTART)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(GameManager), "QuickRestart")]
			[HarmonyILManipulator]
			private static void QuickRestartRoomCachePatch(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdstr(instr, "Quick Restarting..."),
					(Instruction instr) => ILPatternMatchingExt.MatchCall<Debug>(instr, "Log")
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(QuickRestartFixes), "ForcePreprocessRunForQuickStart");
				}
			}

			private static void ForcePreprocessRunForQuickStart(GameManager gm)
			{
				if (Object.op_Implicit((Object)(object)gm))
				{
					gm.GlobalInjectionData.PreprocessRun(false);
				}
			}
		}

		[HarmonyPatch]
		private static class AmmoUIFixes
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_AMMO_UI)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(GameUIAmmoController), "UpdateAmmoUIForModule")]
			[HarmonyPostfix]
			private static void GameUIAmmoControllerUpdateAmmoUIForModulePatch(GameUIAmmoController __instance, ref dfTiledSprite currentAmmoFGSprite, ref dfTiledSprite currentAmmoBGSprite, List<dfTiledSprite> AddlModuleFGSprites, List<dfTiledSprite> AddlModuleBGSprites, dfSprite ModuleTopCap, dfSprite ModuleBottomCap, ProjectileModule module, Gun currentGun, ref AmmoType cachedAmmoTypeForModule, ref string cachedCustomAmmoTypeForModule, ref int cachedShotsInClip, bool didChangeGun, int numberRemaining)
			{
				if (AddlModuleBGSprites != null && AddlModuleBGSprites.Count >= 1 && AddlModuleFGSprites != null && AddlModuleFGSprites.Count >= 1)
				{
					((dfControl)AddlModuleFGSprites[0]).ZOrder = ((dfControl)AddlModuleBGSprites[0]).ZOrder + 1;
					if ((Object)(object)currentAmmoFGSprite != (Object)null)
					{
						((dfControl)currentAmmoFGSprite).ZOrder = ((dfControl)AddlModuleFGSprites[0]).ZOrder + 1;
					}
				}
			}
		}

		[HarmonyPatch]
		private static class OrbitalGunFixes
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_ORBITAL_GUN)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(HoveringGunController), "Initialize")]
			[HarmonyPostfix]
			private static void HoveringGunDoesntShootProperlyWhenCreatedWhileFacingLeftPatch(HoveringGunController __instance)
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)__instance.m_owner) && Object.op_Implicit((Object)(object)((BraveBehaviour)__instance.m_owner).sprite) && ((BraveBehaviour)__instance.m_owner).sprite.FlipX)
				{
					Transform shootPointTransform = __instance.m_shootPointTransform;
					shootPointTransform.localPosition = Vector3Extensions.WithY(shootPointTransform.localPosition, 0f - shootPointTransform.localPosition.y);
				}
			}
		}

		[HarmonyPatch]
		private static class CoopTurboFixes
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_COOP_TURBO)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(PlayerController), "UpdateTurboModeStats")]
			[HarmonyILManipulator]
			private static void CoopTurboModeFixHookIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdfld<PlayerController>(instr, "m_turboSpeedModifier"),
					(Instruction instr) => instr.OpCode == OpCodes.Callvirt
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(CoopTurboFixes), "RecalculateTurboStats");
					if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
					{
						(Instruction instr) => ILPatternMatchingExt.MatchLdfld<PlayerController>(instr, "m_turboRollSpeedModifier"),
						(Instruction instr) => instr.OpCode == OpCodes.Callvirt
					}))
					{
						val.Emit(OpCodes.Ldarg_0);
						val.CallPrivate(typeof(CoopTurboFixes), "RecalculateTurboStats");
					}
				}
			}

			private static void RecalculateTurboStats(PlayerController player)
			{
				player.stats.RecalculateStats(player, false, false);
			}
		}

		[HarmonyPatch]
		private static class BulletTrailFixes
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_BULLET_TRAILS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(TrailController), "Update")]
			[HarmonyILManipulator]
			private static void TrailControllerUpdateIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCallvirt(instr, (MethodBase)typeof(LinkedList<Bone>).GetMethod("get_Count"))
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(BulletTrailFixes), "KeepTrailAliveWhenEmpty");
				}
			}

			private static int KeepTrailAliveWhenEmpty(int oldCount, TrailController trail)
			{
				if (!trail.destroyOnEmpty)
				{
					return 999;
				}
				return oldCount;
			}
		}

		[HarmonyPatch]
		private static class BeamDamageCapPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_DAMAGE_CAPS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(BasicBeamController), "FrameUpdate")]
			[HarmonyILManipulator]
			private static void BasicBeamControllerFrameUpdateIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				for (int i = 0; i < 3; i++)
				{
					if (!val.TryGotoNext((MoveType)((i != 2) ? 2 : 0), new Func<Instruction, bool>[1]
					{
						(Instruction instr) => ILPatternMatchingExt.MatchCallvirt<HealthHaver>(instr, "ApplyDamage")
					}))
					{
						return;
					}
				}
				if (val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 0)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(BeamDamageCapPatch), "BeamShouldIgnoreDamageCaps");
				}
			}

			private static bool BeamShouldIgnoreDamageCaps(bool origVal, BasicBeamController beam)
			{
				if (!origVal)
				{
					if (Object.op_Implicit((Object)(object)((BraveBehaviour)beam).projectile))
					{
						return ((BraveBehaviour)beam).projectile.ignoreDamageCaps;
					}
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class EvolverDevolvePatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_EVOLVER)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(EvolverGunController), "OnDestroy")]
			[HarmonyPrefix]
			private static bool EvolverGunControllerOnDestroyPatch(EvolverGunController __instance)
			{
				__instance.Disengage();
				return false;
			}
		}

		[HarmonyPatch]
		private static class AmmoDriftPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_AMMO_DRIFT)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(GameUIAmmoController), "UpdateUIGun")]
			[HarmonyILManipulator]
			private static void BasicBeamControllerFrameUpdateIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdfld<GameUIAmmoController>(instr, "m_cachedGun"),
					(Instruction instr) => ILPatternMatchingExt.MatchCallvirt<Gun>(instr, "get_InfiniteAmmo")
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(AmmoDriftPatch), "WasReallyInfiniteAmmo");
				}
			}

			private static bool WasReallyInfiniteAmmo(bool origVal, GameUIAmmoController self)
			{
				if (origVal)
				{
					return self.m_cachedMaxAmmo == int.MaxValue;
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class RepausePatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_REPAUSE)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyILManipulator]
			private static void GameManagerDepixelateCRIL(ILContext il, MethodBase original)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				Type ot = original.DeclaringType;
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0),
					(Instruction instr) => ILPatternMatchingExt.MatchLdfld(instr, ot.GetEnumeratorField("$this")),
					(Instruction instr) => ILPatternMatchingExt.MatchCall<Component>(instr, "get_gameObject"),
					(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(BraveTime), "ClearMultiplier")
				}))
				{
					ILLabel val2 = val.MarkLabel();
					if (val.TryGotoPrev((MoveType)0, new Func<Instruction, bool>[4]
					{
						(Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0),
						(Instruction instr) => ILPatternMatchingExt.MatchLdfld(instr, ot.GetEnumeratorField("$this")),
						(Instruction instr) => ILPatternMatchingExt.MatchCall<Component>(instr, "get_gameObject"),
						(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(BraveTime), "ClearMultiplier")
					}))
					{
						val.Emit(OpCodes.Ldarg_0);
						val.Emit(OpCodes.Ldfld, ot.GetEnumeratorField("$this"));
						val.CallPrivate(typeof(RepausePatch), "IsActuallyStillPaused");
						val.Emit(OpCodes.Brtrue, (object)val2);
					}
				}
			}

			private static bool IsActuallyStillPaused(GameManager instance)
			{
				return instance.m_paused;
			}
		}

		[HarmonyPatch]
		private static class MimicTransformationPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_MIMIC_CHEST)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Chest), "DoMimicTransformation")]
			[HarmonyPrefix]
			private static bool DoMimicTransformation(Chest __instance)
			{
				return !string.IsNullOrEmpty(__instance.MimicGuid);
			}
		}

		[HarmonyPatch]
		private static class HighStressPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_HIGH_STRESS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(GameUIHeartController), "UpdateHealth")]
			[HarmonyILManipulator]
			private static void GameUIHeartControllerUpdateHealthPatchIL(ILContext il)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: 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)
				ILCursor val = new ILCursor(il);
				ILLabel afterNextShotKillsLabel = null;
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 1),
					(Instruction instr) => ILPatternMatchingExt.MatchLdfld<HealthHaver>(instr, "NextShotKills"),
					(Instruction instr) => ILPatternMatchingExt.MatchBrfalse(instr, ref afterNextShotKillsLabel)
				}))
				{
					val.Emit(OpCodes.Ldarg, 1);
					val.Emit(OpCodes.Ldloca, 0);
					val.Emit(OpCodes.Ldloca, 2);
					val.CallPrivate(typeof(HighStressPatch), "HighStressArmorFix");
					val.Emit(OpCodes.Br, (object)afterNextShotKillsLabel);
				}
			}

			private static void HighStressArmorFix(HealthHaver hh, ref float health, ref float armor)
			{
				GameActor gameActor = ((BraveBehaviour)hh).gameActor;
				PlayerController val = (PlayerController)(object)((gameActor is PlayerController) ? gameActor : null);
				if (val != null && val.ForceZeroHealthState)
				{
					health = 0f;
					armor = 1f;
				}
				else
				{
					health = 0.5f;
					armor = 0f;
				}
			}
		}

		[HarmonyPatch]
		private static class BrickOfCashPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_BRICK_OF_CASH)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(SecretRoomDoorBeer), "DoSnitchBrick")]
			[HarmonyILManipulator]
			private static void SecretRoomDoorBeerDoSnitchBrickPatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchCall<DungeonData>(instr, "GetIntVector2FromDirection")
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.CallPrivate(typeof(BrickOfCashPatch), "BrickOfCashFix");
				}
			}

			private static IntVector2 BrickOfCashFix(IntVector2 origVal, SecretRoomDoorBeer secret)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Invalid comparison between Unknown and I4
				//IL_0026: 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_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)
				if ((int)secret.exitDef.downstreamExit.referencedExit.exitDirection == 6)
				{
					return origVal + new IntVector2(-1, 0);
				}
				return origVal;
			}
		}

		[HarmonyPatch]
		private static class GunMagnificencePatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_GUN_MAGNIFICENCE)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(PickupObject), "HandleMagnficence")]
			[HarmonyPrefix]
			private static bool PickupObjectHandleMagnficencePatch(PickupObject __instance)
			{
				Gun val = (Gun)(object)((__instance is Gun) ? __instance : null);
				if (val != null && val.HasBeenPickedUp)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class InfiniteBeamAmmoPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_INFINITE_BEAMS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(MagazineRack), "Update")]
			[HarmonyILManipulator]
			private static void MagazineRackUpdatePatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_005c: 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)
				ILCursor val = new ILCursor(il);
				ILLabel val2 = default(ILLabel);
				if (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[2]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchLdloc(instr, 0),
					(Instruction instr) => ILPatternMatchingExt.MatchBrtrue(instr, ref val2)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.Emit(OpCodes.Ldloc_1);
					val.CallPrivate(typeof(InfiniteBeamAmmoPatch), "InfiniteBeamAmmoFix");
				}
			}

			private static void InfiniteBeamAmmoFix(MagazineRack rack, PlayerController player)
			{
				if (!player.InfiniteAmmo.HasOverride("MagazineRack"))
				{
					return;
				}
				int playerIDX = player.PlayerIDX;
				if (playerIDX == 0 || playerIDX == 1)
				{
					int num = ((playerIDX == 0) ? rack.m_p1MaxGunAmmoThisFrame : rack.m_p2MaxGunAmmoThisFrame);
					int num2 = ((playerIDX == 0) ? rack.m_p1GunIDThisFrame : rack.m_p2GunIDThisFrame);
					Gun currentGun = ((GameActor)player).CurrentGun;
					if (currentGun != null && !currentGun.RequiresFundsToShoot && currentGun.CurrentAmmo < num && ((PickupObject)currentGun).PickupObjectId == num2)
					{
						currentGun.ammo = Mathf.Min(currentGun.AdjustedMaxAmmo, num);
					}
				}
			}
		}

		[HarmonyPatch]
		private static class CapedBulletKinPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_CAPED_BULLET_KIN)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(UnlockPlayableBulletManBehavior), "Start")]
			[HarmonyPostfix]
			private static void UnlockPlayableBulletManBehaviorStartPatch(UnlockPlayableBulletManBehavior __instance)
			{
				((BehaviorBase)__instance).m_updateEveryFrame = true;
			}
		}

		[HarmonyPatch]
		private static class FlakBulletsPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_FLAK_BULLETS)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(ComplexProjectileModifier), "PostProcessProjectile")]
			[HarmonyILManipulator]
			private static void ComplexProjectileModifierPostProcessProjectilePatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchStfld<SpawnProjModifier>(instr, "PostprocessSpawnedProjectiles")
				}))
				{
					val.Emit(OpCodes.Ldarg_1);
					val.CallPrivate(typeof(FlakBulletsPatch), "FlakBulletsFix");
				}
			}

			private static bool FlakBulletsFix(bool origVal, Projectile proj)
			{
				if (origVal)
				{
					return !proj.SpawnedFromOtherPlayerProjectile;
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class ScattershotPatch
		{
			private static bool Prepare(MethodBase original)
			{
				if (!GGVConfig.FIX_SCATTERSHOT)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(GunVolleyModificationItem), "ModifyVolley")]
			[HarmonyILManipulator]
			private static void GunVolleyModificationItemModifyVolleyPatchIL(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction instr) => ILPatternMatchingExt.MatchStfld<ProjectileModule>(instr, "ammoCost")
				}))
				{
					val.Emit(OpCodes.Ldloc, 7);
					val.CallPrivate(typeof(ScattershotPatch), "ScattershotFix");
				}
			}

			private static void ScattershotFix(ProjectileModule mod)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Expected O, but got Unknown
				if (mod.ammoCost > 0)
				{
					return;
				}
				List<ChargeProjectile> chargeProjectiles = mod.chargeProjectiles;
				if (chargeProjectiles == null)
				{
					return;
				}
				mod.chargeProjectiles = new List<ChargeProjectile>(chargeProjectiles.Count);
				foreach (ChargeProjectile item2 in chargeProjectiles)
				{
					ChargeProjectile item = new ChargeProjectile
					{
						ChargeTime = item2.ChargeTime,
						Projectile = item2.Projectile,
						UsedProperties = item2.UsedProperties,
						VfxPool = item2.VfxPool,
						LightIntensity = item2.LightIntensity,
						ScreenShake = item2.ScreenShake,
						OverrideShootAnimation = item2.OverrideShootAnimation,
						OverrideMuzzleFlashVfxPool = item2.OverrideMuzzleFlashVfxPool,
						MegaReflection = item2.MegaReflection,
						AdditionalWwiseEvent = item2.AdditionalWwiseEvent,
						AmmoCost = 0
					};
					mod.chargeProjectiles.Add(item);
				}
			}
		}

		private static ulong[] _Bitfield = new ulong[10000];

		[HarmonyPatch(typeof(BraveMemory), "EnsureHeapSize")]
		[HarmonyPrefix]
		private static void BraveMemoryEnsureHeapSizePatch(ref int kilobytes)
		{
			if (GGVConfig.PREALLOCATE_HEAP > 0)
			{
				kilobytes = GGVConfig.PREALLOCATE_HEAP * 1048576;
			}
		}
	}
	[HarmonyPatch]
	internal static class Gooptimizations
	{
		private class ExtraGoopData
		{
			private static ExtraGoopData _NullEGD = new ExtraGoopData(null);

			private static ExtraGoopData _CachedEGD = _NullEGD;

			private static List<ExtraGoopData> _AllEGDs = new List<ExtraGoopData>();

			public DeadlyDeadlyGoopManager manager;

			public ulong[,,] goopedCellBitfield;

			public GoopPositionData[,] goopedCellGrid;

			public List<GoopPositionData> allGoopedCells;

			private int _xChunks;

			private int _yChunks;

			private int _cachedWidth;

			private int _cachedHeight;

			private DungeonData _cachedDungeon;

			private Dictionary<GoopPositionData, int> _allGoopedCellsIndices;

			private ExtraGoopData(DeadlyDeadlyGoopManager manager)
			{
				this.manager = manager;
				if (!((Object)(object)manager == (Object)null))
				{
					DungeonData val = (_cachedDungeon = GameManager.Instance.Dungeon.data);
					_cachedWidth = val.m_width;
					_cachedHeight = val.m_height;
					_xChunks = Mathf.CeilToInt((float)_cachedWidth / (float)manager.CHUNK_SIZE);
					_yChunks = Mathf.CeilToInt((float)_cachedHeight / (float)manager.CHUNK_SIZE);
					goopedCellBitfield = new ulong[_xChunks, _yChunks, 7];
					goopedCellGrid = new GoopPositionData[(int)((float)_cachedWidth / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE), (int)((float)_cachedHeight / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE)];
					allGoopedCells = new List<GoopPositionData>();
					_allGoopedCellsIndices = new Dictionary<GoopPositionData, int>();
					_AllEGDs.Add(this);
				}
			}

			private void Resize()
			{
				int width = _cachedDungeon.m_width;
				int height = _cachedDungeon.m_height;
				int num = Mathf.CeilToInt((float)width / (float)manager.CHUNK_SIZE);
				int num2 = Mathf.CeilToInt((float)height / (float)manager.CHUNK_SIZE);
				ulong[,,] array = new ulong[num, num2, 7];
				for (int i = 0; i < _xChunks; i++)
				{
					for (int j = 0; j < _yChunks; j++)
					{
						for (int k = 0; k < 7; k++)
						{
							array[i, j, k] = goopedCellBitfield[i, j, k];
						}
					}
				}
				_cachedWidth = width;
				_cachedHeight = height;
				_xChunks = num;
				_yChunks = num2;
				goopedCellBitfield = array;
				goopedCellGrid = new GoopPositionData[(int)((float)_cachedWidth / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE), (int)((float)_cachedHeight / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE)];
				foreach (GoopPositionData allGoopedCell in allGoopedCells)
				{
					goopedCellGrid[allGoopedCell.goopPosition.x, allGoopedCell.goopPosition.y] = allGoopedCell;
				}
			}

			internal static void ResizeAllBitfields()
			{
				for (int num = _AllEGDs.Count - 1; num >= 0; num--)
				{
					_AllEGDs[num].Resize();
				}
			}

			internal static ExtraGoopData Get(DeadlyDeadlyGoopManager manager)
			{
				if ((Object)(object)_CachedEGD.manager == (Object)(object)manager)
				{
					return _CachedEGD;
				}
				for (int num = _AllEGDs.Count - 1; num >= 0; num--)
				{
					if (!((Object)(object)_AllEGDs[num].manager != (Object)(object)manager))
					{
						return _CachedEGD = _AllEGDs[num];
					}
				}
				return _CachedEGD = new ExtraGoopData(manager);
			}

			internal static void ClearLevelData()
			{
				_AllEGDs.Clear();
				_CachedEGD = _NullEGD;
			}

			internal static bool TestGoopedBit(DeadlyDeadlyGoopManager manager, IntVector2 pos)
			{
				//IL_000f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				int num = (int)((float)manager.CHUNK_SIZE / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE);
				int num2 = (int)((float)pos.x / (float)num);
				int num3 = (int)((float)pos.y / (float)num);
				int num4 = pos.x % num * num + pos.y % num;
				ExtraGoopData extraGoopData = Get(manager);
				if (num2 < 0 || num3 < 0 || num2 >= extraGoopData._xChunks || num3 >= extraGoopData._yChunks)
				{
					return false;
				}
				return (extraGoopData.goopedCellBitfield[num2, num3, num4 / 64] & (ulong)(1L << num4 % 64)) != 0;
			}

			private void SetGoopedBit(IntVector2 pos)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				int num = (int)((float)manager.CHUNK_SIZE / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE);
				int num2 = (int)((float)pos.x / (float)num);
				int num3 = (int)((float)pos.y / (float)num);
				int num4 = pos.x % num * num + pos.y % num;
				if (num2 >= 0 && num3 >= 0 && num2 < _xChunks && num3 < _yChunks)
				{
					goopedCellBitfield[num2, num3, num4 / 64] |= (ulong)(1L << num4 % 64);
				}
			}

			private void ClearGoopedBit(IntVector2 pos)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				int num = (int)((float)manager.CHUNK_SIZE / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE);
				int num2 = (int)((float)pos.x / (float)num);
				int num3 = (int)((float)pos.y / (float)num);
				int num4 = pos.x % num * num + pos.y % num;
				if (num2 >= 0 && num3 >= 0 && num2 < _xChunks && num3 < _yChunks)
				{
					goopedCellBitfield[num2, num3, num4 / 64] &= (ulong)(~(1L << num4 % 64));
				}
			}

			internal void AddGoop(GoopPositionData goop)
			{
				//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_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)
				IntVector2 goopPosition = goop.goopPosition;
				SetGoopedBit(goopPosition);
				goopedCellGrid[goopPosition.x, goopPosition.y] = goop;
				int count = allGoopedCells.Count;
				allGoopedCells.Add(goop);
				_allGoopedCellsIndices[goop] = count;
			}

			internal void RemoveGoop(GoopPositionData goop)
			{
				//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_0019: 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_002b: Unknown result type (might be due to invalid IL or missing references)
				if (_allGoopedCellsIndices.TryGetValue(goop, out var value))
				{
					IntVector2 goopPosition = goop.goopPosition;
					ClearGoopedBit(goopPosition);
					goopedCellGrid[goopPosition.x, goopPosition.y] = null;
					_allGoopedCellsIndices.Remove(goop);
					int index = allGoopedCells.Count - 1;
					allGoopedCells[value] = allGoopedCells[index];
					_allGoopedCellsIndices[allGoopedCells[value]] = value;
					allGoopedCells.RemoveAt(index);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <HandleRecursiveElectrificationFast>d__14 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public DeadlyDeadlyGoopManager __instance;

			public IntVector2 cellIndex;

			private uint <currentSemaphore>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HandleRecursiveElectrificationFast>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				int num;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					GoopPositionData val = __instance.m_goopedCells[cellIndex];
					if (!__instance.goopDefinition.CanBeElectrified || val.IsFrozen || val.remainingLifespan < __instance.goopDefinition.fadePeriod)
					{
						return false;
					}
					DeadlyDeadlyGoopManager _instance = __instance;
					<currentSemaphore>5__2 = (val.elecTriggerSemaphore = ++_instance.m_lastElecSemaphore);
					num = 0;
					_GoopsToElectrify.Enqueue(val);
					break;
				}
				case 1:
					<>1__state = -1;
					num = 0;
					break;
				}
				while (_GoopsToElectrify.Count > 0)
				{
					GoopPositionData val2 = _GoopsToElectrify.Dequeue();
					if (val2 == null)
					{
						continue;
					}
					if (!val2.IsFrozen && val2.remainingLifespan >= __instance.goopDefinition.fadePeriod)
					{
						if (!val2.IsElectrified)
						{
							val2.IsElectrified = true;
							val2.remainingElecTimer = 0f;
						}
						val2.remainingElectrifiedTime = __instance.goopDefinition.electrifiedTime;
					}
					for (int i = 0; i < 8; i++)
					{
						GoopPositionData val3 = val2.neighborGoopData[i];
						if (val3 != null && val3.elecTriggerSemaphore < <currentSemaphore>5__2 && (!val3.IsElectrified || val3.remainingElectrifiedTime < __instance.goopDefinition.electrifiedTime - 0.01f))
						{
							val3.elecTriggerSemaphore = <currentSemaphore>5__2;
							_GoopsToElectrify.Enqueue(val3);
						}
					}
					if ((float)(++num) > 200f)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implement

OptimizeIMGUI/OptimizeIMGUI.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BepInEx.OptimizeIMGUI")]
[assembly: AssemblyProduct("BepInEx.OptimizeIMGUI")]
[assembly: AssemblyDescription("Optimize IMGUI GC allocations")]
[assembly: AssemblyFileVersion("1.0")]
[assembly: AssemblyCompany("https://github.com/BepInEx/BepInEx.Utility")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2021 BepInEx")]
[assembly: AssemblyInformationalVersion("1.0.0+2b6c4f2e02fb90ea6833f786d2caae3f02e99f02")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BepInEx;

[BepInPlugin("BepInEx.OptimizeIMGUI", "Optimize IMGUI GC allocations", "1.0")]
public class OptimizeIMGUI : BaseUnityPlugin
{
	private static class Hooks
	{
		private static readonly Dictionary<int, Dictionary<float, GUILayoutOption>> _layoutOptionCache;

		private static readonly ConstructorInfo _layoutOptionConstructor;

		private static readonly GUILayoutOption _widthTrue;

		private static readonly GUILayoutOption _widthFalse;

		private static readonly GUILayoutOption _heightTrue;

		private static readonly GUILayoutOption _heightFalse;

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GUILayoutUtility), "Begin")]
		private static IEnumerable<CodeInstruction> FixOnguiGarbageDump(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Expected O, but got Unknown
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Expected O, but got Unknown
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Expected O, but got Unknown
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Expected O, but got Unknown
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Expected O, but got Unknown
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Expected O, but got Unknown
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Expected O, but got Unknown
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Expected O, but got Unknown
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Expected O, but got Unknown
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Expected O, but got Unknown
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Expected O, but got Unknown
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Expected O, but got Unknown
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Expected O, but got Unknown
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Expected O, but got Unknown
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Expected O, but got Unknown
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Expected O, but got Unknown
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Expected O, but got Unknown
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Expected O, but got Unknown
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Expected O, but got Unknown
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Expected O, but got Unknown
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("UnityEngine.GUILayoutUtility") ?? throw new MissingMemberException("AccessTools.TypeByName(\"UnityEngine.GUILayoutUtility\")");
			Type? obj = type.GetNestedType("LayoutCache", AccessTools.all) ?? throw new MissingMemberException("luT.GetNestedType(\"LayoutCache\", AccessTools.all)");
			FieldInfo fieldInfo = AccessTools.Field(obj, "topLevel") ?? throw new MissingMemberException("AccessTools.Field(lcT, \"topLevel\")");
			FieldInfo fieldInfo2 = AccessTools.Field(obj, "windows") ?? throw new MissingMemberException("AccessTools.Field(lcT, \"windows\")");
			FieldInfo fieldInfo3 = AccessTools.Field(type, "current") ?? throw new MissingMemberException("AccessTools.Field(luT, \"current\")");
			FieldInfo fieldInfo4 = AccessTools.Field(obj, "layoutGroups") ?? throw new MissingMemberException("AccessTools.Field(lcT, \"layoutGroups\")");
			Type type2 = AccessTools.TypeByName("UnityEngine.GUILayoutGroup") ?? throw new MissingMemberException("AccessTools.TypeByName(\"UnityEngine.GUILayoutGroup\")");
			FieldInfo fieldInfo5 = AccessTools.Field(type2, "entries") ?? throw new MissingMemberException("AccessTools.Field(lgT, \"entries\")");
			Type type3 = AccessTools.TypeByName("UnityEngine.GUILayoutEntry") ?? throw new MissingMemberException("AccessTools.TypeByName(\"UnityEngine.GUILayoutEntry\")");
			MethodInfo methodInfo = AccessTools.Method(typeof(List<>).MakeGenericType(type3), "Clear", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(type, "SelectIDList", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.PropertyGetter(typeof(Event), "current");
			MethodInfo methodInfo4 = AccessTools.PropertyGetter(typeof(Event), "type");
			Label label = generator.DefineLabel();
			Label label2 = generator.DefineLabel();
			Label label3 = generator.DefineLabel();
			List<CodeInstruction> list = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)methodInfo2),
				new CodeInstruction(OpCodes.Stloc_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)methodInfo3),
				new CodeInstruction(OpCodes.Callvirt, (object)methodInfo4),
				new CodeInstruction(OpCodes.Ldc_I4_8, (object)null),
				new CodeInstruction(OpCodes.Bne_Un_S, (object)label),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label2),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Newobj, (object)AccessTools.Constructor(type2, new Type[0], false)),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null)
				{
					labels = new List<Label> { label2 }
				},
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo5),
				new CodeInstruction(OpCodes.Callvirt, (object)methodInfo),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label3),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Newobj, (object)AccessTools.Constructor(type2, new Type[0], false)),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null)
				{
					labels = new List<Label> { label3 }
				},
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo5),
				new CodeInstruction(OpCodes.Callvirt, (object)methodInfo),
				new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo3),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo3),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo4),
				new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.Method(typeof(Stack), "Clear", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo3),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo4),
				new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo3),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.Method(typeof(Stack), "Push", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Ret, (object)null),
				new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo3)
				{
					labels = new List<Label> { label }
				}
			};
			List<CodeInstruction> list2 = instructions.ToList();
			int num = 0;
			for (int num2 = list2.Count - 1; num2 >= 0; num2--)
			{
				num += Convert.ToInt32(list2[num2].opcode == OpCodes.Ldsfld);
				if (num == 3)
				{
					for (int i = num2 + 1; i < list2.Count; i++)
					{
						list.Add(list2[i]);
					}
					break;
				}
			}
			if (num != 3)
			{
				throw new InvalidOperationException("IL footprint does not match what was expected");
			}
			return list;
		}

		private static GUILayoutOption CreateNewGuiLayoutOption(int type, object value)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			return (GUILayoutOption)_layoutOptionConstructor.Invoke(new object[2] { type, value });
		}

		static Hooks()
		{
			_layoutOptionCache = new Dictionary<int, Dictionary<float, GUILayoutOption>>();
			_layoutOptionConstructor = AccessTools.FirstConstructor(typeof(GUILayoutOption), (Func<ConstructorInfo, bool>)((ConstructorInfo info) => info.GetParameters().Length == 2));
			_widthTrue = CreateNewGuiLayoutOption(6, 1);
			_widthFalse = CreateNewGuiLayoutOption(6, 0);
			_heightTrue = CreateNewGuiLayoutOption(7, 1);
			_heightFalse = CreateNewGuiLayoutOption(7, 0);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GUILayout), "Width")]
		[HarmonyPatch(typeof(GUILayout), "MinWidth")]
		[HarmonyPatch(typeof(GUILayout), "MaxWidth")]
		[HarmonyPatch(typeof(GUILayout), "Height")]
		[HarmonyPatch(typeof(GUILayout), "MinHeight")]
		[HarmonyPatch(typeof(GUILayout), "MaxHeight")]
		private static IEnumerable<CodeInstruction> CachedGetOptionFPatch(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Box, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Newobj, (object)null, (string)null)
			}).SetAndAdvance(OpCodes.Nop, (object)null).Set(OpCodes.Call, (object)AccessTools.Method(typeof(Hooks), "CachedGetOptionF", (Type[])null, (Type[])null))
				.Instructions();
		}

		private static GUILayoutOption CachedGetOptionF(int type, float value)
		{
			if (!_layoutOptionCache.TryGetValue(type, out var value2))
			{
				value2 = new Dictionary<float, GUILayoutOption>();
				_layoutOptionCache[type] = value2;
			}
			if (!value2.TryGetValue(value, out var value3))
			{
				value3 = (value2[value] = CreateNewGuiLayoutOption(type, value));
			}
			return value3;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GUILayout), "ExpandWidth")]
		[HarmonyPatch(typeof(GUILayout), "ExpandHeight")]
		private static IEnumerable<CodeInstruction> CachedGetOptionBPatch(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Box, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Newobj, (object)null, (string)null)
			}).SetAndAdvance(OpCodes.Nop, (object)null).Set(OpCodes.Call, (object)AccessTools.Method(typeof(Hooks), "CachedGetOptionB", (Type[])null, (Type[])null))
				.Instructions();
		}

		private static GUILayoutOption CachedGetOptionB(int type, int value)
		{
			switch (type)
			{
			case 6:
				if (value != 0)
				{
					return _widthTrue;
				}
				return _widthFalse;
			case 7:
				if (value != 0)
				{
					return _heightTrue;
				}
				return _heightFalse;
			default:
				throw new ArgumentException("Unknown type " + type, "type");
			}
		}
	}

	public const string GUID = "BepInEx.OptimizeIMGUI";

	public const string PluginName = "Optimize IMGUI GC allocations";

	public const string Version = "1.0";

	internal static ManualLogSource Logger;

	private void Awake()
	{
		Logger = ((BaseUnityPlugin)this).Logger;
		Harmony.CreateAndPatchAll(typeof(Hooks), (string)null);
	}
}