Decompiled source of Gungeon Go Vroom v1.6.0
GungeonGoVroom.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
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 agousing 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); } }