Decompiled source of FilteredBros v2.0.1

UMM/Mods/FilteredBros/FilteredBros.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using HarmonyLib;
using RocketLib;
using RocketLib.Collections;
using UnityEngine;
using UnityModManagerNet;
using World.LevelEdit;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("FilteredBros")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FilteredBros")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("45354712-869e-4445-8ff5-929a9daffc1c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FilteredBros
{
	public enum BroGroup
	{
		Campaign,
		Expendabros,
		Unused,
		Customs
	}
	public class BroToggle
	{
		private static List<BroToggle> _all;

		public static List<BroToggle> Broforce;

		public static List<BroToggle> Expendabros;

		public static List<BroToggle> Secret;

		public static List<BroToggle> Customs;

		public readonly HeroType heroType;

		public readonly int unlockNumber;

		public readonly BroGroup group;

		public bool enabled;

		private bool _lastValue;

		public static List<BroToggle> All
		{
			get
			{
				if (_all == null)
				{
					_all = new List<BroToggle>(Broforce);
					_all.AddRange(Expendabros);
					_all.AddRange(Secret);
				}
				return _all;
			}
		}

		public static int BrosEnabled { get; private set; }

		public string Name { get; private set; }

		static BroToggle()
		{
			_all = null;
			Broforce = new List<BroToggle>();
			Expendabros = new List<BroToggle>();
			Secret = new List<BroToggle>();
			Customs = new List<BroToggle>();
			BrosEnabled = 0;
			Broforce = new List<BroToggle>();
			Expendabros = new List<BroToggle>();
			Secret = new List<BroToggle>();
		}

		public BroToggle(HeroType heroType, int unlockNumber, BroGroup group)
		{
			//IL_0007: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			this.heroType = heroType;
			this.unlockNumber = unlockNumber;
			this.group = group;
			if (this.group == BroGroup.Campaign)
			{
				Broforce.Add(this);
			}
			else if (this.group == BroGroup.Expendabros)
			{
				Expendabros.Add(this);
			}
			else if (this.group == BroGroup.Unused)
			{
				Secret.Add(this);
			}
			Name = HeroController.GetHeroName(this.heroType);
		}

		public override string ToString()
		{
			return Name;
		}

		public void DrawToggle()
		{
			if (IsBroUnlocked())
			{
				enabled = GUILayout.Toggle(enabled, ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width((float)Main.settings.ui.toggleWidth) });
			}
			else
			{
				enabled = GUILayout.Toggle(true, "<color=\"gray\">???</color>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width((float)Main.settings.ui.toggleWidth) });
			}
			if (_lastValue != enabled)
			{
				Mod.ShouldUpdateUnlockIntervals = true;
				if (_lastValue)
				{
					BrosEnabled--;
				}
				else
				{
					BrosEnabled++;
				}
			}
			_lastValue = enabled;
		}

		public bool IsBroUnlocked()
		{
			if (group == BroGroup.Campaign && unlockNumber > PlayerProgress.Instance.freedBros)
			{
				return Main.cheat;
			}
			return true;
		}
	}
	public static class Main
	{
		public static ModEntry mod;

		public static bool enabled;

		public static Settings settings;

		public static bool cheat;

		private static bool Load(ModEntry modEntry)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			modEntry.OnGUI = ModUI.OnGUI;
			modEntry.OnSaveGUI = OnSaveGUI;
			modEntry.OnToggle = OnToggle;
			settings = ModSettings.Load<Settings>(modEntry);
			mod = modEntry;
			Harmony val = new Harmony(modEntry.Info.Id);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			val.PatchAll(executingAssembly);
			Mod.Start();
			cheat = Environment.UserName == "Gorzon";
			return true;
		}

		private static void OnSaveGUI(ModEntry modEntry)
		{
			List<bool> list = new List<bool>();
			foreach (BroToggle item in BroToggle.All)
			{
				list.Add(item.enabled);
			}
			settings.brosEnable = list;
			((ModSettings)settings).Save(modEntry);
		}

		private static bool OnToggle(ModEntry modEntry, bool value)
		{
			enabled = value;
			return true;
		}

		public static void Log(object msg)
		{
			mod.Logger.Log(msg.ToString());
		}
	}
	public class Mod
	{
		private static bool _shouldUpdateUnlockIntervals = false;

		private static int _intervalMax = -1;

		public static bool CanUsePatch
		{
			get
			{
				if (Main.enabled)
				{
					if (LevelSelectionController.IsCustomCampaign() && !LevelEditorGUI.IsActive && !Map.isEditing)
					{
						return Main.settings.mod.patchInCustomsLevel;
					}
					return true;
				}
				return false;
			}
		}

		public static Settings Settings => Main.settings;

		public static bool ShouldUpdateUnlockIntervals
		{
			get
			{
				if (!IEnumerableExtensions.IsNullOrEmpty<KeyValuePair<int, HeroType>>((IEnumerable<KeyValuePair<int, HeroType>>)CurrentUnlockIntervals))
				{
					return _shouldUpdateUnlockIntervals;
				}
				return true;
			}
			set
			{
				_shouldUpdateUnlockIntervals = value;
			}
		}

		public static Dictionary<int, HeroType> OriginalUnlockIntervals { get; } = Heroes.OriginalUnlockIntervals;


		public static Dictionary<int, HeroType> CurrentUnlockIntervals { get; private set; }

		internal static void Start()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			new GamePassword("iaminthematrix", (Action)IAmInTheMatrix);
			List<HeroType> list = Heroes.CampaignBro.ToList();
			list.Remove((HeroType)10);
			CreateBroToggles(list, BroGroup.Campaign);
			CreateBroToggles(Heroes.Expendabros.ToList(), BroGroup.Expendabros);
			List<HeroType> list2 = Heroes.Unused.ToList();
			list2.Remove((HeroType)500);
			CreateBroToggles(list2, BroGroup.Unused);
			if (BroToggle.All == null || Settings.brosEnable == null)
			{
				return;
			}
			for (int i = 0; i < Settings.brosEnable.Count; i++)
			{
				if (i < BroToggle.All.Count && BroToggle.All[i] != null)
				{
					BroToggle.All[i].enabled = Settings.brosEnable[i];
				}
			}
		}

		private static void CreateBroToggles(List<HeroType> heroArray, BroGroup group)
		{
			//IL_0031: 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)
			//IL_0043: 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)
			if (_intervalMax == -1)
			{
				_intervalMax = OriginalUnlockIntervals.Last().Key;
			}
			foreach (HeroType hero in heroArray)
			{
				int num = -1;
				new BroToggle(unlockNumber: (!OriginalUnlockIntervals.ContainsValue(hero)) ? (_intervalMax += 10) : OriginalUnlockIntervals.First((KeyValuePair<int, HeroType> x) => x.Value == hero).Key, heroType: hero, group: group);
			}
		}

		public static void UpdateCurrentUnlockIntervals()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (CurrentUnlockIntervals == null)
			{
				CurrentUnlockIntervals = new Dictionary<int, HeroType>();
			}
			if (IEnumerableExtensions.IsNullOrEmpty<BroToggle>((IEnumerable<BroToggle>)BroToggle.All))
			{
				Main.Log("[UpdateCurrentUnlockIntervals] There is no BroToggle. Can't update dictionary.");
				return;
			}
			CurrentUnlockIntervals.Clear();
			foreach (BroToggle item in BroToggle.All)
			{
				if (item != null && item.enabled)
				{
					CurrentUnlockIntervals.Add(item.unlockNumber, item.heroType);
				}
			}
			ShouldUpdateUnlockIntervals = false;
		}

		private static void IAmInTheMatrix()
		{
			Main.cheat = true;
		}
	}
	public static class ModUI
	{
		public static int boxHeight = 135;

		public static int spaceBetweenGroups = 20;

		public static int maxWidth = 0;

		private static string _search = string.Empty;

		private static FuzzySearcher<BroToggle> _fuzzySearcher = new FuzzySearcher<BroToggle>();

		private static List<BroToggle> _campaignBroFiltered = null;

		private static List<BroToggle> _expendaBroFiltered = null;

		private static List<BroToggle> _hideBroFiltered = null;

		internal static void OnGUI(ModEntry modEntry)
		{
			if (_fuzzySearcher == null)
			{
				_fuzzySearcher = new FuzzySearcher<BroToggle>();
			}
			if (maxWidth < 1)
			{
				maxWidth = 940;
			}
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)maxWidth) });
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height((float)boxHeight),
				GUILayout.ExpandWidth(false)
			});
			Extensions.Draw<ModSettings>(Main.settings.mod, modEntry);
			GUILayout.EndVertical();
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height((float)boxHeight),
				GUILayout.ExpandWidth(false)
			});
			Extensions.Draw<UISettings>(Main.settings.ui, modEntry);
			GUILayout.EndVertical();
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height((float)boxHeight) });
			GUILayout.Label("Informations", UI.bold, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.Label("Number of Freed Bros: " + PlayerProgress.Instance.freedBros, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			int numberOfRescuesToNextUnlock = HeroUnlockController.GetNumberOfRescuesToNextUnlock();
			if (numberOfRescuesToNextUnlock != -1)
			{
				GUILayout.Label($"Next unlock in {numberOfRescuesToNextUnlock} saves", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			else
			{
				GUILayout.Label("Every Bros have been unlocked!", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			GUILayout.Label("Number of bro select : " + BroToggle.BrosEnabled, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.EndVertical();
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.Label("Search", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			_search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
			GUILayout.EndHorizontal();
			_campaignBroFiltered = _fuzzySearcher.FuzzySearch(BroToggle.Broforce, _search);
			DrawToggleGroup("Broforce", _campaignBroFiltered, UI.bold);
			GUILayout.Space((float)spaceBetweenGroups);
			_expendaBroFiltered = _fuzzySearcher.FuzzySearch(BroToggle.Expendabros, _search);
			DrawToggleGroup("Expendabros", _expendaBroFiltered, UI.bold);
			GUILayout.Space((float)spaceBetweenGroups);
			_hideBroFiltered = _fuzzySearcher.FuzzySearch(BroToggle.Secret, _search);
			DrawToggleGroup("Unused", _hideBroFiltered, UI.bold);
			GUILayout.Space((float)spaceBetweenGroups);
		}

		private static void DrawToggleGroup(string groupeName, List<BroToggle> broToggles, GUIStyle nameStyle)
		{
			GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.Label(groupeName, nameStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.EndHorizontal();
			if (broToggles == null)
			{
				GUILayout.Label("Filtered Bros encountered an error :(", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				return;
			}
			if (broToggles.Count == 0)
			{
				GUILayout.Label("No Bros Founded", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				return;
			}
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (GUILayout.Button("Select All", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				Select(broToggles, enable: true);
			}
			if (GUILayout.Button("Select Nothing", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }))
			{
				Select(broToggles, enable: false);
			}
			GUILayout.EndHorizontal();
			int num = 0;
			bool flag = false;
			foreach (BroToggle broToggle in broToggles)
			{
				if (num == 0)
				{
					GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
					flag = true;
				}
				broToggle.DrawToggle();
				GUILayout.Space(10f);
				num++;
				if (num == Main.settings.ui.numberOfBroPerLine)
				{
					num = 0;
					GUILayout.EndHorizontal();
					flag = false;
				}
			}
			if (flag)
			{
				GUILayout.EndHorizontal();
			}
		}

		private static void Select(List<BroToggle> list, bool enable)
		{
			foreach (BroToggle item in list)
			{
				item.enabled = enable;
			}
		}
	}
	public class Settings : ModSettings
	{
		public UISettings ui = new UISettings();

		public ModSettings mod = new ModSettings();

		public List<bool> brosEnable;

		public override void Save(ModEntry modEntry)
		{
			ModSettings.Save<Settings>(this, modEntry);
		}
	}
	[DrawFields(/*Could not decode attribute arguments.*/)]
	public class UISettings : IDrawable
	{
		[Header("UI Settings")]
		[Draw(/*Could not decode attribute arguments.*/)]
		public int numberOfBroPerLine = 6;

		[Draw(/*Could not decode attribute arguments.*/)]
		public int toggleWidth = 128;

		public void OnChange()
		{
		}
	}
	[DrawFields(/*Could not decode attribute arguments.*/)]
	public class ModSettings : IDrawable
	{
		[Header("Mod Settings")]
		[Draw(/*Could not decode attribute arguments.*/)]
		public bool patchInCustomsLevel;

		[Draw(/*Could not decode attribute arguments.*/)]
		public bool useInLevelEditor;

		[Draw(/*Could not decode attribute arguments.*/)]
		public bool ignoreForcedBros;

		[Draw(/*Could not decode attribute arguments.*/)]
		public int maxLifeNumber;

		public void OnChange()
		{
		}
	}
}
namespace FilteredBros.Patches
{
	[HarmonyPatch(typeof(PlayerProgress))]
	public static class PlayerProgressP
	{
		[HarmonyPatch("PostLoadProcess")]
		[HarmonyPrefix]
		private static bool PostLoadProcess(PlayerProgress __instance)
		{
			return !Mod.CanUsePatch;
		}

		[HarmonyPatch("IsHeroUnlocked")]
		[HarmonyPrefix]
		private static void IsHeroUnlocked(PlayerProgress __instance)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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)
			if (!Mod.CanUsePatch || !Mod.ShouldUpdateUnlockIntervals)
			{
				return;
			}
			Mod.UpdateCurrentUnlockIntervals();
			if (Mod.CurrentUnlockIntervals == null || Mod.CurrentUnlockIntervals.Count < 0)
			{
				Main.Log("You have selected 0 bro, please select at least one. (The one who are name \"???\" don't count)");
				__instance.unlockedHeroes = Mod.OriginalUnlockIntervals.Values.ToList();
				Mod.ShouldUpdateUnlockIntervals = false;
				return;
			}
			Traverse.Create(typeof(HeroUnlockController)).Field("_heroUnlockIntervals").SetValue((object)Mod.CurrentUnlockIntervals);
			__instance.unlockedHeroes.Clear();
			foreach (HeroType value in Mod.CurrentUnlockIntervals.Values)
			{
				__instance.unlockedHeroes.Add(value);
			}
			HeroType[] array = __instance.yetToBePlayedUnlockedHeroes.ToArray();
			HeroType[] array2 = array;
			foreach (HeroType val in array2)
			{
				if (!Mod.CurrentUnlockIntervals.ContainsValue(val))
				{
					__instance.yetToBePlayedUnlockedHeroes.Remove(val);
				}
			}
			Mod.ShouldUpdateUnlockIntervals = false;
		}
	}
	[HarmonyPatch(typeof(LevelEditorGUI))]
	public static class LevelEditorP
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start(LevelEditorGUI __instance)
		{
			if (!Main.enabled || !Main.settings.mod.useInLevelEditor)
			{
				LevelEditorGUI.broChangeHeroTypes = Mod.OriginalUnlockIntervals.Values.ToList();
				HarmonyExtensions.SetFieldValue<List<HeroType>>((object)__instance, "heroTypes", LevelEditorGUI.broChangeHeroTypes);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "AddLife")]
	internal static class LifeNumberLimited_Patch
	{
		private static void Postfix(Player __instance)
		{
			if (Mod.CanUsePatch && Main.settings.mod.maxLifeNumber > 0 && __instance.Lives > Main.settings.mod.maxLifeNumber)
			{
				__instance.Lives = Main.settings.mod.maxLifeNumber;
			}
		}
	}
	[HarmonyPatch(typeof(MapData), "Deserialize")]
	internal static class MapData_Deserialize_Patch
	{
		private static void Postfix(MapData __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (Mod.CanUsePatch && Main.settings.mod.ignoreForcedBros)
			{
				__instance.forcedBro = (HeroType)1000;
				__instance.forcedBros = new List<HeroType>();
			}
		}
	}
}