using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using PluginConfig.API; using PluginConfig.API.Decorators; using PluginConfig.API.Fields; using PluginConfig.API.Functionals; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("CyberGrindFilter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CyberGrindFilter")] [assembly: AssemblyTitle("CG Spawn Filter")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace CyberGrindFilter; internal class EnemySpawnField : CustomConfigField { private static TMP_FontAsset cachedFont; private static Sprite cachedToggleBg; private static Sprite cachedCheckmark; private static ColorBlock cachedToggleColors; private static Color cachedCheckmarkColor = Color.white; private static bool styleResolved; private readonly ConfigEntry spawnEntry; private readonly ConfigEntry radiantEntry; private readonly Action onChanged; private Toggle spawnToggle; private Toggle radiantToggle; public bool SpawnEnabled => spawnEntry.Value; public bool RadiantEnabled => radiantEntry.Value; public EnemySpawnField(ConfigPanel panel, string name, string key, Action onChanged) : base(panel, 600f, 30f, name) { this.onChanged = onChanged; spawnEntry = Plugin.BepConfig.Bind("Enemies", key + "_spawn", true, (ConfigDescription)null); radiantEntry = Plugin.BepConfig.Bind("Enemies", key + "_radiant", true, (ConfigDescription)null); if (!spawnEntry.Value) { radiantEntry.Value = false; } } private static void ResolveStyle(RectTransform fieldUI) { //IL_0066: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (styleResolved) { return; } styleResolved = true; TextMeshProUGUI val = (((Object)(object)((Transform)fieldUI).parent != (Object)null) ? ((Component)((Transform)fieldUI).parent).GetComponentInChildren() : null); if ((Object)(object)val != (Object)null) { cachedFont = ((TMP_Text)val).font; } Toggle val2 = (((Object)(object)((Transform)fieldUI).parent != (Object)null) ? ((Component)((Transform)fieldUI).parent).GetComponentInChildren() : null); if ((Object)(object)val2 != (Object)null) { cachedToggleColors = ((Selectable)val2).colors; Graphic targetGraphic = ((Selectable)val2).targetGraphic; Image val3 = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); if ((Object)(object)val3 != (Object)null) { cachedToggleBg = val3.sprite; } Graphic graphic = val2.graphic; Image val4 = (Image)(object)((graphic is Image) ? graphic : null); if ((Object)(object)val4 != (Object)null) { cachedCheckmark = val4.sprite; cachedCheckmarkColor = ((Graphic)val4).color; } } } protected override void OnCreateUI(RectTransform fieldUI) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_00a4: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) ResolveStyle(fieldUI); GameObject val = new GameObject("FieldBg"); val.transform.SetParent((Transform)(object)fieldUI, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.sizeDelta = Vector2.zero; ((Graphic)val.AddComponent()).color = Color.black; val.AddComponent().ignoreLayout = true; HorizontalLayoutGroup obj2 = ((Component)fieldUI).gameObject.AddComponent(); ((LayoutGroup)obj2).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((LayoutGroup)obj2).padding = new RectOffset(8, 8, 2, 2); AddLabel(fieldUI, ((ConfigField)this).displayName, 14f, 1f, 200f); spawnToggle = AddToggle(fieldUI, spawnEntry.Value, disabled: false); AddLabel(fieldUI, "SPAWN", 12f, 0f, 50f); radiantToggle = AddToggle(fieldUI, radiantEntry.Value, !spawnEntry.Value); TextMeshProUGUI radiantLabel = AddLabel(fieldUI, "RADIANT", 12f, 0f, 60f); if (!spawnEntry.Value) { ((Graphic)radiantLabel).color = new Color(1f, 1f, 1f, 0.3f); } ((UnityEvent)(object)spawnToggle.onValueChanged).AddListener((UnityAction)delegate(bool flag) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) spawnEntry.Value = flag; if (!flag) { radiantToggle.SetIsOnWithoutNotify(false); radiantEntry.Value = false; ((Selectable)radiantToggle).interactable = false; SetToggleBgAlpha(radiantToggle, 0.4f); ((Graphic)radiantLabel).color = new Color(1f, 1f, 1f, 0.3f); } else { radiantToggle.SetIsOnWithoutNotify(true); radiantEntry.Value = true; ((Selectable)radiantToggle).interactable = true; SetToggleBgAlpha(radiantToggle, 1f); ((Graphic)radiantLabel).color = Color.white; } onChanged?.Invoke(); }); ((UnityEvent)(object)radiantToggle.onValueChanged).AddListener((UnityAction)delegate(bool value) { radiantEntry.Value = value; onChanged?.Invoke(); }); } private TextMeshProUGUI AddLabel(RectTransform parent, string text, float fontSize, float flexWidth, float minWidth) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Label"); val.transform.SetParent((Transform)(object)parent, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text; ((TMP_Text)val2).fontSize = fontSize; ((Graphic)val2).color = Color.white; ((TMP_Text)val2).alignment = (TextAlignmentOptions)4097; if ((Object)(object)cachedFont != (Object)null) { ((TMP_Text)val2).font = cachedFont; } LayoutElement obj = val.AddComponent(); obj.flexibleWidth = flexWidth; obj.minWidth = minWidth; obj.minHeight = 26f; return val2; } private Toggle AddToggle(RectTransform parent, bool value, bool disabled) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01cc: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Toggle"); val.transform.SetParent((Transform)(object)parent, false); LayoutElement obj = val.AddComponent(); obj.minWidth = 30f; obj.minHeight = 30f; obj.preferredWidth = 30f; obj.preferredHeight = 30f; GameObject val2 = new GameObject("Background"); val2.transform.SetParent(val.transform, false); RectTransform obj2 = val2.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.sizeDelta = Vector2.zero; Image val3 = val2.AddComponent(); if ((Object)(object)cachedToggleBg != (Object)null) { val3.sprite = cachedToggleBg; val3.type = (Type)1; } ((Graphic)val3).color = (disabled ? new Color(0.15f, 0.15f, 0.15f, 0.4f) : new Color(0.15f, 0.15f, 0.15f)); GameObject val4 = new GameObject("Checkmark"); val4.transform.SetParent(val2.transform, false); RectTransform obj3 = val4.AddComponent(); obj3.anchorMin = new Vector2(0.15f, 0.15f); obj3.anchorMax = new Vector2(0.85f, 0.85f); obj3.sizeDelta = Vector2.zero; Image val5 = val4.AddComponent(); if ((Object)(object)cachedCheckmark != (Object)null) { val5.sprite = cachedCheckmark; val5.type = (Type)0; ((Graphic)val5).color = cachedCheckmarkColor; } else { ((Graphic)val5).color = Color.white; } Toggle val6 = val.AddComponent(); ((Selectable)val6).targetGraphic = (Graphic)(object)val3; val6.graphic = (Graphic)(object)val5; val6.isOn = value; ((Selectable)val6).interactable = !disabled; if (styleResolved && ((ColorBlock)(ref cachedToggleColors)).normalColor != default(Color)) { ((Selectable)val6).colors = cachedToggleColors; } return val6; } private static void SetToggleBgAlpha(Toggle toggle, float alpha) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Graphic targetGraphic = ((Selectable)toggle).targetGraphic; Image val = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); if ((Object)(object)val != (Object)null) { Color color = ((Graphic)val).color; color.a = alpha; ((Graphic)val).color = color; } } public void SetSpawn(bool value) { if ((Object)(object)spawnToggle != (Object)null) { spawnToggle.isOn = value; return; } spawnEntry.Value = value; radiantEntry.Value = value; } public void SetRadiant(bool value) { if ((Object)(object)radiantToggle != (Object)null && ((Selectable)radiantToggle).interactable) { radiantToggle.isOn = value; } else if (SpawnEnabled) { radiantEntry.Value = value; } } } [HarmonyPatch] internal static class Patches { private static EndlessEnemy[] origMelee; private static EndlessEnemy[] origProjectile; private static EndlessEnemy[] origUncommon; private static EndlessEnemy[] origSpecial; private static GameObject origHideousMass; private static PrefabDatabase prefabDb; private static bool fallbackActive; private static bool inGetNextEnemy; private static readonly Dictionary originalSpawnWaves = new Dictionary(); private static bool hmOnlyMode; private static string GetFullName(EndlessEnemy enemy) { EnemyIdentifier componentInChildren = enemy.prefab.GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null)) { return ((object)Unsafe.As(ref enemy.enemyType)/*cast due to .constrained prefix*/).ToString(); } return componentInChildren.FullName; } private static EndlessEnemy CloneForFallback(EndlessEnemy e) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) EndlessEnemy val = ScriptableObject.CreateInstance(); val.enemyType = e.enemyType; val.prefab = e.prefab; val.spawnCost = e.spawnCost; val.spawnWave = 0; val.costIncreasePerSpawn = 0; originalSpawnWaves[val] = e.spawnWave; return val; } internal static void ApplyFilters() { if ((Object)(object)prefabDb == (Object)null || origMelee == null) { return; } originalSpawnWaves.Clear(); fallbackActive = false; prefabDb.meleeEnemies = origMelee.Where((EndlessEnemy e) => Settings.IsSpawnEnabled(GetFullName(e))).ToArray(); prefabDb.projectileEnemies = origProjectile.Where((EndlessEnemy e) => Settings.IsSpawnEnabled(GetFullName(e))).ToArray(); prefabDb.uncommonEnemies = origUncommon.Where((EndlessEnemy e) => Settings.IsSpawnEnabled(GetFullName(e))).ToArray(); prefabDb.specialEnemies = origSpecial.Where((EndlessEnemy e) => Settings.IsSpawnEnabled(GetFullName(e))).ToArray(); prefabDb.hideousMass = (Settings.IsSpawnEnabledHM() ? origHideousMass : null); if (prefabDb.meleeEnemies.Length == 0 && prefabDb.projectileEnemies.Length == 0) { fallbackActive = true; EndlessEnemy[] array = prefabDb.uncommonEnemies.Concat(prefabDb.specialEnemies).Select(CloneForFallback).ToArray(); if (array.Length != 0) { prefabDb.meleeEnemies = array; prefabDb.projectileEnemies = array; } prefabDb.uncommonEnemies = prefabDb.uncommonEnemies.Select(CloneForFallback).ToArray(); prefabDb.specialEnemies = prefabDb.specialEnemies.Select(CloneForFallback).ToArray(); } else if (prefabDb.meleeEnemies.Length == 0) { prefabDb.meleeEnemies = prefabDb.projectileEnemies; } else if (prefabDb.projectileEnemies.Length == 0) { prefabDb.projectileEnemies = prefabDb.meleeEnemies; } hmOnlyMode = prefabDb.meleeEnemies.Length == 0 && prefabDb.projectileEnemies.Length == 0 && prefabDb.uncommonEnemies.Length == 0 && prefabDb.specialEnemies.Length == 0 && (Object)(object)prefabDb.hideousMass != (Object)null; int num = origMelee.Length - prefabDb.meleeEnemies.Length + origProjectile.Length - prefabDb.projectileEnemies.Length + origUncommon.Length - prefabDb.uncommonEnemies.Length + origSpecial.Length - prefabDb.specialEnemies.Length + (((Object)(object)prefabDb.hideousMass == (Object)null && (Object)(object)origHideousMass != (Object)null) ? 1 : 0); if (num > 0) { Plugin.Log.LogInfo((object)$"Filters applied: {num} enemy type(s) blocked"); } Plugin.Log.LogInfo((object)string.Format("[DEBUG] ApplyFilters: hmOnlyMode={0} fallback={1} melee={2} proj={3} uncom={4} spec={5} hm={6}", hmOnlyMode, fallbackActive, prefabDb.meleeEnemies.Length, prefabDb.projectileEnemies.Length, prefabDb.uncommonEnemies.Length, prefabDb.specialEnemies.Length, ((Object)(object)prefabDb.hideousMass != (Object)null) ? "yes" : "null")); } [HarmonyPatch(typeof(EndlessGrid), "Start")] [HarmonyPostfix] private static void Start_Postfix(PrefabDatabase ___prefabs) { try { prefabDb = ___prefabs; if (origMelee == null) { origMelee = ___prefabs.meleeEnemies.ToArray(); origProjectile = ___prefabs.projectileEnemies.ToArray(); origUncommon = ___prefabs.uncommonEnemies.ToArray(); origSpecial = ___prefabs.specialEnemies.ToArray(); origHideousMass = ___prefabs.hideousMass; } else { ___prefabs.meleeEnemies = origMelee.ToArray(); ___prefabs.projectileEnemies = origProjectile.ToArray(); ___prefabs.uncommonEnemies = origUncommon.ToArray(); ___prefabs.specialEnemies = origSpecial.ToArray(); ___prefabs.hideousMass = origHideousMass; } ApplyFilters(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Start_Postfix error: {arg}"); } } [HarmonyPatch(typeof(EndlessGrid), "SpawnRadiant")] [HarmonyPrefix] private static bool SpawnRadiant_Prefix(EndlessEnemy target, int indexOf, int ___currentWave, List ___spawnedEnemyTypes, ref bool __result) { if (!Settings.IsRadiantEnabled(GetFullName(target))) { __result = false; return false; } if (fallbackActive && originalSpawnWaves.TryGetValue(target, out var value)) { float num = value * 2 + 25; float num2 = target.spawnCost; if (target.spawnCost < 10) { num2 += 1f; } if (target.spawnCost > 10) { num2 = num2 / 2f + 5f; } __result = (float)___currentWave >= num + (float)___spawnedEnemyTypes[indexOf].amount * num2; return false; } return true; } [HarmonyPatch(typeof(EndlessGrid), "SpawnOnGrid")] [HarmonyPrefix] private static bool SpawnOnGrid_Prefix(GameObject obj, ref GameObject __result) { if ((Object)(object)obj == (Object)null) { __result = null; return false; } return true; } [HarmonyPatch(typeof(EndlessGrid), "GetEnemies")] [HarmonyPrefix] private static void GetEnemies_Prefix(PrefabDatabase ___prefabs, ref int ___hideousMasses, ref int ___points, int ___massAntiBuffer, int ___currentWave, ref float ___uncommonAntiBuffer, ref int ___specialAntiBuffer) { if (hmOnlyMode) { Plugin.Log.LogInfo((object)string.Format("[DEBUG] GetEnemies: hideousMasses={0} points={1} massAntiBuffer={2} wave={3} hm={4}", ___hideousMasses, ___points, ___massAntiBuffer, ___currentWave, ((Object)(object)___prefabs.hideousMass != (Object)null) ? "yes" : "null")); } if ((Object)(object)___prefabs.hideousMass == (Object)null && ___hideousMasses > 0) { ___points += ___hideousMasses * 45; ___hideousMasses = 0; } if (___prefabs.uncommonEnemies.Length == 0) { ___uncommonAntiBuffer = 999f; } if (___prefabs.specialEnemies.Length == 0) { ___specialAntiBuffer = 999; } } [HarmonyPatch(typeof(EndlessGrid), "GetEnemies")] [HarmonyPostfix] private static void GetEnemies_Postfix(List ___deathcatchers, List ___spawnPartway, ref int ___totalDeathcatchers) { if (!fallbackActive) { return; } if (___spawnPartway != null) { foreach (GameObject item in ___spawnPartway) { if ((Object)(object)item != (Object)null) { item.SetActive(true); } } ___spawnPartway.Clear(); } if (___deathcatchers != null) { ___deathcatchers.Clear(); ___totalDeathcatchers = 0; } } [HarmonyPatch(typeof(EndlessGrid), "GetNextEnemy")] [HarmonyPrefix] private static bool GetNextEnemy_Prefix(PrefabDatabase ___prefabs, ref int ___usedMeleePositions, List ___meleePositions, ref int ___usedProjectilePositions, List ___projectilePositions, ref int ___enemyAmount, int ___tempEnemyAmount) { if (fallbackActive) { inGetNextEnemy = true; } bool flag = ___prefabs.meleeEnemies.Length != 0; bool flag2 = ___prefabs.projectileEnemies.Length != 0; if (!flag && !flag2) { if (hmOnlyMode) { Plugin.Log.LogInfo((object)$"[DEBUG] GetNextEnemy: empty arrays, enemyAmount={___tempEnemyAmount}"); } ___enemyAmount = ___tempEnemyAmount; inGetNextEnemy = false; return false; } if (!flag) { ___usedMeleePositions = ___meleePositions.Count; } if (!flag2) { ___usedProjectilePositions = ___projectilePositions.Count; } return true; } [HarmonyPatch(typeof(EndlessGrid), "GetNextEnemy")] [HarmonyPostfix] private static void GetNextEnemy_Postfix() { inGetNextEnemy = false; } [HarmonyPatch(typeof(EndlessGrid), "NextWave")] [HarmonyPrefix] private static void NextWave_Prefix(ref int ___massAntiBuffer, ref int ___hideousMasses, ref int ___maxPoints) { if (Settings.IsAutoRandomize) { Settings.Randomize(); } if (hmOnlyMode) { Plugin.Log.LogInfo((object)$"[DEBUG] NextWave PRE: massAntiBuffer={___massAntiBuffer} hideousMasses={___hideousMasses} maxPoints={___maxPoints}"); ___massAntiBuffer = 0; ___hideousMasses = 0; if (___maxPoints < 71) { ___maxPoints = 71; } Plugin.Log.LogInfo((object)$"[DEBUG] NextWave POST: massAntiBuffer={___massAntiBuffer} hideousMasses={___hideousMasses} maxPoints={___maxPoints}"); } } [HarmonyPatch(typeof(Deathcatcher), "Start")] [HarmonyPostfix] private static void Deathcatcher_Start_Postfix(Deathcatcher __instance) { if (fallbackActive && !((Object)(object)prefabDb == (Object)null)) { __instance.IsActive(true); Transform parent = ((Component)__instance).transform.parent; Transform val = ((parent != null) ? parent.Find("Case/Opener") : null); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); } } } [HarmonyPatch(typeof(LeaderboardController), "SubmitCyberGrindScore")] [HarmonyPrefix] private static bool SubmitCyberGrindScore_Prefix() { if (Settings.IsFiltering) { Plugin.Log.LogInfo((object)"Leaderboard submission blocked: spawn filters are active"); return false; } return true; } [HarmonyPatch(typeof(GameProgressSaver), "SetBestCyber")] [HarmonyPrefix] private static bool SetBestCyber_Prefix() { if (Settings.IsFiltering) { Plugin.Log.LogInfo((object)"Local high score save blocked: spawn filters are active"); return false; } return true; } } [BepInPlugin("CyberGrindFilter", "Cybergrind Spawn Filter", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigFile BepConfig; private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; BepConfig = ((BaseUnityPlugin)this).Config; Settings.Initialize(); new Harmony("CyberGrindFilter").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Cybergrind Spawn Filter v1.0.0 loaded"); } } internal static class PluginInfo { public const string GUID = "CyberGrindFilter"; public const string NAME = "Cybergrind Spawn Filter"; public const string VERSION = "1.0.0"; } internal static class Settings { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static OnClick <>9__16_0; public static BoolValueChangeEventDelegate <>9__16_1; public static Func <>9__19_2; public static Func <>9__19_3; public static Func <>9__19_4; public static Action <>9__20_0; internal void b__16_0() { Randomize(); } internal void b__16_1(BoolValueChangeEvent e) { pendingHmValue = e.value; Patches.ApplyFilters(); pendingHmValue = null; } internal bool b__19_2(EnemySpawnField f) { return !f.SpawnEnabled; } internal bool b__19_3(EnemySpawnField f) { return f.SpawnEnabled; } internal bool b__19_4(EnemySpawnField f) { return !f.RadiantEnabled; } internal void b__20_0() { Patches.ApplyFilters(); } } private static readonly Dictionary enemyToggles = new Dictionary(); private static BoolField hideousMassSpawn; private static bool? pendingHmValue; private static SpawnChanceSlider randomizeSlider; private static BoolField autoRandomize; private static readonly List commonToggles = new List(); private static readonly List uncommonToggles = new List(); private static readonly List specialToggles = new List(); public static bool IsFiltering { get { foreach (EnemySpawnField value in enemyToggles.Values) { if (!value.SpawnEnabled || !value.RadiantEnabled) { return true; } } if (hideousMassSpawn != null && !hideousMassSpawn.value) { return true; } return false; } } public static bool IsAutoRandomize { get { BoolField obj = autoRandomize; if (obj == null) { return false; } return obj.value; } } internal static void Randomize() { int value = randomizeSlider.Value; List list = enemyToggles.Values.ToList(); foreach (EnemySpawnField item in list) { item.SetSpawn(value: false); } if (hideousMassSpawn != null) { hideousMassSpawn.value = false; } int num = list.Count + ((hideousMassSpawn != null) ? 1 : 0); value = Mathf.Min(value, num); List list2 = Enumerable.Range(0, num).ToList(); for (int num2 = list2.Count - 1; num2 > 0; num2--) { int index = Random.Range(0, num2 + 1); int value2 = list2[num2]; list2[num2] = list2[index]; list2[index] = value2; } for (int i = 0; i < value; i++) { int num3 = list2[i]; if (num3 < list.Count) { list[num3].SetSpawn(value: true); list[num3].SetRadiant(value: true); } else if (hideousMassSpawn != null) { hideousMassSpawn.value = true; } } Patches.ApplyFilters(); } public static bool IsSpawnEnabled(string fullName) { if (enemyToggles.TryGetValue(fullName, out var value)) { return value.SpawnEnabled; } return true; } public static bool IsSpawnEnabledHM() { if (pendingHmValue.HasValue) { return pendingHmValue.Value; } BoolField obj = hideousMassSpawn; if (obj == null) { return true; } return obj.value; } public static bool IsRadiantEnabled(string fullName) { if (enemyToggles.TryGetValue(fullName, out var value)) { return value.RadiantEnabled; } return true; } internal static void Initialize() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_013d: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Expected O, but got Unknown try { PluginConfigurator val = PluginConfigurator.Create("Cybergrind Spawn Filter", "CyberGrindFilter"); LoadIcon(val); PrefabDatabase val2 = Addressables.LoadAssetAsync((object)"Assets/Data/Cyber Grind Patterns/Data/Prefab Database.asset").WaitForCompletion(); LogEnemies("Melee", val2.meleeEnemies); LogEnemies("Projectile", val2.projectileEnemies); LogEnemies("Uncommon", val2.uncommonEnemies); LogEnemies("Special", val2.specialEnemies); new ConfigHeader(val.rootPanel, " ", 8); new ConfigHeader(val.rootPanel, "GLOBAL CONTROLS", 18); AddBulkButtons(val.rootPanel, "global", enemyToggles.Values, includeHM: true); new ConfigHeader(val.rootPanel, "RANDOMIZE", 18); ButtonField val3 = new ButtonField(val.rootPanel, "RANDOMIZE SPAWNS", "global_randomize"); randomizeSlider = new SpawnChanceSlider(val.rootPanel, "RANDOMIZE CHOOSE COUNT", "randomizeCount", 10, 1); autoRandomize = new BoolField(val.rootPanel, "AUTO-RANDOMIZE ON WAVE START", "autoRandomize", false); object obj = <>c.<>9__16_0; if (obj == null) { OnClick val4 = delegate { Randomize(); }; <>c.<>9__16_0 = val4; obj = (object)val4; } val3.onClick += (OnClick)obj; new ConfigHeader(val.rootPanel, "COMMON ENEMIES", 18); AddBulkButtons(val.rootPanel, "common", commonToggles, includeHM: false); foreach (EndlessEnemy item in val2.meleeEnemies.Concat(val2.projectileEnemies)) { AddEnemyField(val.rootPanel, item.prefab, commonToggles); } new ConfigHeader(val.rootPanel, "UNCOMMON ENEMIES", 18); AddBulkButtons(val.rootPanel, "uncommon", uncommonToggles, includeHM: false); EndlessEnemy[] uncommonEnemies = val2.uncommonEnemies; foreach (EndlessEnemy val5 in uncommonEnemies) { AddEnemyField(val.rootPanel, val5.prefab, uncommonToggles); } new ConfigHeader(val.rootPanel, "SPECIAL ENEMIES", 18); AddBulkButtons(val.rootPanel, "special", specialToggles, includeHM: false); uncommonEnemies = val2.specialEnemies; foreach (EndlessEnemy val6 in uncommonEnemies) { AddEnemyField(val.rootPanel, val6.prefab, specialToggles); } new ConfigHeader(val.rootPanel, "HIDEOUS MASS", 18); EnemyIdentifier componentInChildren = val2.hideousMass.GetComponentInChildren(true); string text = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.FullName : "Hideous Mass"); hideousMassSpawn = new BoolField(val.rootPanel, text.ToUpperInvariant(), "spawn_HideousMass", true); BoolField obj2 = hideousMassSpawn; object obj3 = <>c.<>9__16_1; if (obj3 == null) { BoolValueChangeEventDelegate val7 = delegate(BoolValueChangeEvent e) { pendingHmValue = e.value; Patches.ApplyFilters(); pendingHmValue = null; }; <>c.<>9__16_1 = val7; obj3 = (object)val7; } obj2.onValueChange += (BoolValueChangeEventDelegate)obj3; int max = enemyToggles.Count + ((hideousMassSpawn != null) ? 1 : 0); randomizeSlider.SetMax(max); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize settings: {arg}"); } } private static void LoadIcon(PluginConfigurator config) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string path = Path.Combine(directoryName, "icon.png"); if (!File.Exists(path)) { DirectoryInfo parent = Directory.GetParent(directoryName); if (parent != null) { path = Path.Combine(parent.FullName, "icon.png"); } } if (File.Exists(path)) { byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); config.image = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to load icon: " + ex.Message)); } } private static void LogEnemies(string category, EndlessEnemy[] enemies) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < enemies.Length; i++) { EnemyIdentifier componentInChildren = enemies[i].prefab.GetComponentInChildren(true); string text = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.FullName : "???"); Plugin.Log.LogInfo((object)$"[{category}][{i}] {enemies[i].enemyType} = {text} (cost={enemies[i].spawnCost}, wave={enemies[i].spawnWave})"); } } private static void AddBulkButtons(ConfigPanel panel, string prefix, IEnumerable toggles, bool includeHM) { //IL_0052: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown ButtonArrayField val = new ButtonArrayField(panel, prefix + "_bulk", 2, new float[2] { 0.5f, 0.5f }, new string[2] { "TOGGLE ALL SPAWN", "TOGGLE ALL RADIANT" }, 5f); val.OnClickEventHandler(0).onClick += (OnClick)delegate { bool flag = toggles.Any((EnemySpawnField f) => !f.SpawnEnabled); if (includeHM && hideousMassSpawn != null && !hideousMassSpawn.value) { flag = true; } foreach (EnemySpawnField toggle in toggles) { toggle.SetSpawn(flag); } if (includeHM && hideousMassSpawn != null) { hideousMassSpawn.value = flag; } Patches.ApplyFilters(); }; val.OnClickEventHandler(1).onClick += (OnClick)delegate { List list = toggles.Where((EnemySpawnField f) => f.SpawnEnabled).ToList(); bool radiant = list.Any((EnemySpawnField f) => !f.RadiantEnabled); foreach (EnemySpawnField item in list) { item.SetRadiant(radiant); } Patches.ApplyFilters(); }; } private static void AddEnemyField(ConfigPanel panel, GameObject prefab, List sectionList) { EnemyIdentifier componentInChildren = prefab.GetComponentInChildren(true); string text = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.FullName : ((Object)prefab).name); if (!enemyToggles.ContainsKey(text)) { string key = text.Replace(" ", ""); EnemySpawnField enemySpawnField = new EnemySpawnField(panel, text.ToUpperInvariant(), key, delegate { Patches.ApplyFilters(); }); enemyToggles[text] = enemySpawnField; sectionList.Add(enemySpawnField); } } } internal class SpawnChanceSlider : CustomConfigField { private static TMP_FontAsset cachedFont; private static bool fontResolved; private readonly ConfigEntry entry; private Slider slider; private TextMeshProUGUI valueText; private int maxValue; public int Value => entry.Value; public SpawnChanceSlider(ConfigPanel panel, string name, string key, int defaultValue, int max) : base(panel, 600f, 32f, name) { maxValue = max; entry = Plugin.BepConfig.Bind("Settings", key, defaultValue, (ConfigDescription)null); if (entry.Value > max) { entry.Value = max; } if (entry.Value < 1) { entry.Value = 1; } } public void SetMax(int max) { maxValue = max; if (entry.Value > max) { entry.Value = max; } if (entry.Value < 1) { entry.Value = 1; } if ((Object)(object)slider != (Object)null) { slider.maxValue = max; slider.value = entry.Value; } if ((Object)(object)valueText != (Object)null) { ((TMP_Text)valueText).text = entry.Value.ToString(); } } protected override void OnCreateUI(RectTransform fieldUI) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown if (!fontResolved) { fontResolved = true; TextMeshProUGUI val = (((Object)(object)((Transform)fieldUI).parent != (Object)null) ? ((Component)((Transform)fieldUI).parent).GetComponentInChildren() : null); if ((Object)(object)val != (Object)null) { cachedFont = ((TMP_Text)val).font; } } GameObject val2 = new GameObject("FieldBg"); val2.transform.SetParent((Transform)(object)fieldUI, false); RectTransform obj = val2.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.sizeDelta = Vector2.zero; ((Graphic)val2.AddComponent()).color = Color.black; val2.AddComponent().ignoreLayout = true; HorizontalLayoutGroup obj2 = ((Component)fieldUI).gameObject.AddComponent(); ((LayoutGroup)obj2).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((LayoutGroup)obj2).padding = new RectOffset(8, 8, 2, 2); AddLabel(fieldUI, ((ConfigField)this).displayName, 14f, 1f, 150f); slider = BuildSlider(fieldUI); valueText = AddLabel(fieldUI, entry.Value.ToString(), 14f, 0f, 45f); ((UnityEvent)(object)slider.onValueChanged).AddListener((UnityAction)delegate(float num) { entry.Value = Mathf.RoundToInt(num); ((TMP_Text)valueText).text = entry.Value.ToString(); }); } private Slider BuildSlider(RectTransform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Slider"); val.transform.SetParent((Transform)(object)parent, false); LayoutElement obj = val.AddComponent(); obj.minWidth = 250f; obj.preferredWidth = 250f; obj.minHeight = 24f; GameObject val2 = new GameObject("Background"); val2.transform.SetParent(val.transform, false); RectTransform obj2 = val2.AddComponent(); obj2.anchorMin = new Vector2(0f, 0.5f); obj2.anchorMax = new Vector2(1f, 0.5f); obj2.sizeDelta = new Vector2(0f, 4f); obj2.anchoredPosition = Vector2.zero; ((Graphic)val2.AddComponent()).color = new Color(0.2f, 0.2f, 0.2f); GameObject val3 = new GameObject("Fill Area"); val3.transform.SetParent(val.transform, false); RectTransform obj3 = val3.AddComponent(); obj3.anchorMin = new Vector2(0f, 0.5f); obj3.anchorMax = new Vector2(1f, 0.5f); obj3.sizeDelta = new Vector2(-16f, 4f); obj3.anchoredPosition = Vector2.zero; GameObject val4 = new GameObject("Fill"); val4.transform.SetParent(val3.transform, false); RectTransform val5 = val4.AddComponent(); val5.anchorMin = Vector2.zero; val5.anchorMax = new Vector2(0f, 1f); val5.sizeDelta = Vector2.zero; ((Graphic)val4.AddComponent()).color = new Color(0.4f, 0.4f, 0.4f); GameObject val6 = new GameObject("Handle Slide Area"); val6.transform.SetParent(val.transform, false); RectTransform obj4 = val6.AddComponent(); obj4.anchorMin = Vector2.zero; obj4.anchorMax = Vector2.one; obj4.sizeDelta = new Vector2(-16f, 0f); obj4.anchoredPosition = Vector2.zero; GameObject val7 = new GameObject("Handle"); val7.transform.SetParent(val6.transform, false); RectTransform val8 = val7.AddComponent(); val8.sizeDelta = new Vector2(16f, 0f); Image val9 = val7.AddComponent(); ((Graphic)val9).color = Color.white; Slider obj5 = val.AddComponent(); ((Selectable)obj5).targetGraphic = (Graphic)(object)val9; obj5.fillRect = val5; obj5.handleRect = val8; obj5.direction = (Direction)0; obj5.minValue = 1f; obj5.maxValue = maxValue; obj5.wholeNumbers = true; obj5.value = entry.Value; ColorBlock colors = ((Selectable)obj5).colors; ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = new Color(0.85f, 0.85f, 0.85f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.65f, 0.65f, 0.65f); ((Selectable)obj5).colors = colors; return obj5; } private TextMeshProUGUI AddLabel(RectTransform parent, string text, float fontSize, float flexWidth, float minWidth) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Label"); val.transform.SetParent((Transform)(object)parent, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text; ((TMP_Text)val2).fontSize = fontSize; ((Graphic)val2).color = Color.white; ((TMP_Text)val2).alignment = (TextAlignmentOptions)4097; if ((Object)(object)cachedFont != (Object)null) { ((TMP_Text)val2).font = cachedFont; } LayoutElement obj = val.AddComponent(); obj.flexibleWidth = flexWidth; obj.minWidth = minWidth; obj.minHeight = 26f; return val2; } }