using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using Configgy;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BigCG")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+38bc30309c03e62ffb632e8cfea8fd8a886767cf")]
[assembly: AssemblyProduct("BigCG")]
[assembly: AssemblyTitle("BigCG")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 BigCG
{
public static class MeshBaking
{
public const int MaxCubesPerMesh = 150;
public const int MaxStairsPerMesh = 150;
private static void CreateCombinedObject(out GameObject gameObject, out MeshRenderer renderer, out MeshFilter filter)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
GameObject val = new GameObject("Combined Static Mesh (BigCG)");
val.transform.parent = ((Component)MonoSingleton<EndlessGrid>.Instance).transform;
val.layer = LayerMask.NameToLayer("Outdoors");
gameObject = val;
renderer = gameObject.AddComponent<MeshRenderer>();
filter = gameObject.AddComponent<MeshFilter>();
}
private static void CompleteMesh(Mesh mesh, CombineInstance[] combineInstances)
{
mesh.CombineMeshes(combineInstances, true, true);
mesh.Optimize();
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.UploadMeshData(false);
}
public static GameObject CreateCubeMesh(int start, int amount)
{
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
//IL_0079: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
CreateCombinedObject(out var gameObject, out var renderer, out var filter);
List<CombineInstance> list = new List<CombineInstance>();
Material[] sharedMaterials = ((Renderer)MonoSingleton<EndlessGrid>.Instance.cubes[0][0].MeshRenderer).sharedMaterials;
for (int i = 0; i < sharedMaterials.Length; i++)
{
for (int j = 0; j < amount; j++)
{
int num = (j + start) / Plugin.GridSize;
EndlessCube val = MonoSingleton<EndlessGrid>.Instance.cubes[num][j + start - num * Plugin.GridSize];
if (Object.op_Implicit((Object)(object)val))
{
CombineInstance item = default(CombineInstance);
((CombineInstance)(ref item)).transform = ((Renderer)val.MeshRenderer).localToWorldMatrix;
((CombineInstance)(ref item)).mesh = val.MeshFilter.sharedMesh;
((CombineInstance)(ref item)).subMeshIndex = i;
list.Add(item);
((Renderer)val.MeshRenderer).enabled = false;
}
}
}
Mesh val2 = new Mesh();
CompleteMesh(val2, list.ToArray());
filter.sharedMesh = val2;
((Renderer)renderer).sharedMaterials = sharedMaterials;
((Renderer)renderer).enabled = true;
return gameObject;
}
public static GameObject CreateStairsMesh(int start, int amount)
{
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
CreateCombinedObject(out var gameObject, out var renderer, out var filter);
List<CombineInstance> list = new List<CombineInstance>();
Material[] sharedMaterials = ((Renderer)MonoSingleton<EndlessGrid>.Instance.cubes[0][0].MeshRenderer).sharedMaterials;
int num = 0;
foreach (GameObject item2 in MonoSingleton<EndlessGrid>.Instance.spawnedPrefabs.Where((GameObject x) => (Object)(object)x.GetComponent<EndlessStairs>() != (Object)null))
{
if (num <= start + amount && num >= start)
{
num++;
EndlessStairs component = item2.GetComponent<EndlessStairs>();
CombineInstance item;
if (component.ActivateFirst)
{
item = default(CombineInstance);
((CombineInstance)(ref item)).transform = ((Renderer)component.PrimaryMeshRenderer).localToWorldMatrix;
((CombineInstance)(ref item)).mesh = component.PrimaryMeshFilter.sharedMesh;
list.Add(item);
((Renderer)component.PrimaryMeshRenderer).enabled = false;
}
if (component.ActivateSecond)
{
item = default(CombineInstance);
((CombineInstance)(ref item)).transform = ((Renderer)component.SecondaryMeshRenderer).localToWorldMatrix;
((CombineInstance)(ref item)).mesh = component.SecondaryMeshFilter.sharedMesh;
list.Add(item);
((Renderer)component.SecondaryMeshRenderer).enabled = false;
}
}
}
Mesh val = new Mesh();
CompleteMesh(val, list.ToArray());
filter.sharedMesh = val;
((Renderer)renderer).sharedMaterials = sharedMaterials;
((Renderer)renderer).enabled = true;
return gameObject;
}
}
public static class PatternFixer
{
public static void FixPattern(ArenaPattern pattern)
{
if ((Object)(object)pattern == (Object)null)
{
Debug.LogWarning((object)"Pattern is null,,, guh?");
return;
}
pattern.heights = string.Join("\n", FixPatternHeights(pattern.heights.Split(new char[1] { '\n' }).ToList()));
pattern.prefabs = string.Join("\n", FixPatternEnemies(pattern.prefabs.Split(new char[1] { '\n' }).ToList()));
}
public static string[] FixStringPattern(string[] pattern)
{
List<string> list = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();
List<string> list4 = list2;
foreach (string text in pattern)
{
if (text == string.Empty)
{
list4 = list3;
}
else
{
list4.Add(text);
}
}
list.AddRange(FixPatternHeights(list2));
list.Add(string.Empty);
list.AddRange(FixPatternEnemies(list3));
return list.ToArray();
}
private static List<string> FixPatternHeights(List<string> pattern)
{
List<List<int>> list = ParseStringArray(pattern);
foreach (List<int> item in list)
{
if (item.Count < Plugin.GridSize)
{
int num = 0;
while (item.Count != Plugin.GridSize)
{
item.Add(item[num]);
num++;
}
}
else if (item.Count > Plugin.GridSize)
{
int num2 = item.Count - Plugin.GridSize;
item.RemoveRange(item.Count - num2 - 1, num2);
}
}
if (list.Count < Plugin.GridSize)
{
int num3 = 0;
while (list.Count != Plugin.GridSize)
{
list.Add(list[num3]);
num3++;
}
}
else if (list.Count > Plugin.GridSize)
{
int num4 = list.Count - Plugin.GridSize;
list.RemoveRange(list.Count - num4, num4);
}
return ListIntPatternToStringListPattern(list);
}
private static List<string> FixPatternEnemies(List<string> pattern)
{
List<string> list = new List<string>();
foreach (string item in pattern)
{
string text = item;
if (text.Length < Plugin.GridSize)
{
int num = 0;
while (text.Length != Plugin.GridSize)
{
text += text[num];
num++;
}
}
else if (item.Length > Plugin.GridSize)
{
text = text.Substring(0, Plugin.GridSize);
}
list.Add(text);
}
if (list.Count < Plugin.GridSize)
{
int num2 = 0;
while (list.Count != Plugin.GridSize)
{
list.Add(list[num2]);
num2++;
}
}
else if (list.Count > Plugin.GridSize)
{
int num3 = list.Count - Plugin.GridSize;
list.RemoveRange(list.Count - num3 - 1, num3);
}
return list;
}
private static List<List<int>> ParseStringArray(List<string> pattern)
{
List<List<int>> list = new List<List<int>>();
foreach (string item in pattern)
{
if (!CorrectlyClosedBrackets(item))
{
Debug.LogError((object)"Brackets don't close in pattern.");
return null;
}
if (!MinusesInValidPositions(item))
{
Debug.LogError((object)"Minuses are invalid in pattern.");
return null;
}
List<int> list2 = new List<int>();
list.Add(list2);
bool flag = false;
bool flag2 = false;
bool flag3 = false;
string text = item;
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if ((c == '(' || c == ')') ? true : false)
{
flag2 = false;
flag = !flag;
continue;
}
if (!flag)
{
list2.Add(int.Parse(c.ToString()));
continue;
}
if (!flag2)
{
if (c == '-')
{
flag3 = true;
continue;
}
list2.Add(int.Parse(c.ToString()) * ((!flag3) ? 1 : (-1)));
flag2 = true;
continue;
}
list2[list2.Count - 1] = int.Parse(string.Concat(list2[list2.Count - 1], c));
if (flag3)
{
list2[list2.Count - 1] *= -1;
flag3 = false;
}
}
}
Debug.Log((object)"SEPERATOR ---");
foreach (List<int> item2 in list)
{
Debug.Log((object)string.Join(" ", item2));
}
return list;
}
private static List<string> ListIntPatternToStringListPattern(List<List<int>> pattern)
{
List<string> list = new List<string>();
foreach (List<int> item in pattern)
{
string text = string.Empty;
foreach (int item2 in item)
{
text = ((item2.ToString().Length != 1) ? (text + $"({item2})") : (text + item2));
}
list.Add(text);
}
return list;
}
private static bool CorrectlyClosedBrackets(string line)
{
return Regex.Matches(line, "\\(").Count == Regex.Matches(line, "\\)").Count;
}
private static bool MinusesInValidPositions(string line)
{
for (int i = 0; i < line.Length; i++)
{
if (line[i] == '-' && !char.IsDigit(line[i + 1]) && line[i - 1] != '(')
{
return false;
}
}
return true;
}
}
[BepInPlugin("waffle.ultrakill.bigcg", "Big Cybergrind", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "waffle.ultrakill.bigcg";
public const string Name = "Big Cybergrind";
public const string Version = "1.0.0";
[Configgable("", "Enable Big CG", 0, "Enable features of the mod.\nDisable this to reenable score submission.")]
public static ConfigToggle ModEnabled = new ConfigToggle(true);
[Configgable("", "Grid Length", 0, "Length of the grid - default is 16.\nThis starts lagging really bad at high values.")]
public static int GridSize = 32;
[Configgable("", "Budget Multiplier", 1, "Increase the budget allocated to enemy spawns to offset the size of the map.")]
public static int Multiplier = 2;
[Configgable("Optimisations", "Optimised Cube Model", 2, "Replaces the grid cube model with one that has 1/5th of the tris.\nLooks worse when using texture or vertex warping.")]
public static bool OptimizedModel = true;
[Configgable("Optimisations", "Optimised Stair Model", 3, "Replaces the stairs with a ramp that has 1/10th of the tris.\nLooks worse generally and when using texture or vertex warping.")]
public static bool OptimizedStairs = false;
[Configgable("Optimisations", "Fast Animation", 4, "Animations between waves are buggy, but lag less.\nGood for performance, but not recommended.")]
public static bool FastAnim = false;
private static Harmony s_harmony = new Harmony("waffle.ultrakill.bigcg");
private static FieldInfo s_gridSize = AccessTools.Field(typeof(Plugin), "GridSize");
private static MethodInfo s_mainGridSize = AccessTools.Method(typeof(Plugin), "get_MainGridSize", (Type[])null, (Type[])null);
private static MethodInfo s_getFiles = AccessTools.Method(typeof(Directory), "GetFiles", new Type[3]
{
typeof(string),
typeof(string),
typeof(SearchOption)
}, (Type[])null);
private static MethodInfo s_getFilesReplacement = AccessTools.Method(typeof(Plugin), "GetFilesReplacement", (Type[])null, (Type[])null);
private static MethodInfo s_fixStringPattern = AccessTools.Method(typeof(PatternFixer), "FixStringPattern", (Type[])null, (Type[])null);
private static MethodInfo s_readAllLines = AccessTools.Method(typeof(File), "ReadAllLines", new Type[1] { typeof(string) }, (Type[])null);
private static string[] s_extensions = new string[2] { ".cgp", ".cgpe" };
private static List<GameObject> s_mergedMeshes = new List<GameObject>();
private static AssetBundle s_modBundle;
private static Mesh s_optimizedCube;
private static Mesh s_optimizedStairs;
public static int MainGridSize => (GridSize >= 16) ? 16 : GridSize;
private void Start()
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
string path = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar));
s_modBundle = AssetBundle.LoadFromFile(Path.Combine(path, "bigcgassets.bundle"));
s_optimizedCube = s_modBundle.LoadAsset<Mesh>("optimizedgridcube.dae");
s_optimizedStairs = s_modBundle.LoadAsset<Mesh>("optimizedstairs.dae");
ConfigBuilder val = new ConfigBuilder("waffle.ultrakill.bigcg", "Big Cybergrind");
val.Build();
((ConfigValueElement<bool>)(object)ModEnabled).OnValueChanged = delegate(bool value)
{
if (value)
{
s_harmony.PatchAll(typeof(Plugin));
}
else
{
s_harmony.UnpatchSelf();
}
};
}
[HarmonyPatch(typeof(LeaderboardController), "SubmitCyberGrindScore")]
[HarmonyPatch(typeof(LeaderboardController), "SubmitLevelScore")]
[HarmonyPrefix]
private static bool DisableCg()
{
Debug.Log((object)"BCG patches enabled, disable CG ‼\ufe0f");
return false;
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(CustomPatterns), "GeneratePatternPreview")]
[HarmonyPatch(typeof(EndlessGrid), "LoadPattern")]
[HarmonyPatch(typeof(EndlessGrid), "MakeGridDynamic")]
[HarmonyPatch(typeof(EndlessGrid), "OneDone")]
[HarmonyPatch(typeof(EndlessGrid), "Start")]
private static IEnumerable<CodeInstruction> ReplaceGridSize(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_I4_S && (sbyte)instruction.operand == 16)
{
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
}
yield return instruction;
}
}
[HarmonyPatch(typeof(EndlessGrid), "SetupStaticGridMesh")]
private static IEnumerable<CodeInstruction> ReplaceMainGridSize(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_I4_S && (sbyte)instruction.operand == 16)
{
instruction.opcode = OpCodes.Call;
instruction.operand = s_mainGridSize;
}
yield return instruction;
}
}
[HarmonyPatch(typeof(CustomPatterns), "BuildButtons")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> FixButtonSize(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_R4 && CodeInstructionExtensions.OperandIs(instruction, (object)48f))
{
yield return new CodeInstruction(OpCodes.Ldsfld, (object)s_gridSize);
yield return new CodeInstruction(OpCodes.Ldc_I4_3, (object)null);
yield return new CodeInstruction(OpCodes.Mul, (object)null);
yield return new CodeInstruction(OpCodes.Conv_R4, (object)null);
}
else if (instruction.opcode == OpCodes.Ldc_I4_S && CodeInstructionExtensions.OperandIs(instruction, (object)48))
{
yield return new CodeInstruction(OpCodes.Ldsfld, (object)s_gridSize);
yield return new CodeInstruction(OpCodes.Ldc_I4_3, (object)null);
yield return new CodeInstruction(OpCodes.Mul, (object)null);
}
else
{
yield return instruction;
}
}
}
[HarmonyPatch(typeof(CustomPatterns), "LoadPattern")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> CustomPatternsLoadPattern(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_I4_S)
{
switch ((sbyte)instruction.operand)
{
case 15:
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
yield return instruction;
yield return new CodeInstruction(OpCodes.Ldc_I4_1, (object)null);
yield return new CodeInstruction(OpCodes.Sub, (object)null);
continue;
case 16:
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
yield return instruction;
continue;
case 17:
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
yield return instruction;
yield return new CodeInstruction(OpCodes.Ldc_I4_1, (object)null);
yield return new CodeInstruction(OpCodes.Add, (object)null);
continue;
case 32:
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
yield return instruction;
yield return new CodeInstruction(OpCodes.Ldc_I4_2, (object)null);
yield return new CodeInstruction(OpCodes.Mul, (object)null);
continue;
case 33:
instruction.opcode = OpCodes.Ldsfld;
instruction.operand = s_gridSize;
yield return instruction;
yield return new CodeInstruction(OpCodes.Ldc_I4_2, (object)null);
yield return new CodeInstruction(OpCodes.Mul, (object)null);
yield return new CodeInstruction(OpCodes.Ldc_I4_1, (object)null);
yield return new CodeInstruction(OpCodes.Add, (object)null);
continue;
}
}
yield return instruction;
if (instruction.opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)s_readAllLines))
{
yield return new CodeInstruction(OpCodes.Call, (object)s_fixStringPattern);
}
}
}
[HarmonyPatch(typeof(EndlessGrid), "LoadPattern")]
[HarmonyPrefix]
private static void FixPatterns(EndlessGrid __instance, ArenaPattern pattern)
{
PatternFixer.FixPattern(pattern);
}
[HarmonyPatch(typeof(EndlessGrid), "NextWave")]
[HarmonyPostfix]
private static void DestroyBakedMeshes()
{
s_mergedMeshes.RemoveAll((GameObject x) => (Object)(object)x == (Object)null);
foreach (GameObject s_mergedMesh in s_mergedMeshes)
{
Object.Destroy((Object)(object)s_mergedMesh);
}
}
[HarmonyPatch(typeof(EndlessGrid), "SetupStaticGridMesh")]
[HarmonyPostfix]
private static void DoOtherBakes()
{
int num = GridSize * GridSize;
int num3;
for (int i = MainGridSize * MainGridSize; i != num; i += num3)
{
int num2 = num - i;
num3 = ((150 > num2) ? num2 : 150);
s_mergedMeshes.Add(MeshBaking.CreateCubeMesh(i - 1, num3));
}
int num4 = MonoSingleton<EndlessGrid>.Instance.spawnedPrefabs.Count((GameObject x) => (Object)(object)x.GetComponent<EndlessStairs>() != (Object)null);
int num6;
for (int j = 0; j != num4; j += num6)
{
int num5 = num4 - j;
num6 = ((150 > num5) ? num5 : 150);
s_mergedMeshes.Add(MeshBaking.CreateStairsMesh(j - 1, num6));
}
}
[HarmonyPatch(typeof(EndlessGrid), "SetupStaticGridMesh")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> PreventStairCreation(IEnumerable<CodeInstruction> instructions)
{
CodeInstruction[] ciArray = instructions.ToArray();
for (int i = 0; i < ciArray.Length; i++)
{
if (i < 2)
{
yield return ciArray[i];
continue;
}
if (ciArray[i - 2].opcode == OpCodes.Ldloc_S && ciArray[i - 1].opcode == OpCodes.Ldc_I4_1 && ciArray[i].opcode == OpCodes.Bne_Un)
{
yield return new CodeInstruction(OpCodes.Pop, (object)null);
yield return new CodeInstruction(OpCodes.Ldc_I4, (object)100);
}
yield return ciArray[i];
}
}
[HarmonyPatch(typeof(EndlessCube), "Update")]
[HarmonyPostfix]
private static void FixSlowMoveCube(EndlessCube __instance)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (FastAnim && __instance.active)
{
__instance.tf.position = __instance.targetPos;
}
}
[HarmonyPatch(typeof(EndlessStairs), "Update")]
[HarmonyPostfix]
private static void FixSlowMoveStairs(EndlessStairs __instance)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if (FastAnim && __instance.moving)
{
if (__instance.activateFirst)
{
__instance.primaryStairs.position = ((Component)__instance).transform.position;
}
if (__instance.activateSecond)
{
__instance.secondaryStairs.position = ((Component)__instance).transform.position;
}
}
}
[HarmonyPatch(typeof(EndlessGrid), "GetEnemies")]
[HarmonyPrefix]
private static void MultiplyPoints(EndlessGrid __instance)
{
__instance.maxPoints *= Multiplier;
Debug.Log((object)("Multiplying points to " + __instance.maxPoints));
}
[HarmonyPatch(typeof(EndlessGrid), "GetNextEnemy")]
[HarmonyPrefix]
private static void CheckIfWasLastEnemy(EndlessGrid __instance, ref bool __state)
{
__state = __instance.enemyAmount == __instance.tempEnemyAmount;
}
[HarmonyPatch(typeof(EndlessGrid), "GetNextEnemy")]
[HarmonyPostfix]
private static void DividePoints(EndlessGrid __instance, ref bool __state)
{
if (!__state && __instance.enemyAmount == __instance.tempEnemyAmount)
{
__instance.maxPoints /= Multiplier;
Debug.Log((object)("Dividing points to " + __instance.maxPoints));
}
}
[HarmonyPatch(typeof(EndlessCube), "Awake")]
[HarmonyPostfix]
private static void ReplaceCubeModel(EndlessCube __instance)
{
if (OptimizedModel)
{
__instance.MeshFilter.mesh = s_optimizedCube;
}
}
[HarmonyPatch(typeof(EndlessStairs), "Start")]
[HarmonyPostfix]
private static void ReplaceStairModel(EndlessStairs __instance)
{
if (OptimizedStairs)
{
__instance.PrimaryMeshFilter.mesh = s_optimizedStairs;
__instance.SecondaryMeshFilter.mesh = s_optimizedStairs;
}
}
[HarmonyPatch(typeof(CustomPatterns), "BuildButtons")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> AddCgpeFiles(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)s_getFiles))
{
instruction.operand = s_getFilesReplacement;
}
yield return instruction;
}
}
[HarmonyPatch(typeof(CustomPatterns), "OpenEditor")]
[HarmonyPrefix]
private static bool OpenCustomEditor()
{
Application.OpenURL("https://wafflethings.github.io/CGPEditor/");
return false;
}
private static string[] GetFilesReplacement(string path, string filter, SearchOption option)
{
return (from f in new DirectoryInfo(path).EnumerateFiles()
where s_extensions.Contains(f.Extension.ToLower())
select f.ToString()).ToArray();
}
}
}