Decompiled source of Gungeon Go Vroom v1.5.3
GungeonGoVroom.dll
Decompiled a day 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 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 { 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) { self.m_ambientVFXProcessingActive = true; while (self.m_ambientVFXProcessingActive) { if (GameManager.Instance.IsLoadingLevel || (int)GameManager.Options.ShaderQuality == 0 || (int)GameManager.Options.ShaderQuality == 3) { yield return null; continue; } DungeonData data = self.data; if (data == null) { yield return null; continue; } CameraController mainCameraController = GameManager.Instance.MainCameraController; if (!Object.op_Implicit((Object)(object)mainCameraController)) { yield return null; continue; } 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); } } } yield return null; } self.m_ambientVFXProcessingActive = false; } } [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) { if (!GGVConfig.OPT_MOUSE_EVENTS) { return false; } return true; } [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 { private static bool Prepare(MethodBase original) { if (!GGVConfig.FIX_SHUFFLE) { return false; } return true; } private static IEnumerable<MethodBase> TargetMethods() { MethodInfo genShuffle = typeof(BraveUtility).GetMethod("GenerationShuffle", BindingFlags.Static | BindingFlags.Public); yield return genShuffle.MakeGenericMethod(typeof(int)); yield return genShuffle.MakeGenericMethod(typeof(IntVector2)); yield return genShuffle.MakeGenericMethod(typeof(Tuple<RuntimeRoomExitData, RuntimeRoomExitData>)); yield return genShuffle.MakeGenericMethod(typeof(PrototypeRoomExit)); MethodInfo standardShuffle = typeof(BraveUtility).GetMethod("Shuffle", BindingFlags.Static | BindingFlags.Public); yield return standardShuffle.MakeGenericMethod(typeof(int)); yield return standardShuffle.MakeGenericMethod(typeof(IntVector2)); yield return standardShuffle.MakeGenericMethod(typeof(AIActor)); yield return standardShuffle.MakeGenericMethod(typeof(IPaydayItem)); } [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; } } } 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); } } } private static readonly Color32 _Transparent = new Color32((byte)0, (byte)0, (byte)0, (byte)0); private static Queue<GoopPositionData> _GoopsToElectrify = new Queue<GoopPositionData>(); private static float _InvSqrRadius = 1f; private static bool Prepare(MethodBase original) { if (!GGVConfig.OPT_GOOP) { return false; } return true; } [HarmonyPatch(typeof(DeadlyDeadlyGoopManager), "ClearPerLevelData")] [HarmonyPostfix] private static void DeadlyDeadlyGoopManagerClearPerLevelDataPatch() { ExtraGoopData.ClearLevelData(); } [HarmonyPatch(typeof(DungeonData), "ClearCachedCellData")] [HarmonyPostfix] private static void ClearCachedCellData(DungeonData __instance) { __instance.m_width = __instance.cellData.Length; __instance.m_height = __instance.cellData[0].Length; ExtraGoopData.ResizeAllBitfields(); } [HarmonyPatch(typeof(DeadlyDeadlyGoopManager), "RebuildMeshUvsAndColors")] [HarmonyPrefix] private static bool DeadlyDeadlyGoopManagerRebuildMeshUvsAndColorsPatch(DeadlyDeadlyGoopManager __instance, int chunkX, int chunkY) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) Mesh chunkMesh = __instance.GetChunkMesh(chunkX, chunkY); for (int i = 0; i < __instance.m_colorArray.Length; i++) { __instance.m_colorArray[i].a = 0; } int num = Mathf.RoundToInt((float)__instance.CHUNK_SIZE / DeadlyDeadlyGoopManager.GOOP_GRID_SIZE); int num2 = chunkX * num; int num3 = num2 + num; int num4 = chunkY * num; int num5 = num4 + num; _ = __instance.m_goopedCells; GoopPositionData val = null; IntVector2 val2 = default(IntVector2); Vector2 val3 = __instance.m_uvMap[-1]; int count = __instance.m_centerUVOptions.Count; Vector2 value = default(Vector2); ExtraGoopData extraGoopData = ExtraGoopData.Get(__instance); ulong[,,] goopedCellBitfield = extraGoopData.goopedCellBitfield; int num6 = -1; Vector2 val4 = default(Vector2); for (int j = num2; j < num3; j++) { val2.x = j; for (int k = num4; k < num5; k++) { num6++; if ((goopedCellBitfield[chunkX, chunkY, num6 / 64] & (ulong)(1L << num6 % 64)) == 0L) { continue; } val2.y = k; val = extraGoopData.goopedCellGrid[j, k]; if (val != null && !(val.remainingLifespan <= 0f)) { int num7 = val.baseIndex; if (num7 < 0) { num7 = (val.baseIndex = __instance.GetGoopBaseIndex(val2, chunkX, chunkY)); } if (val.NeighborsAsInt == 255) { value = __instance.m_centerUVOptions[(int)((float)count * ((IntVector2)(ref val2)).GetHashedRandomValue())]; } else if (!__instance.m_uvMap.TryGetValue(val.NeighborsAsInt, out value) && !__instance.m_uvMap.TryGetValue(val.NeighborsAsIntFuckDiagonals, out value)) { value = val3; } __instance.m_uvArray[num7] = value; __instance.m_uvArray[num7 + 1] = new Vector2(value.x + 0.125f, value.y + 0f); __instance.m_uvArray[num7 + 2] = new Vector2(value.x + 0f, value.y + 0.125f); __instance.m_uvArray[num7 + 3] = new Vector2(value.x + 0.125f, value.y + 0.125f); if (__instance.goopDefinition.CanBeFrozen) { ((Vector2)(ref val4))..ctor((float)(val.IsFrozen ? 1 : 0), 0f); __instance.m_uv2Array[num7] = val4; __instance.m_uv2Array[num7 + 1] = val4; __instance.m_uv2Array[num7 + 2] = val4; __instance.m_uv2Array[num7 + 3] = val4; } __instance.AssignVertexColors(val, val2, chunkX, chunkY); } } } chunkMesh.uv = __instance.m_uvArray; chunkMesh.uv2 = __instance.m_uv2Array; chunkMesh.colors32 = __instance.m_colorArray; return false; } [HarmonyPatch(typeof(DeadlyDeadlyGoopManager), "LateUpdate")] [HarmonyPrefix] private static bool DeadlyDeadlyGoopManagerLateUpdatePatch(DeadlyDeadlyGoopManager __instance) { //IL_00b9: 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_09b2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_06cc: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_0706: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_071a: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Invalid comparison between Unknown and I4 //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Invalid comparison between Unknown and I4 //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_093c: Unknown result type (might be due to invalid IL or missing references) //IL_093e: Unknown result type (might be due to invalid IL or missing references) //IL_0940: Unknown result type (might be due to invalid IL or missing references) //IL_094a: Unknown result type (might be due to invalid IL or missing references) //IL_08c3: Unknown result type (might be due to invalid IL or missing references) //IL_08cb: Unknown result type (might be due to invalid IL or missing references) //IL_08d4: Unknown result type (might be due to invalid IL or missing references) //IL_0901: Unknown result type (might be due to invalid IL or missing references) //IL_0906: Unknown result type (might be due to invalid IL or missing references) //IL_0923: Unknown result type (might be due to invalid IL or missing references) //IL_0925: Unknown result type (might be due to invalid IL or missing references) //IL_092d: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_083e: Unknown result type (might be due to invalid IL or missing references) //IL_0847: Unknown result type (might be due to invalid IL or missing references) //IL_0874: Unknown result type (might be due to invalid IL or missing references) //IL_0879: Unknown result type (might be due to invalid IL or missing references) //IL_0896: Unknown result type (might be due to invalid IL or missing references) //IL_0898: Unknown result type (might be due to invalid IL or missing references) //IL_08a0: Unknown result type (might be due to invalid IL or missing references) //IL_0787: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_0798: Unknown result type (might be due to invalid IL or missing references) //IL_07c5: Unknown result type (might be due to invalid IL or missing references) //IL_07ca: Unknown result type (might be due to invalid IL or missing references) //IL_07e7: Unknown result type (might be due to invalid IL or missing references) //IL_07e9: Unknown result type (might be due to invalid IL or missing references) //IL_07f1: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_098b: Unknown result type (might be due to invalid IL or missing references) //IL_0984: Unknown result type (might be due to invalid IL or missing references) if (Time.timeScale <= 0f || GameManager.Instance.IsPaused) { return false; } __instance.m_removalPositions.Clear(); bool flag = false; bool flag2 = false; __instance.m_currentUpdateBin = (__instance.m_currentUpdateBin + 1) % 4; __instance.m_deltaTimes.Enqueue(BraveTime.DeltaTime); float num = 0f; for (int i = 0; i < __instance.m_deltaTimes.Count; i++) { num += __instance.m_deltaTimes[i]; } ExtraGoopData extraGoopData = ExtraGoopData.Get(__instance); int count = extraGoopData.allGoopedCells.Count; for (int j = 0; j < count; j++) { GoopPositionData val = extraGoopData.allGoopedCells[j]; if (val.GoopUpdateBin != __instance.m_currentUpdateBin) { continue; } IntVector2 goopPosition = val.goopPosition; val.unfrozeLastFrame = false; if (__instance.goopDefinition.usesAmbientGoopFX && val.remainingLifespan > 0f && Random.value < __instance.goopDefinition.ambientGoopFXChance && val.SupportsAmbientVFX) { Vector3 val2 = ((IntVector2)(ref goopPosition)).ToVector3((float)goopPosition.y) * DeadlyDeadlyGoopManager.GOOP_GRID_SIZE; __instance.goopDefinition.ambientGoopFX.SpawnAtPosition(val2, 0f, (Transform)null, (Vector2?)null, (Vector2?)null, (float?)null, false, (SpawnMethod)null, (tk2dBaseSprite)null, false); } if (!val.IsOnFire && !val.IsElectrified && !__instance.goopDefinition.usesLifespan && !val.lifespanOverridden && !val.selfIgnites) { continue; } if (val.selfIgnites) { if (val.remainingTimeTilSelfIgnition <= 0f) { val.selfIgnites = false; __instance.IgniteCell(goopPosition); } else { val.remainingTimeTilSelfIgnition -= num; } } if (val.remainingLifespan > 0f) { if (!val.IsFrozen) { val.remainingLifespan -= num; } else { val.remainingFreezeTimer -= num; if (val.remainingFreezeTimer <= 0f) { val.hasBeenFrozen = 1; val.remainingLifespan = Mathf.Min(val.remainingLifespan, __instance.goopDefinition.fadePeriod); val.remainingLifespan -= num; } } if (__instance.goopDefinition.usesAcidAudio) { flag2 = true; } if (val.remainingLifespan < __instance.goopDefinition.fadePeriod && val.IsElectrified) { val.remainingLifespan = __instance.goopDefinition.fadePeriod; } if (val.remainingLifespan < __instance.goopDefinition.fadePeriod || val.remainingLifespan <= 0f) { __instance.SetDirty(goopPosition); val.IsOnFire = false; val.IsElectrified = false; val.HasPlayedFireIntro = false; val.HasPlayedFireOutro = false; if (val.remainingLifespan <= 0f) { __instance.m_removalPositions.Add(goopPosition); continue; } } if (val.IsElectrified) { val.remainingElectrifiedTime -= num; val.remainingElecTimer -= num; if (val.remainingElectrifiedTime <= 0f) { val.IsElectrified = false; val.remainingElectrifiedTime = 0f; } if (val.IsElectrified && (Object)(object)__instance.m_elecSystem != (Object)null && val.remainingElecTimer <= 0f && goopPosition.x % 2 == 0 && goopPosition.y % 2 == 0) { Vector3 val3 = ((IntVector2)(ref goopPosition)).ToVector3((float)goopPosition.y) * DeadlyDeadlyGoopManager.GOOP_GRID_SIZE + dfVectorExtensions.Quantize(new Vector3(Random.Range(0.125f, 0.375f), Random.Range(0.125f, 0.375f), 0.125f), 0.0625f); float num2 = Random.Range(0.75f, 1.5f); if (Random.value < 0.1f) { EmitParams val4 = default(EmitParams); ((EmitParams)(ref val4)).position = val3; ((EmitParams)(ref val4)).velocity = Vector3.zero; ((EmitParams)(ref val4)).startSize = __instance.m_fireSystem.startSize; ((EmitParams)(ref val4)).startLifetime = num2; ((EmitParams)(ref val4)).startColor = Color32.op_Implicit(__instance.m_fireSystem.startColor); ((EmitParams)(ref val4)).randomSeed = (uint)(Random.value * 4.2949673E+09f); EmitParams val5 = val4; __instance.m_elecSystem.Emit(val5, 1); if ((int)GameManager.Options.ShaderQuality != 0 && (int)GameManager.Options.ShaderQuality != 3) { GlobalSparksDoer.DoRandomParticleBurst(((int)GameManager.Options.ShaderQuality != 1) ? 10 : 4, val3 + new Vector3(-0.625f, -0.625f, 0f), val3 + new Vector3(0.625f, 0.625f, 0f), Vector3.up, 120f, 0.5f, (float?)null, (float?)null, (Color?)null, (SparksType)0); } } val.remainingElecTimer = num2 - 0.1f; } } if (val.IsFrozen) { if (val.totalOnFireTime < 0.5f || val.remainingLifespan < __instance.goopDefinition.fadePeriod) { __instance.SetColorDirty(goopPosition); } val.totalOnFireTime += num; if (val.totalOnFireTime >= __instance.goopDefinition.freezeSpreadTime) { for (int k = 0; k < val.neighborGoopData.Length; k++) { if (val.neighborGoopData[k] != null && !val.neighborGoopData[k].IsFrozen && val.neighborGoopData[k].hasBeenFrozen == 0) { if (Random.value < 0.2f) { __instance.FreezeCell(val.neighborGoopData[k].goopPosition); } else { val.totalFrozenTime = 0f; } } } } } if (val.IsOnFire) { flag = true; __instance.SetColorDirty(goopPosition); val.remainingFireTimer -= num; val.totalOnFireTime += num; if (val.totalOnFireTime >= __instance.goopDefinition.igniteSpreadTime) { for (int l = 0; l < val.neighborGoopData.Length; l++) { if (val.neighborGoopData[l] != null && !val.neighborGoopData[l].IsOnFire) { if (Random.value < 0.2f) { __instance.IgniteCell(val.neighborGoopData[l].goopPosition); } else { val.totalOnFireTime = 0f; } } } } } if (!((Object)(object)__instance.m_fireSystem != (Object)null) || !val.IsOnFire || !(val.remainingFireTimer <= 0f) || goopPosition.x % 2 != 0 || goopPosition.y % 2 != 0) { continue; } Vector3 val6 = ((IntVector2)(ref goopPosition)).ToVector3((float)goopPosition.y) * DeadlyDeadlyGoopManager.GOOP_GRID_SIZE + dfVectorExtensions.Quantize(new Vector3(Random.Range(0.125f, 0.375f), Random.Range(0.125f, 0.375f), 0.125f), 0.0625f); float num3 = Random.Range(1f, 1.5f); float num4 = Random.Range(0.
OptimizeIMGUI/OptimizeIMGUI.dll
Decompiled a day 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); } }