Decompiled source of RealerStageTweaker v1.0.1

RealerStageTweaker.dll

Decompiled 3 hours ago
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 System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using On.RoR2;
using On.RoR2.UI.MainMenu;
using R2API;
using R2API.AddressReferencedAssets;
using RoR2;
using RoR2.ExpansionManagement;
using RoR2.Networking;
using RoR2.UI;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RealerStageTweaker")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ea7a57ac5190360172084d86053441cddf8f29a2")]
[assembly: AssemblyProduct("RealerStageTweaker")]
[assembly: AssemblyTitle("RealerStageTweaker")]
[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 RealerStageTweaker
{
	public class Apply
	{
		public static Dictionary<string, ConditionalPoolEntry> Families = new Dictionary<string, ConditionalPoolEntry>();

		public static void Monster(ClassicStageInfo csi, Dictionary<string, float> monsters, Dictionary<string, float> monstersLoop)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_005d: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Unknown result type (might be due to invalid IL or missing references)
			//IL_0606: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			Main.Log.LogInfo((object)"Patching Monsters");
			Category category = GetCategory(csi.monsterDccsPool);
			PoolEntry val = GetEntry(csi.monsterDccsPool);
			if (val == null)
			{
				val = new PoolEntry
				{
					dccs = ScriptableObject.CreateInstance<DirectorCardCategorySelection>(),
					weight = 1f
				};
			}
			ConditionalPoolEntry val2 = (ConditionalPoolEntry)(object)((val is ConditionalPoolEntry) ? val : null);
			if (val2 != null)
			{
				val2.requiredExpansions = Array.Empty<ExpansionDef>();
			}
			List<PoolEntry> list4 = new List<PoolEntry>();
			list4.AddRange(category.alwaysIncluded.Where((PoolEntry x) => x.dccs is FamilyDirectorCardCategorySelection));
			list4.Add(val);
			category.alwaysIncluded = list4.ToArray();
			category.includedIfConditionsMet = category.includedIfConditionsMet.Where((ConditionalPoolEntry x) => ((PoolEntry)x).dccs is FamilyDirectorCardCategorySelection).ToArray();
			category.includedIfNoConditionsMet = category.includedIfNoConditionsMet.Where((PoolEntry x) => x.dccs is FamilyDirectorCardCategorySelection).ToArray();
			for (int i = 0; i < val.dccs.categories.Length; i++)
			{
				Category val3 = val.dccs.categories[i];
				List<DirectorCard> list5 = new List<DirectorCard>();
				DirectorCard[] cards = val3.cards;
				foreach (DirectorCard val4 in cards)
				{
					SpawnCard spawnCard = val4.spawnCard;
					string text = ((spawnCard == null) ? null : ((Object)spawnCard).name?.Replace(",", ""));
					if (string.IsNullOrWhiteSpace(text))
					{
						Main.Log.LogWarning((object)("invalid spawncard at " + ((object)val4)?.ToString() + "!"));
						continue;
					}
					bool flag = false;
					float value = 0f;
					if (monstersLoop.TryGetValue(text, out value))
					{
						flag = true;
					}
					else if (!monsters.TryGetValue(text, out value) || value <= 0f)
					{
						list.Add(text);
						continue;
					}
					bool flag2 = false;
					bool flag3 = val4.minimumStageCompletions == 0;
					if (flag3 != flag)
					{
						flag2 = true;
					}
					val4.minimumStageCompletions = (flag ? 5 : 0);
					if ((float)val4.selectionWeight != value)
					{
						flag2 = true;
						val4.selectionWeight = (int)value;
					}
					if (flag2)
					{
						list2.Add(text);
					}
					list5.Add(val4);
					monsters.Remove(text);
					monstersLoop.Remove(text);
				}
				string[] array = monstersLoop.Keys.ToArray();
				foreach (string text2 in array)
				{
					if (SavedConfig.Category[text2] == val3.name)
					{
						list5.Add(MakeDirectorCard(text2, (SpawnCard)(object)Main.Enemies[text2], monstersLoop[text2], isLoop: true));
						list3.Add(text2);
						monsters.Remove(text2);
						monstersLoop.Remove(text2);
					}
				}
				string[] array2 = monsters.Keys.ToArray();
				foreach (string text3 in array2)
				{
					if (SavedConfig.Category[text3] == val3.name)
					{
						list5.Add(MakeDirectorCard(text3, (SpawnCard)(object)Main.Enemies[text3], monsters[text3], isLoop: false));
						list3.Add(text3);
						monsters.Remove(text3);
						monstersLoop.Remove(text3);
					}
				}
				val.dccs.categories[i].cards = list5.ToArray();
			}
			while (monstersLoop.Count > 0 || monsters.Count > 0)
			{
				string text4 = SavedConfig.Category[((monstersLoop.Count == 0) ? monsters.First() : monstersLoop.First()).Key];
				Category val5 = default(Category);
				val5.name = text4;
				val5.selectionWeight = SavedConfig.CategoryWeight[text4];
				val5.cards = Array.Empty<DirectorCard>();
				Category val6 = val5;
				List<DirectorCard> list6 = new List<DirectorCard>();
				foreach (string key in monstersLoop.Keys)
				{
					if (SavedConfig.Category[key] == val6.name)
					{
						list6.Add(MakeDirectorCard(key, (SpawnCard)(object)Main.Enemies[key], monstersLoop[key], isLoop: true));
						list3.Add(key);
						monsters.Remove(key);
						monstersLoop.Remove(key);
					}
				}
				foreach (string key2 in monsters.Keys)
				{
					if (SavedConfig.Category[key2] == val6.name)
					{
						list6.Add(MakeDirectorCard(key2, (SpawnCard)(object)Main.Enemies[key2], monsters[key2], isLoop: false));
						list3.Add(key2);
						monsters.Remove(key2);
						monstersLoop.Remove(key2);
					}
				}
				val6.cards = list6.ToArray();
				DirectorCardCategorySelection dccs = val.dccs;
				Category[] categories = val.dccs.categories;
				int num = 0;
				Category[] array3 = (Category[])(object)new Category[1 + categories.Length];
				ReadOnlySpan<Category> readOnlySpan = new ReadOnlySpan<Category>(categories);
				readOnlySpan.CopyTo(new Span<Category>(array3).Slice(num, readOnlySpan.Length));
				num += readOnlySpan.Length;
				array3[num] = val6;
				num++;
				dccs.categories = array3;
			}
			Main.Log.LogInfo((object)$"Added {list3.Count} ({Setup.JoinAndOrderBy(list3)}), Changed {list2.Count} ({Setup.JoinAndOrderBy(list2)}), Removed {list.Count} ({Setup.JoinAndOrderBy(list)}) monsters");
		}

		public static void Family(ClassicStageInfo csi, List<string> families)
		{
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			Main.Log.LogInfo((object)"Patching Families");
			Category val = null;
			int num = 0;
			Category[] poolCategories = csi.monsterDccsPool.poolCategories;
			foreach (Category val2 in poolCategories)
			{
				if (val2.name == "Families" || val2.name == "Family")
				{
					val = val2;
					num = int.MaxValue;
				}
				bool flag = val2.includedIfConditionsMet.Any(Setup.HasDLC);
				PoolEntry[] families2 = GetFamilies(val2);
				if (families2.Length > num)
				{
					val = val2;
					num = families2.Length;
				}
				IEnumerable<PoolEntry> contains = families2.Where((PoolEntry x) => families.Contains(((FamilyDirectorCardCategorySelection)x.dccs).selectionChatString.Replace(",", "")));
				list.AddRange(families2.Select((PoolEntry x) => ((FamilyDirectorCardCategorySelection)x.dccs).selectionChatString.Replace(",", "")).Except(contains.Select((PoolEntry x) => ((FamilyDirectorCardCategorySelection)x.dccs).selectionChatString.Replace(",", ""))));
				List<PoolEntry> list3 = new List<PoolEntry>();
				list3.AddRange(val2.alwaysIncluded.Where((PoolEntry x) => !(x.dccs is FamilyDirectorCardCategorySelection) || contains.Contains(x)));
				val2.alwaysIncluded = list3.ToArray();
				List<ConditionalPoolEntry> list4 = new List<ConditionalPoolEntry>();
				list4.AddRange(val2.includedIfConditionsMet.Where((ConditionalPoolEntry x) => !(((PoolEntry)x).dccs is FamilyDirectorCardCategorySelection) || contains.Contains((PoolEntry)(object)x)));
				val2.includedIfConditionsMet = list4.ToArray();
				List<PoolEntry> list5 = new List<PoolEntry>();
				list5.AddRange(val2.includedIfNoConditionsMet.Where((PoolEntry x) => !(x.dccs is FamilyDirectorCardCategorySelection) || contains.Contains(x)));
				val2.includedIfNoConditionsMet = list5.ToArray();
				families.RemoveAll(contains.Select((PoolEntry x) => ((FamilyDirectorCardCategorySelection)x.dccs).selectionChatString.Replace(",", "")).Contains<string>);
			}
			if (val == null)
			{
				val = new Category
				{
					categoryWeight = ClassicStageInfo.monsterFamilyChance,
					name = "Family"
				};
				DccsPool monsterDccsPool = csi.monsterDccsPool;
				Category[] poolCategories2 = csi.monsterDccsPool.poolCategories;
				int num2 = 0;
				Category[] array = (Category[])(object)new Category[1 + poolCategories2.Length];
				ReadOnlySpan<Category> readOnlySpan = new ReadOnlySpan<Category>(poolCategories2);
				readOnlySpan.CopyTo(new Span<Category>(array).Slice(num2, readOnlySpan.Length));
				num2 += readOnlySpan.Length;
				array[num2] = val;
				num2++;
				monsterDccsPool.poolCategories = array;
			}
			List<ConditionalPoolEntry> list6 = new List<ConditionalPoolEntry>();
			foreach (string family in families)
			{
				if (Families.TryGetValue(family, out var value))
				{
					list6.Add(value);
					continue;
				}
				FamilyDirectorCardCategorySelection val3 = ScriptableObject.CreateInstance<FamilyDirectorCardCategorySelection>();
				((Object)val3).name = "dccs" + Setup.ToTitleCase(family);
				val3.selectionChatString = family;
				val3.minimumStageCompletion = 0;
				val3.maximumStageCompletion = int.MaxValue;
				((DirectorCardCategorySelection)val3).categories = SavedConfig.Families[family].Select(delegate(string x)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Unknown result type (might be due to invalid IL or missing references)
					Category result = default(Category);
					result.name = SavedConfig.Category[x];
					result.selectionWeight = SavedConfig.CategoryWeight[SavedConfig.Category[x]];
					result.cards = (DirectorCard[])(object)new DirectorCard[1] { MakeDirectorCard(x, (SpawnCard)(object)Main.Enemies[x], 1f, isLoop: false) };
					return result;
				}).ToArray();
				ConditionalPoolEntry val4 = new ConditionalPoolEntry
				{
					dccs = (DirectorCardCategorySelection)(object)val3,
					requiredExpansions = Array.Empty<ExpansionDef>(),
					weight = 1f
				};
				Families.Add(family, val4);
				list6.Add(val4);
			}
			Category val5 = val;
			ConditionalPoolEntry[] includedIfConditionsMet = val.includedIfConditionsMet;
			List<ConditionalPoolEntry> list7 = list6;
			int num3 = 0;
			ConditionalPoolEntry[] array2 = (ConditionalPoolEntry[])(object)new ConditionalPoolEntry[includedIfConditionsMet.Length + list7.Count];
			ReadOnlySpan<ConditionalPoolEntry> readOnlySpan2 = new ReadOnlySpan<ConditionalPoolEntry>(includedIfConditionsMet);
			readOnlySpan2.CopyTo(new Span<ConditionalPoolEntry>(array2).Slice(num3, readOnlySpan2.Length));
			num3 += readOnlySpan2.Length;
			foreach (ConditionalPoolEntry item in list7)
			{
				array2[num3] = item;
				num3++;
			}
			val5.includedIfConditionsMet = array2;
			Main.Log.LogInfo((object)$"Added {families.Count} ({Setup.JoinAndOrderBy(families)}), Removed {list.Count} ({Setup.JoinAndOrderBy(list)}) family events");
		}

		public static PoolEntry[] GetFamilies(Category category)
		{
			bool flag = category.includedIfConditionsMet.Any(Setup.HasDLC);
			List<PoolEntry> list = new List<PoolEntry>();
			list.AddRange(category.alwaysIncluded.Where((PoolEntry x) => x.dccs is FamilyDirectorCardCategorySelection));
			PoolEntry[] source;
			if (!flag)
			{
				source = category.includedIfNoConditionsMet;
			}
			else
			{
				PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)category.includedIfConditionsMet;
				source = includedIfConditionsMet;
			}
			list.AddRange(source.Where((PoolEntry x) => x.dccs is FamilyDirectorCardCategorySelection));
			return list.ToArray();
		}

		public static void Interactable(ClassicStageInfo csi, Dictionary<string, float> interactables)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_005d: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			Main.Log.LogInfo((object)"Patching Interactables");
			Category category = GetCategory(csi.interactableDccsPool);
			PoolEntry val = GetEntry(csi.interactableDccsPool);
			if (val == null)
			{
				val = new PoolEntry
				{
					dccs = ScriptableObject.CreateInstance<DirectorCardCategorySelection>(),
					weight = 1f
				};
			}
			ConditionalPoolEntry val2 = (ConditionalPoolEntry)(object)((val is ConditionalPoolEntry) ? val : null);
			if (val2 != null)
			{
				val2.requiredExpansions = Array.Empty<ExpansionDef>();
			}
			category.alwaysIncluded = (PoolEntry[])(object)new PoolEntry[1] { val };
			category.includedIfConditionsMet = Array.Empty<ConditionalPoolEntry>();
			category.includedIfNoConditionsMet = Array.Empty<PoolEntry>();
			for (int i = 0; i < val.dccs.categories.Length; i++)
			{
				Category val3 = val.dccs.categories[i];
				List<DirectorCard> list4 = new List<DirectorCard>();
				DirectorCard[] cards = val3.cards;
				foreach (DirectorCard val4 in cards)
				{
					SpawnCard spawnCard = val4.spawnCard;
					string text = ((spawnCard == null) ? null : ((Object)spawnCard).name?.Replace(",", ""));
					if (string.IsNullOrWhiteSpace(text))
					{
						Main.Log.LogWarning((object)("invalid spawncard at " + ((object)val4)?.ToString() + "!"));
					}
					else
					{
						if (text == "iscShockDrone")
						{
							continue;
						}
						float value = 0f;
						if (!interactables.TryGetValue(text, out value) || value <= 0f)
						{
							list.Add(text);
							continue;
						}
						if ((float)val4.selectionWeight != value)
						{
							list2.Add(text);
							val4.selectionWeight = (int)value;
						}
						list4.Add(val4);
						interactables.Remove(text);
					}
				}
				string[] array = interactables.Keys.ToArray();
				foreach (string text2 in array)
				{
					if (SavedConfig.Category[text2] == val3.name)
					{
						list4.Add(MakeDirectorCard(text2, (SpawnCard)(object)Main.Interactables[text2], interactables[text2], isLoop: false));
						list3.Add(text2);
						interactables.Remove(text2);
					}
				}
				val.dccs.categories[i].cards = list4.ToArray();
			}
			while (interactables.Count > 0)
			{
				string text3 = SavedConfig.Category[interactables.First().Key];
				Category val5 = default(Category);
				val5.name = text3;
				val5.selectionWeight = SavedConfig.CategoryWeight[text3];
				val5.cards = Array.Empty<DirectorCard>();
				Category val6 = val5;
				List<DirectorCard> list5 = new List<DirectorCard>();
				string[] array2 = interactables.Keys.ToArray();
				foreach (string text4 in array2)
				{
					if (SavedConfig.Category[text4] == val6.name)
					{
						list5.Add(MakeDirectorCard(text4, (SpawnCard)(object)Main.Interactables[text4], interactables[text4], isLoop: false));
						list3.Add(text4);
						interactables.Remove(text4);
					}
				}
				val6.cards = list5.ToArray();
				DirectorCardCategorySelection dccs = val.dccs;
				Category[] categories = val.dccs.categories;
				int num = 0;
				Category[] array3 = (Category[])(object)new Category[1 + categories.Length];
				ReadOnlySpan<Category> readOnlySpan = new ReadOnlySpan<Category>(categories);
				readOnlySpan.CopyTo(new Span<Category>(array3).Slice(num, readOnlySpan.Length));
				num += readOnlySpan.Length;
				array3[num] = val6;
				num++;
				dccs.categories = array3;
			}
			Main.Log.LogInfo((object)$"Added {list3.Count} ({Setup.JoinAndOrderBy(list3)}), Changed {list2.Count} ({Setup.JoinAndOrderBy(list2)}), Removed {list.Count} ({Setup.JoinAndOrderBy(list)}) interactables");
		}

		public static void _Finalize(ClassicStageInfo self)
		{
			Category[] poolCategories = self.monsterDccsPool.poolCategories;
			foreach (Category val in poolCategories)
			{
				PoolEntry[] alwaysIncluded = val.alwaysIncluded;
				foreach (PoolEntry val2 in alwaysIncluded)
				{
					val2.dccs.categories = val2.dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val.alwaysIncluded = val.alwaysIncluded.Where((PoolEntry x) => x.weight > 0f && x.dccs.categories.Length != 0).ToArray();
				ConditionalPoolEntry[] includedIfConditionsMet = val.includedIfConditionsMet;
				foreach (ConditionalPoolEntry val3 in includedIfConditionsMet)
				{
					((PoolEntry)val3).dccs.categories = ((PoolEntry)val3).dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val.includedIfConditionsMet = val.includedIfConditionsMet.Where((ConditionalPoolEntry x) => ((PoolEntry)x).weight > 0f && ((PoolEntry)x).dccs.categories.Length != 0).ToArray();
				PoolEntry[] includedIfNoConditionsMet = val.includedIfNoConditionsMet;
				foreach (PoolEntry val4 in includedIfNoConditionsMet)
				{
					val4.dccs.categories = val4.dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val.includedIfNoConditionsMet = val.includedIfNoConditionsMet.Where((PoolEntry x) => x.weight > 0f && x.dccs.categories.Length != 0).ToArray();
			}
			self.monsterDccsPool.poolCategories = self.monsterDccsPool.poolCategories.Where((Category x) => x.categoryWeight > 0f && x.alwaysIncluded.Length + x.includedIfConditionsMet.Length + x.includedIfNoConditionsMet.Length > 0).ToArray();
			Category[] poolCategories2 = self.interactableDccsPool.poolCategories;
			foreach (Category val5 in poolCategories2)
			{
				PoolEntry[] alwaysIncluded2 = val5.alwaysIncluded;
				foreach (PoolEntry val6 in alwaysIncluded2)
				{
					val6.dccs.categories = val6.dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val5.alwaysIncluded = val5.alwaysIncluded.Where((PoolEntry x) => x.weight > 0f && x.dccs.categories.Length != 0).ToArray();
				ConditionalPoolEntry[] includedIfConditionsMet2 = val5.includedIfConditionsMet;
				foreach (ConditionalPoolEntry val7 in includedIfConditionsMet2)
				{
					((PoolEntry)val7).dccs.categories = ((PoolEntry)val7).dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val5.includedIfConditionsMet = val5.includedIfConditionsMet.Where((ConditionalPoolEntry x) => ((PoolEntry)x).weight > 0f && ((PoolEntry)x).dccs.categories.Length != 0).ToArray();
				PoolEntry[] includedIfNoConditionsMet2 = val5.includedIfNoConditionsMet;
				foreach (PoolEntry val8 in includedIfNoConditionsMet2)
				{
					val8.dccs.categories = val8.dccs.categories.Where((Category x) => x.selectionWeight > 0f && x.cards.Count() > 0).ToArray();
				}
				val5.includedIfNoConditionsMet = val5.includedIfNoConditionsMet.Where((PoolEntry x) => x.weight > 0f && x.dccs.categories.Length != 0).ToArray();
			}
			self.interactableDccsPool.poolCategories = self.interactableDccsPool.poolCategories.Where((Category x) => x.categoryWeight > 0f && x.alwaysIncluded.Length + x.includedIfConditionsMet.Length + x.includedIfNoConditionsMet.Length > 0).ToArray();
			if (self.monsterDccsPool.poolCategories.Length == 0)
			{
				Main.Log.LogWarning((object)"Monster pool is empty! did you empty the entire list??");
			}
			if (self.interactableDccsPool.poolCategories.Length == 0)
			{
				Main.Log.LogWarning((object)"Interactable pool is empty! did you empty the entire list??");
			}
			Main.Log.LogInfo((object)"Patch Completed!");
		}

		public static DirectorCard MakeDirectorCard(string name, SpawnCard sc, float weight, bool isLoop)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			return new DirectorCard
			{
				spawnCard = sc,
				selectionWeight = (int)weight,
				minimumStageCompletions = (isLoop ? 5 : 0),
				spawnDistance = (MonsterSpawnDistance)SavedConfig.SpawnDistance[name],
				preventOverhead = SavedConfig.PreventOverhead[name]
			};
		}

		public static PoolEntry GetEntry(DccsPool dp)
		{
			return GetEntry(dp, Setup.GetMainDCCS(dp));
		}

		public static PoolEntry GetEntry(DccsPool dp, DirectorCardCategorySelection dccs)
		{
			Category[] poolCategories = dp.poolCategories;
			foreach (Category val in poolCategories)
			{
				PoolEntry[] alwaysIncluded = val.alwaysIncluded;
				foreach (PoolEntry val2 in alwaysIncluded)
				{
					if ((Object)(object)val2.dccs == (Object)(object)dccs)
					{
						return val2;
					}
				}
				ConditionalPoolEntry[] includedIfConditionsMet = val.includedIfConditionsMet;
				foreach (ConditionalPoolEntry val3 in includedIfConditionsMet)
				{
					if ((Object)(object)((PoolEntry)val3).dccs == (Object)(object)dccs)
					{
						return (PoolEntry)(object)val3;
					}
				}
				PoolEntry[] includedIfNoConditionsMet = val.includedIfNoConditionsMet;
				foreach (PoolEntry val4 in includedIfNoConditionsMet)
				{
					if ((Object)(object)val4.dccs == (Object)(object)dccs)
					{
						return val4;
					}
				}
			}
			return null;
		}

		public static Category GetCategory(DccsPool dp)
		{
			return GetCategory(dp, Setup.GetMainDCCS(dp));
		}

		public static Category GetCategory(DccsPool dp, PoolEntry entry)
		{
			Category[] poolCategories = dp.poolCategories;
			foreach (Category val in poolCategories)
			{
				if (val.alwaysIncluded.Contains(entry) || ((IEnumerable<PoolEntry>)(object)val.includedIfConditionsMet).Contains(entry) || val.includedIfNoConditionsMet.Contains(entry))
				{
					return val;
				}
			}
			return null;
		}

		public static Category GetCategory(DccsPool dp, DirectorCardCategorySelection dccs)
		{
			Category[] poolCategories = dp.poolCategories;
			foreach (Category val in poolCategories)
			{
				if (val.alwaysIncluded.Any((PoolEntry x) => (Object)(object)x.dccs == (Object)(object)dccs) || val.includedIfConditionsMet.Any((ConditionalPoolEntry x) => (Object)(object)((PoolEntry)x).dccs == (Object)(object)dccs) || val.includedIfNoConditionsMet.Any((PoolEntry x) => (Object)(object)x.dccs == (Object)(object)dccs))
				{
					return val;
				}
			}
			return null;
		}

		public static bool TryFirst<T>(IEnumerable<T> arr, Func<T, bool> fn, out T ret)
		{
			ret = default(T);
			foreach (T item in arr)
			{
				if (fn(item))
				{
					ret = item;
					return true;
				}
			}
			return false;
		}
	}
	[BepInPlugin("zzz.prodzpod.RealerStageTweaker", "RealerStageTweaker", "1.0.0")]
	public class Main : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action <>9__14_0;

			public static hook_OnEnter <>9__14_1;

			public static Action <>9__14_2;

			public static hook_RebuildCards <>9__14_3;

			public static Func<string, bool> <>9__14_5;

			public static Func<string, SceneDef> <>9__14_6;

			public static Func<GameObject, bool> <>9__16_3;

			public static Func<Category, bool> <>9__16_4;

			internal void <Awake>b__14_0()
			{
				input = GameObject.Find("MPEventSystem Player0").GetComponent<MPInput>();
			}

			internal void <Awake>b__14_1(orig_OnEnter orig, BaseMainMenuScreen self, MainMenuController mainMenuController)
			{
				//IL_0063: 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)
				orig.Invoke(self, mainMenuController);
				Time.timeScale = 0f;
				MPEventSystem eventSystem = input.eventSystem;
				int cursorOpenerCount = eventSystem.cursorOpenerCount;
				eventSystem.cursorOpenerCount = cursorOpenerCount + 1;
				MPEventSystem eventSystem2 = input.eventSystem;
				cursorOpenerCount = eventSystem2.cursorOpenerForGamepadCount;
				eventSystem2.cursorOpenerForGamepadCount = cursorOpenerCount + 1;
				box = SimpleDialogBox.Create((MPEventSystem)null);
				box.headerToken = new TokenParamsPair("Scanning Stages", Array.Empty<object>());
				box.descriptionToken = new TokenParamsPair("Thank you for using Realer Stage Tweaker!\nCollecting stage and enemy data, please wait...", Array.Empty<object>());
				AddressReferencedAsset.LoadReferencesAsync();
			}

			internal void <Awake>b__14_2()
			{
				SavedConfig.GetConfigs();
			}

			internal void <Awake>b__14_3(orig_RebuildCards orig, ClassicStageInfo self, DirectorCardCategorySelection a, DirectorCardCategorySelection b)
			{
				float monsterCredit = SavedConfig.GetMonsterCredit(SceneCatalog.currentSceneDef);
				if (monsterCredit != -1f && (float)self.sceneDirectorMonsterCredits != monsterCredit)
				{
					Log.LogInfo((object)"Patching Monster Credits");
					self.sceneDirectorMonsterCredits = (int)monsterCredit;
				}
				float interactableCredit = SavedConfig.GetInteractableCredit(SceneCatalog.currentSceneDef);
				if (interactableCredit != -1f && (float)self.sceneDirectorInteractibleCredits != interactableCredit)
				{
					Log.LogInfo((object)"Patching Interactable Credits");
					self.sceneDirectorInteractibleCredits = (int)interactableCredit;
				}
				Dictionary<string, float> monster = SavedConfig.GetMonster(SceneCatalog.currentSceneDef);
				Dictionary<string, float> monsterLoop = SavedConfig.GetMonsterLoop(SceneCatalog.currentSceneDef);
				if (monster != null && monsterLoop != null)
				{
					Apply.Monster(self, monster, monsterLoop);
				}
				List<string> family = SavedConfig.GetFamily(SceneCatalog.currentSceneDef);
				if (family != null)
				{
					Apply.Family(self, family);
				}
				Dictionary<string, float> interactable = SavedConfig.GetInteractable(SceneCatalog.currentSceneDef);
				if (interactable != null)
				{
					Apply.Interactable(self, interactable);
				}
				Apply._Finalize(self);
				orig.Invoke(self, a, b);
			}

			internal bool <Awake>b__14_5(string x)
			{
				return !string.IsNullOrWhiteSpace(x);
			}

			internal SceneDef <Awake>b__14_6(string x)
			{
				return SceneCatalog.GetSceneDefFromSceneName(x.Trim());
			}

			internal bool <GenerateConfigs>b__16_3(GameObject x)
			{
				ClassicStageInfo val = default(ClassicStageInfo);
				return x.TryGetComponent<ClassicStageInfo>(ref val);
			}

			internal bool <GenerateConfigs>b__16_4(Category x)
			{
				return x.name == MonsterPoolCategories.Standard;
			}
		}

		public const string PluginGUID = "prodzpod.RealerStageTweaker";

		public const string PluginAuthor = "prodzpod";

		public const string PluginName = "RealerStageTweaker";

		public const string PluginVersion = "1.0.0";

		public static ManualLogSource Log;

		public static PluginInfo pluginInfo;

		public static ConfigFile Config;

		public static MPInput input;

		public static MPButton button;

		public static SimpleDialogBox box;

		public static ConfigEntry<bool> ResetConfig;

		public static ConfigEntry<bool> ResetConfig2;

		public static Dictionary<string, CharacterSpawnCard> Enemies = new Dictionary<string, CharacterSpawnCard>();

		public static Dictionary<string, InteractableSpawnCard> Interactables = new Dictionary<string, InteractableSpawnCard>();

		public void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			pluginInfo = ((BaseUnityPlugin)this).Info;
			Log = ((BaseUnityPlugin)this).Logger;
			Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "prodzpod.RealerStageTweaker.cfg"), true);
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				input = GameObject.Find("MPEventSystem Player0").GetComponent<MPInput>();
			});
			ResetConfig = Config.Bind<bool>("!! General", "Refresh Config", true, "fetches all monster and interactable cards. requires restart.");
			ResetConfig2 = Config.Bind<bool>("!! General", "Reset Config", true, "resets the config.");
			ConfigEntry<string> BlacklistStage1 = Config.Bind<string>("!! General", "Blacklist for Stage 1", "lakesnight, villagenight, habitatfall", "list of stages that should not appear on stage 1. compatibility with the original StageTweaker.");
			if (ResetConfig.Value)
			{
				object obj = <>c.<>9__14_1;
				if (obj == null)
				{
					hook_OnEnter val = delegate(orig_OnEnter orig, BaseMainMenuScreen self, MainMenuController mainMenuController)
					{
						//IL_0063: 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)
						orig.Invoke(self, mainMenuController);
						Time.timeScale = 0f;
						MPEventSystem eventSystem = input.eventSystem;
						int cursorOpenerCount = eventSystem.cursorOpenerCount;
						eventSystem.cursorOpenerCount = cursorOpenerCount + 1;
						MPEventSystem eventSystem2 = input.eventSystem;
						cursorOpenerCount = eventSystem2.cursorOpenerForGamepadCount;
						eventSystem2.cursorOpenerForGamepadCount = cursorOpenerCount + 1;
						box = SimpleDialogBox.Create((MPEventSystem)null);
						box.headerToken = new TokenParamsPair("Scanning Stages", Array.Empty<object>());
						box.descriptionToken = new TokenParamsPair("Thank you for using Realer Stage Tweaker!\nCollecting stage and enemy data, please wait...", Array.Empty<object>());
						AddressReferencedAsset.LoadReferencesAsync();
					};
					<>c.<>9__14_1 = val;
					obj = (object)val;
				}
				BaseMainMenuScreen.OnEnter += (hook_OnEnter)obj;
				return;
			}
			SavedConfig.Load();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				SavedConfig.GetConfigs();
			});
			object obj2 = <>c.<>9__14_3;
			if (obj2 == null)
			{
				hook_RebuildCards val2 = delegate(orig_RebuildCards orig, ClassicStageInfo self, DirectorCardCategorySelection a, DirectorCardCategorySelection b)
				{
					float monsterCredit = SavedConfig.GetMonsterCredit(SceneCatalog.currentSceneDef);
					if (monsterCredit != -1f && (float)self.sceneDirectorMonsterCredits != monsterCredit)
					{
						Log.LogInfo((object)"Patching Monster Credits");
						self.sceneDirectorMonsterCredits = (int)monsterCredit;
					}
					float interactableCredit = SavedConfig.GetInteractableCredit(SceneCatalog.currentSceneDef);
					if (interactableCredit != -1f && (float)self.sceneDirectorInteractibleCredits != interactableCredit)
					{
						Log.LogInfo((object)"Patching Interactable Credits");
						self.sceneDirectorInteractibleCredits = (int)interactableCredit;
					}
					Dictionary<string, float> monster = SavedConfig.GetMonster(SceneCatalog.currentSceneDef);
					Dictionary<string, float> monsterLoop = SavedConfig.GetMonsterLoop(SceneCatalog.currentSceneDef);
					if (monster != null && monsterLoop != null)
					{
						Apply.Monster(self, monster, monsterLoop);
					}
					List<string> family = SavedConfig.GetFamily(SceneCatalog.currentSceneDef);
					if (family != null)
					{
						Apply.Family(self, family);
					}
					Dictionary<string, float> interactable = SavedConfig.GetInteractable(SceneCatalog.currentSceneDef);
					if (interactable != null)
					{
						Apply.Interactable(self, interactable);
					}
					Apply._Finalize(self);
					orig.Invoke(self, a, b);
				};
				<>c.<>9__14_3 = val2;
				obj2 = (object)val2;
			}
			ClassicStageInfo.RebuildCards += (hook_RebuildCards)obj2;
			Run.Start += (hook_Start)delegate(orig_Start orig, Run self)
			{
				IEnumerable<SceneDef> list = from x in BlacklistStage1.Value.Split(',')
					where !string.IsNullOrWhiteSpace(x)
					select SceneCatalog.GetSceneDefFromSceneName(x.Trim());
				SceneEntry[] sceneEntries = self.startingSceneGroup._sceneEntries;
				self.startingSceneGroup._sceneEntries = sceneEntries.Where((SceneEntry x) => !list.Contains(x.sceneDef)).ToArray();
				orig.Invoke(self);
				self.startingSceneGroup._sceneEntries = sceneEntries;
			};
		}

		[SystemInitializer(new Type[] { })]
		public static void SystemInitializer()
		{
			if (ResetConfig.Value)
			{
				AddressReferencedAsset.OnAddressReferencedAssetsLoaded += GenerateConfigs;
			}
		}

		public static void GenerateConfigs()
		{
			//IL_0026: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			if (ResetConfig.Value)
			{
				Log.LogInfo((object)"Deleting Existing Config");
			}
			DirectorAPI.InitCustomMixEnemyArtifactDccs();
			Enumerator<SceneDef> enumerator = SceneCatalog.allStageSceneDefs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					SceneDef def2 = enumerator.Current;
					AssetReferenceScene sceneAddress = def2.sceneAddress;
					string text = ((sceneAddress != null) ? ((AssetReference)sceneAddress).AssetGUID : null);
					if (!string.IsNullOrEmpty(text))
					{
						if (NetworkManagerSystem.IsAddressablesKeyValid(text, typeof(SceneInstance)))
						{
							AsyncOperationHandle<SceneInstance> val = Addressables.LoadSceneAsync((object)text, (LoadSceneMode)1, true, 100);
							val.Completed += delegate
							{
								loadScene(def2);
							};
						}
					}
					else
					{
						AsyncOperation val2 = SceneManager.LoadSceneAsync(def2.cachedName, (LoadSceneMode)1);
						val2.completed += delegate
						{
							loadScene(def2);
						};
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			static void loadScene(SceneDef def)
			{
				//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_004c: 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_0057: 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)
				//IL_006e: Expected O, but got Unknown
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: 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_0115: 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_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Expected O, but got Unknown
				Scene sceneByName = SceneManager.GetSceneByName(def.cachedName);
				ClassicStageInfo val4 = default(ClassicStageInfo);
				ClassicStageInfo val3 = (ClassicStageInfo.instance = ((Scene)(ref sceneByName)).GetRootGameObjects().First((GameObject x) => x.TryGetComponent<ClassicStageInfo>(ref val4)).GetComponent<ClassicStageInfo>());
				DirectorAPI.SetHooks();
				StageInfo stageInfo = DirectorAPI.GetStageInfo(val3);
				RunArtifactManager.instance = new RunArtifactManager
				{
					_enabledArtifacts = Array.Empty<bool>(),
					run = null
				};
				if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val3.monsterDccsPool))
				{
					DirectorAPI.PortToNewMonsterSystem(val3);
					DirectorAPI.PortToNewInteractableSystem(val3);
					if (!val3.monsterDccsPool.poolCategories.Any((Category x) => x.name == MonsterPoolCategories.Standard))
					{
						if (val3.monsterDccsPool.poolCategories.Length == 0)
						{
							val3.monsterDccsPool.poolCategories = (Category[])(object)new Category[1]
							{
								new Category
								{
									name = MonsterPoolCategories.Standard,
									categoryWeight = 1f,
									alwaysIncluded = Array.Empty<PoolEntry>(),
									includedIfConditionsMet = Array.Empty<ConditionalPoolEntry>(),
									includedIfNoConditionsMet = Array.Empty<PoolEntry>()
								}
							};
						}
						else
						{
							val3.monsterDccsPool.poolCategories[0].name = MonsterPoolCategories.Standard;
						}
					}
					DirectorAPI.ApplyMonsterChanges(val3, stageInfo);
					DirectorAPI.ApplyInteractableChanges(val3, stageInfo);
				}
				Setup.Init(def, val3);
				SceneManager.UnloadSceneAsync(def.cachedName);
			}
		}
	}
	[BepInPlugin("___.prodzpod.RealerStageTweaker", "RealerStageTweaker", "1.0.0")]
	public class Pre : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_ctor <>9__1_0;

			internal void <Awake>b__1_0(orig_ctor orig, SpawnCard self)
			{
				orig.Invoke(self);
				ToSearch.Add(self);
			}
		}

		public static List<SpawnCard> ToSearch = new List<SpawnCard>();

		public void Awake()
		{
			//IL_0015: 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)
			//IL_0020: Expected O, but got Unknown
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				hook_ctor val = delegate(orig_ctor orig, SpawnCard self)
				{
					orig.Invoke(self);
					ToSearch.Add(self);
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			SpawnCard.ctor += (hook_ctor)obj;
		}
	}
	public class SavedConfig
	{
		public struct _SavedConfig
		{
			public Dictionary<string, string> Defaults;

			public Dictionary<string, List<string>> Families;

			public Dictionary<string, string> Category;

			public Dictionary<string, float> Credit;

			public Dictionary<string, float> SceneCredit;

			public Dictionary<string, float> CategoryWeight;

			public Dictionary<string, int> SpawnDistance;

			public Dictionary<string, bool> PreventOverhead;

			public string EnemyList;

			public string FamilyList;

			public string InteractableList;
		}

		public static Dictionary<string, string> Defaults = new Dictionary<string, string>();

		public static Dictionary<string, List<string>> Families = new Dictionary<string, List<string>>();

		public static Dictionary<string, string> Category = new Dictionary<string, string>();

		public static Dictionary<string, float> Credit = new Dictionary<string, float>();

		public static Dictionary<string, float> SceneCredit = new Dictionary<string, float>();

		public static Dictionary<string, float> CategoryWeight = new Dictionary<string, float>();

		public static Dictionary<string, int> SpawnDistance = new Dictionary<string, int>();

		public static Dictionary<string, bool> PreventOverhead = new Dictionary<string, bool>();

		public static Dictionary<SceneDef, ConfigEntry<float>> ConfigMonsterCredit = new Dictionary<SceneDef, ConfigEntry<float>>();

		public static Dictionary<SceneDef, ConfigEntry<float>> ConfigInteractableCredit = new Dictionary<SceneDef, ConfigEntry<float>>();

		public static Dictionary<SceneDef, ConfigEntry<string>> ConfigMonsters = new Dictionary<SceneDef, ConfigEntry<string>>();

		public static Dictionary<SceneDef, ConfigEntry<string>> ConfigMonstersLoop = new Dictionary<SceneDef, ConfigEntry<string>>();

		public static Dictionary<SceneDef, ConfigEntry<string>> ConfigFamilies = new Dictionary<SceneDef, ConfigEntry<string>>();

		public static Dictionary<SceneDef, ConfigEntry<string>> ConfigInteractables = new Dictionary<SceneDef, ConfigEntry<string>>();

		public static void AddDefault(SceneDef def, string name, string val, string desc)
		{
			string key = def.cachedName + "." + name;
			Defaults[key] = val;
			ConfigEntry<string> val2 = Main.Config.Bind<string>(Setup.GetStageName(def), name, val, desc);
			if (Main.ResetConfig2.Value)
			{
				val2.Value = (string)((ConfigEntryBase)val2).DefaultValue;
			}
		}

		public static void Save(string enemyList, string familyList, string interactableList)
		{
			//IL_0020: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0045: 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_0064: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0085: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00c5: 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_00e4: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0125: 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: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_0160: Expected O, but got Unknown
			Main.Log.LogInfo((object)"Saving Persistent Configs");
			string path = Path.Combine(Paths.ConfigPath, "RealerStageTweakerPersistent.json");
			JObject val = new JObject();
			((JContainer)val).Add((object)new JProperty("Defaults", (object)JObject.Parse(JsonConvert.SerializeObject((object)Defaults))));
			((JContainer)val).Add((object)new JProperty("Families", (object)JObject.Parse(JsonConvert.SerializeObject((object)Families))));
			((JContainer)val).Add((object)new JProperty("Category", (object)JObject.Parse(JsonConvert.SerializeObject((object)Category))));
			((JContainer)val).Add((object)new JProperty("Credit", (object)JObject.Parse(JsonConvert.SerializeObject((object)Credit))));
			((JContainer)val).Add((object)new JProperty("SceneCredit", (object)JObject.Parse(JsonConvert.SerializeObject((object)SceneCredit))));
			((JContainer)val).Add((object)new JProperty("CategoryWeight", (object)JObject.Parse(JsonConvert.SerializeObject((object)CategoryWeight))));
			((JContainer)val).Add((object)new JProperty("SpawnDistance", (object)JObject.Parse(JsonConvert.SerializeObject((object)SpawnDistance))));
			((JContainer)val).Add((object)new JProperty("PreventOverhead", (object)JObject.Parse(JsonConvert.SerializeObject((object)PreventOverhead))));
			((JContainer)val).Add((object)new JProperty("EnemyList", (object)enemyList));
			((JContainer)val).Add((object)new JProperty("FamilyList", (object)familyList));
			((JContainer)val).Add((object)new JProperty("InteractableList", (object)interactableList));
			File.WriteAllText(path, ((object)val).ToString());
			Main.Log.LogInfo((object)"Saved Persistent Configs");
		}

		public static void Load()
		{
			Main.Log.LogInfo((object)"Loading Persistent Configs");
			_SavedConfig savedConfig = JsonConvert.DeserializeObject<_SavedConfig>(File.ReadAllText(Path.Combine(Paths.ConfigPath, "RealerStageTweakerPersistent.json")));
			Defaults = savedConfig.Defaults;
			Families = savedConfig.Families;
			Category = savedConfig.Category;
			Credit = savedConfig.Credit;
			SceneCredit = savedConfig.SceneCredit;
			CategoryWeight = savedConfig.CategoryWeight;
			SpawnDistance = savedConfig.SpawnDistance;
			PreventOverhead = savedConfig.PreventOverhead;
			Main.Config.Bind<string>("!! General", "List of Enemies", savedConfig.EnemyList, "for convenience, changing this field does not do anything");
			Main.Config.Bind<string>("!! General", "List of Family Events", savedConfig.FamilyList, "for convenience, changing this field does not do anything");
			Main.Config.Bind<string>("!! General", "List of Interactables", savedConfig.InteractableList, "for convenience, changing this field does not do anything");
			Sync("cscColossusGrassy", "cscColossusDefault");
			Main.Log.LogInfo((object)"Loaded Persistent Configs");
		}

		public static void Sync(string from, string to)
		{
			if (Category.TryGetValue(from, out var value))
			{
				Category[to] = value;
			}
			if (Credit.TryGetValue(from, out var value2))
			{
				Credit[to] = value2;
			}
			if (SceneCredit.TryGetValue(from, out var value3))
			{
				SceneCredit[to] = value3;
			}
			if (CategoryWeight.TryGetValue(from, out var value4))
			{
				CategoryWeight[to] = value4;
			}
			if (SpawnDistance.TryGetValue(from, out var value5))
			{
				SpawnDistance[to] = value5;
			}
			if (PreventOverhead.TryGetValue(from, out var value6))
			{
				PreventOverhead[to] = value6;
			}
		}

		public static void GetConfigs()
		{
			//IL_0002: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<SceneDef> enumerator = SceneCatalog.allStageSceneDefs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					SceneDef current = enumerator.Current;
					string stageName = Setup.GetStageName(current);
					if (SceneCredit.TryGetValue(current.cachedName + ".monster", out var value))
					{
						ConfigMonsterCredit.Add(current, Main.Config.Bind<float>(stageName, "Monster Credits", value, "Amount of monster credits this stage has at the beginning."));
					}
					if (SceneCredit.TryGetValue(current.cachedName + ".interactable", out var value2))
					{
						ConfigInteractableCredit.Add(current, Main.Config.Bind<float>(stageName, "Interactable Credits", value2, "Amount of interactable credits this stage has at the beginning."));
					}
					if (Defaults.TryGetValue(current.cachedName + ".Monsters", out var value3))
					{
						ConfigMonsters.Add(current, Main.Config.Bind<string>(stageName, "Monsters", value3, "Format: NAME=WEIGHT, separated by commas."));
					}
					if (Defaults.TryGetValue(current.cachedName + ".Monsters Post Loop", out var value4))
					{
						ConfigMonstersLoop.Add(current, Main.Config.Bind<string>(stageName, "Monsters Post Loop", value4, "monsters that can ONLY be spawned post loop. Format: NAME=WEIGHT, separated by commas."));
					}
					if (Defaults.TryGetValue(current.cachedName + ".Family Events", out var value5))
					{
						ConfigFamilies.Add(current, Main.Config.Bind<string>(stageName, "Family Events", value5, "list of possible family events. Separated by commas."));
					}
					if (Defaults.TryGetValue(current.cachedName + ".Interactables", out var value6))
					{
						ConfigInteractables.Add(current, Main.Config.Bind<string>(stageName, "Interactables", value6, "list of shrines, chests and other interactables to spawn. Format: NAME=WEIGHT, separated by commas."));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			foreach (SpawnCard item in Pre.ToSearch)
			{
				CharacterSpawnCard val = (CharacterSpawnCard)(object)((item is CharacterSpawnCard) ? item : null);
				if (val != null && !Main.Enemies.ContainsKey(((Object)val).name.Replace(",", "")))
				{
					Main.Enemies.Add(((Object)val).name.Replace(",", ""), val);
				}
				InteractableSpawnCard val2 = (InteractableSpawnCard)(object)((item is InteractableSpawnCard) ? item : null);
				if (val2 != null && !Main.Interactables.ContainsKey(((Object)val2).name.Replace(",", "")))
				{
					Main.Interactables.Add(((Object)val2).name.Replace(",", ""), val2);
				}
			}
			foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators)
			{
				foreach (object key3 in resourceLocator.Keys)
				{
					if (!key3.ToString().Contains("/csc"))
					{
						continue;
					}
					AsyncOperationHandle<CharacterSpawnCard> val3 = Addressables.LoadAssetAsync<CharacterSpawnCard>((object)key3.ToString());
					val3.Completed += delegate(AsyncOperationHandle<CharacterSpawnCard> res)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						//IL_0009: Invalid comparison between Unknown and I4
						if ((int)res.Status == 1)
						{
							CharacterSpawnCard result2 = res.Result;
							if (Object.op_Implicit((Object)(object)result2))
							{
								string key2 = ((Object)result2).name.Replace(",", "");
								if (!Main.Enemies.ContainsKey(key2))
								{
									Main.Enemies.Add(key2, result2);
								}
							}
						}
					};
				}
			}
			foreach (IResourceLocator resourceLocator2 in Addressables.ResourceLocators)
			{
				foreach (object key4 in resourceLocator2.Keys)
				{
					if (!key4.ToString().Contains("/isc"))
					{
						continue;
					}
					AsyncOperationHandle<InteractableSpawnCard> val4 = Addressables.LoadAssetAsync<InteractableSpawnCard>((object)key4.ToString());
					val4.Completed += delegate(AsyncOperationHandle<InteractableSpawnCard> res)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						//IL_0009: Invalid comparison between Unknown and I4
						if ((int)res.Status == 1)
						{
							InteractableSpawnCard result = res.Result;
							if (Object.op_Implicit((Object)(object)result))
							{
								string key = ((Object)result).name.Replace(",", "");
								if (!Main.Interactables.ContainsKey(key))
								{
									Main.Interactables.Add(key, result);
								}
							}
						}
					};
				}
			}
			Main.Log.LogInfo((object)$"Loaded {Main.Enemies.Count} Enemy Spawncards (+ all basegame cards)");
			Main.Log.LogInfo((object)$"Loaded {Main.Interactables.Count} Interactable Spawncards (+ all basegame cards)");
		}

		public static float GetMonsterCredit(SceneDef def)
		{
			if (ConfigMonsterCredit.TryGetValue(def, out var value))
			{
				return value.Value;
			}
			Main.Log.LogWarning((object)"this scene does not have persistent info! regenerate your config...");
			return -1f;
		}

		public static float GetInteractableCredit(SceneDef def)
		{
			if (ConfigInteractableCredit.TryGetValue(def, out var value))
			{
				return value.Value;
			}
			Main.Log.LogWarning((object)"this scene does not have persistent info! regenerate your config...");
			return -1f;
		}

		public static Dictionary<string, float> GetMonster(SceneDef def)
		{
			if (!ConfigMonsters.TryGetValue(def, out var value))
			{
				return null;
			}
			return new Dictionary<string, float>(value.Value.Split(',').Where(delegate(string x)
			{
				if (string.IsNullOrWhiteSpace(x))
				{
					return false;
				}
				if (x.Split('=').Length != 2)
				{
					Main.Log.LogWarning((object)("Config is malformed! " + x));
					return false;
				}
				return true;
			}).Select(delegate(string x)
			{
				string[] array = x.Split('=');
				return new KeyValuePair<string, float>(array[0].Trim(), float.Parse(array[1]));
			}));
		}

		public static Dictionary<string, float> GetMonsterLoop(SceneDef def)
		{
			if (!ConfigMonstersLoop.TryGetValue(def, out var value))
			{
				return null;
			}
			return new Dictionary<string, float>(value.Value.Split(',').Where(delegate(string x)
			{
				if (string.IsNullOrWhiteSpace(x))
				{
					return false;
				}
				if (x.Split('=').Length != 2)
				{
					Main.Log.LogWarning((object)("Config is malformed! " + x));
					return false;
				}
				return true;
			}).Select(delegate(string x)
			{
				string[] array = x.Split('=');
				return new KeyValuePair<string, float>(array[0].Trim(), float.Parse(array[1]));
			}));
		}

		public static List<string> GetFamily(SceneDef def)
		{
			if (!ConfigFamilies.TryGetValue(def, out var value))
			{
				return null;
			}
			return (from x in value.Value.Split(',')
				where !string.IsNullOrWhiteSpace(x)
				select x.Trim()).ToList();
		}

		public static Dictionary<string, float> GetInteractable(SceneDef def)
		{
			if (!ConfigInteractables.TryGetValue(def, out var value))
			{
				return null;
			}
			return new Dictionary<string, float>(value.Value.Split(',').Where(delegate(string x)
			{
				if (string.IsNullOrWhiteSpace(x))
				{
					return false;
				}
				if (x.Split('=').Length != 2)
				{
					Main.Log.LogWarning((object)("Config is malformed! " + x));
					return false;
				}
				return true;
			}).Select(delegate(string x)
			{
				string[] array = x.Split('=');
				return new KeyValuePair<string, float>(array[0].Trim(), float.Parse(array[1]));
			}));
		}
	}
	public class Setup
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<KeyValuePair<CharacterSpawnCard, float>, string> <>9__4_0;

			public static Func<KeyValuePair<CharacterSpawnCard, float>, string> <>9__4_1;

			public static Func<KeyValuePair<CharacterSpawnCard, float>, string> <>9__4_2;

			public static Func<KeyValuePair<CharacterSpawnCard, float>, string> <>9__4_3;

			public static Func<FamilyDirectorCardCategorySelection, string> <>9__4_4;

			public static Func<FamilyDirectorCardCategorySelection, string> <>9__4_5;

			public static Func<KeyValuePair<InteractableSpawnCard, float>, string> <>9__4_6;

			public static Func<KeyValuePair<InteractableSpawnCard, float>, string> <>9__4_7;

			public static Func<KeyValuePair<string, string>, string> <>9__5_0;

			public static Func<KeyValuePair<string, string>, string> <>9__5_1;

			public static Func<KeyValuePair<string, string>, string> <>9__5_2;

			public static Func<KeyValuePair<string, string>, string> <>9__5_3;

			public static Func<KeyValuePair<string, string>, string> <>9__5_4;

			public static Func<KeyValuePair<string, string>, string> <>9__5_5;

			public static Func<KeyValuePair<string, string>, string> <>9__5_6;

			public static Func<KeyValuePair<string, string>, string> <>9__5_7;

			public static Func<KeyValuePair<string, string>, string> <>9__5_8;

			public static UnityAction <>9__6_0;

			public static Func<string, string> <>9__7_0;

			public static Func<string, string> <>9__7_1;

			public static Comparison<ConditionalPoolEntry> <>9__16_0;

			public static Func<ExpansionDef, bool> <>9__18_0;

			public static Func<ExpansionDef, bool> <>9__18_1;

			public static Func<ExpansionDef, bool> <>9__19_0;

			internal string <Init>b__4_0(KeyValuePair<CharacterSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "") + "=" + x.Value;
			}

			internal string <Init>b__4_1(KeyValuePair<CharacterSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "");
			}

			internal string <Init>b__4_2(KeyValuePair<CharacterSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "") + "=" + x.Value;
			}

			internal string <Init>b__4_3(KeyValuePair<CharacterSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "");
			}

			internal string <Init>b__4_4(FamilyDirectorCardCategorySelection x)
			{
				return x.selectionChatString.Replace(",", "");
			}

			internal string <Init>b__4_5(FamilyDirectorCardCategorySelection x)
			{
				return x.selectionChatString.Replace(",", "");
			}

			internal string <Init>b__4_6(KeyValuePair<InteractableSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "") + "=" + x.Value;
			}

			internal string <Init>b__4_7(KeyValuePair<InteractableSpawnCard, float> x)
			{
				return ((Object)x.Key).name.Replace(",", "");
			}

			internal string <Finalize_>b__5_0(KeyValuePair<string, string> x)
			{
				return x.Key + "=" + x.Value;
			}

			internal string <Finalize_>b__5_1(KeyValuePair<string, string> x)
			{
				return x.Value;
			}

			internal string <Finalize_>b__5_2(KeyValuePair<string, string> x)
			{
				return x.Key;
			}

			internal string <Finalize_>b__5_3(KeyValuePair<string, string> x)
			{
				return x.Key + "=" + x.Value;
			}

			internal string <Finalize_>b__5_4(KeyValuePair<string, string> x)
			{
				return x.Value;
			}

			internal string <Finalize_>b__5_5(KeyValuePair<string, string> x)
			{
				return x.Key;
			}

			internal string <Finalize_>b__5_6(KeyValuePair<string, string> x)
			{
				return x.Key + "=" + x.Value;
			}

			internal string <Finalize_>b__5_7(KeyValuePair<string, string> x)
			{
				return x.Value;
			}

			internal string <Finalize_>b__5_8(KeyValuePair<string, string> x)
			{
				return x.Key;
			}

			internal void <DisplayEndMessage>b__6_0()
			{
				((Component)GameObject.Find("MainMenu").GetComponent<MainMenuController>().titleMenuScreen).GetComponent<TitleMenuController>().consoleFunctions.SubmitCmd("quit");
			}

			internal string <JoinAndOrderBy>b__7_0(string x)
			{
				return x;
			}

			internal string <JoinAndOrderBy>b__7_1(string x)
			{
				return x;
			}

			internal int <GetMainDCCS>b__16_0(ConditionalPoolEntry a, ConditionalPoolEntry b)
			{
				return DLCList(b).CompareTo(DLCList(a));
			}

			internal bool <DLCList>b__18_0(ExpansionDef x)
			{
				return ((Object)x).name == "DLC1";
			}

			internal bool <DLCList>b__18_1(ExpansionDef x)
			{
				return ((Object)x).name == "DLC2";
			}

			internal bool <HasDLC>b__19_0(ExpansionDef x)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Invalid comparison between Unknown and I4
				if (((Object)x).name == "DLC1")
				{
					return (int)SceneCatalog.FindSceneIndex("snowyforest") != -1;
				}
				if (((Object)x).name == "DLC2")
				{
					return (int)SceneCatalog.FindSceneIndex("habitat") != -1;
				}
				Main.Log.LogWarning((object)("unchecked DLC found: " + ((Object)x).name + "! let prod know of this."));
				return false;
			}
		}

		public static Dictionary<string, string> totalMonsters = new Dictionary<string, string>();

		public static Dictionary<string, string> totalFamilies = new Dictionary<string, string>();

		public static Dictionary<string, string> totalInteractables = new Dictionary<string, string>();

		public static int processedScenes = 0;

		public static int ID = 0;

		public static Dictionary<object, int> IDToKey = new Dictionary<object, int>();

		public static void Init(SceneDef def, ClassicStageInfo csi)
		{
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: 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_022c: Expected I4, but got Unknown
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Expected I4, but got Unknown
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)csi == (Object)null)
			{
				Finalize_();
				return;
			}
			SavedConfig.SceneCredit[def.cachedName + ".monster"] = csi.sceneDirectorMonsterCredits;
			ConfigEntry<float> val = Main.Config.Bind<float>(GetStageName(def), "Monster Credits", (float)csi.sceneDirectorMonsterCredits, "Amount of monster credits this stage has at the beginning.");
			if (Main.ResetConfig2.Value)
			{
				val.Value = (float)((ConfigEntryBase)val).DefaultValue;
			}
			SavedConfig.SceneCredit[def.cachedName + ".interactable"] = csi.sceneDirectorMonsterCredits;
			ConfigEntry<float> val2 = Main.Config.Bind<float>(GetStageName(def), "Interactable Credits", (float)csi.sceneDirectorInteractibleCredits, "Amount of interactable credits this stage has at the beginning.");
			if (Main.ResetConfig2.Value)
			{
				val2.Value = (float)((ConfigEntryBase)val2).DefaultValue;
			}
			if (def.cachedName == "voidraid")
			{
				Finalize_();
				return;
			}
			Dictionary<CharacterSpawnCard, float> dictionary = new Dictionary<CharacterSpawnCard, float>();
			Dictionary<CharacterSpawnCard, float> dictionary2 = new Dictionary<CharacterSpawnCard, float>();
			List<FamilyDirectorCardCategorySelection> list = new List<FamilyDirectorCardCategorySelection>();
			Dictionary<InteractableSpawnCard, float> dictionary3 = new Dictionary<InteractableSpawnCard, float>();
			DirectorCardCategorySelection mainDCCS = GetMainDCCS(csi.monsterDccsPool);
			if ((Object)(object)mainDCCS != (Object)null)
			{
				Category[] categories = mainDCCS.categories;
				foreach (Category val3 in categories)
				{
					DirectorCard[] cards = val3.cards;
					foreach (DirectorCard val4 in cards)
					{
						SpawnCard spawnCard = val4.spawnCard;
						CharacterSpawnCard val5 = (CharacterSpawnCard)(object)((spawnCard is CharacterSpawnCard) ? spawnCard : null);
						if (!((Object)(object)val5 == (Object)null))
						{
							string key = ((Object)val5).name.Replace(",", "");
							if (!SavedConfig.Category.ContainsKey(key))
							{
								SavedConfig.Category.Add(key, val3.name);
							}
							if (!SavedConfig.Credit.ContainsKey(key))
							{
								SavedConfig.Credit.Add(key, val4.cost);
							}
							if (!SavedConfig.SpawnDistance.ContainsKey(key))
							{
								SavedConfig.SpawnDistance.Add(key, (int)val4.spawnDistance);
							}
							if (!SavedConfig.PreventOverhead.ContainsKey(key))
							{
								SavedConfig.PreventOverhead.Add(key, val4.preventOverhead);
							}
							if (!SavedConfig.CategoryWeight.ContainsKey(val3.name))
							{
								SavedConfig.CategoryWeight.Add(val3.name, val3.selectionWeight);
							}
							Dictionary<CharacterSpawnCard, float> dictionary4 = ((val4.minimumStageCompletions < def.stageOrder) ? dictionary : dictionary2);
							if (dictionary4.ContainsKey(val5))
							{
								dictionary4[val5] += val4.selectionWeight;
							}
							else
							{
								dictionary4.Add(val5, val4.selectionWeight);
							}
						}
					}
				}
			}
			FamilyDirectorCardCategorySelection[] familyDCCS = GetFamilyDCCS(csi.monsterDccsPool);
			FamilyDirectorCardCategorySelection[] array = familyDCCS;
			foreach (FamilyDirectorCardCategorySelection val6 in array)
			{
				string text = val6.selectionChatString.Replace(",", "");
				if (!SavedConfig.Families.ContainsKey(val6.selectionChatString))
				{
					List<string> list2 = new List<string>();
					Category[] categories2 = ((DirectorCardCategorySelection)val6).categories;
					foreach (Category val7 in categories2)
					{
						DirectorCard[] cards2 = val7.cards;
						foreach (DirectorCard val8 in cards2)
						{
							list2.Add(((Object)val8.spawnCard).name.Replace(",", ""));
						}
					}
					SavedConfig.Families.Add(val6.selectionChatString, list2);
				}
				list.Add(val6);
			}
			DirectorCardCategorySelection mainDCCS2 = GetMainDCCS(csi.interactableDccsPool);
			if ((Object)(object)mainDCCS2 != (Object)null)
			{
				Category[] categories3 = mainDCCS2.categories;
				foreach (Category val9 in categories3)
				{
					DirectorCard[] cards3 = val9.cards;
					foreach (DirectorCard val10 in cards3)
					{
						SpawnCard spawnCard2 = val10.spawnCard;
						InteractableSpawnCard val11 = (InteractableSpawnCard)(object)((spawnCard2 is InteractableSpawnCard) ? spawnCard2 : null);
						if (!((Object)(object)val11 == (Object)null))
						{
							string key2 = ((Object)val11).name.Replace(",", "");
							if (!SavedConfig.Category.ContainsKey(key2))
							{
								SavedConfig.Category.Add(key2, val9.name);
							}
							if (!SavedConfig.Credit.ContainsKey(key2))
							{
								SavedConfig.Credit.Add(key2, val10.cost);
							}
							if (!SavedConfig.SpawnDistance.ContainsKey(key2))
							{
								SavedConfig.SpawnDistance.Add(key2, (int)val10.spawnDistance);
							}
							if (!SavedConfig.PreventOverhead.ContainsKey(key2))
							{
								SavedConfig.PreventOverhead.Add(key2, val10.preventOverhead);
							}
							if (!SavedConfig.CategoryWeight.ContainsKey(val9.name))
							{
								SavedConfig.CategoryWeight.Add(val9.name, val9.selectionWeight);
							}
							if (dictionary3.ContainsKey(val11))
							{
								dictionary3[val11] += val10.selectionWeight;
							}
							else
							{
								dictionary3.Add(val11, val10.selectionWeight);
							}
						}
					}
				}
			}
			if (dictionary.Count == 0 && dictionary2.Count == 0 && list.Count == 0 && dictionary3.Count == 0)
			{
				Finalize_();
				return;
			}
			Main.Log.LogInfo((object)("Adding Configs for " + GetStageName(def)));
			SavedConfig.AddDefault(def, "Monsters", JoinAndOrderBy(dictionary, (KeyValuePair<CharacterSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "") + "=" + x.Value, (KeyValuePair<CharacterSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "")), "Format: NAME=WEIGHT, separated by commas.");
			foreach (KeyValuePair<CharacterSpawnCard, float> item in dictionary)
			{
				if (!totalMonsters.ContainsKey(((Object)item.Key).name))
				{
					totalMonsters.Add(((Object)item.Key).name.Replace(",", ""), GetEnemyName(item.Key));
				}
			}
			SavedConfig.AddDefault(def, "Monsters Post Loop", JoinAndOrderBy(dictionary2, (KeyValuePair<CharacterSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "") + "=" + x.Value, (KeyValuePair<CharacterSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "")), "monsters that can ONLY be spawned post loop. Format: NAME=WEIGHT, separated by commas.");
			foreach (KeyValuePair<CharacterSpawnCard, float> item2 in dictionary2)
			{
				if (!totalMonsters.ContainsKey(((Object)item2.Key).name))
				{
					totalMonsters.Add(((Object)item2.Key).name.Replace(",", ""), GetEnemyName(item2.Key));
				}
			}
			SavedConfig.AddDefault(def, "Family Events", JoinAndOrderBy(list, (FamilyDirectorCardCategorySelection x) => x.selectionChatString.Replace(",", ""), (FamilyDirectorCardCategorySelection x) => x.selectionChatString.Replace(",", "")), "list of possible family events. Separated by commas.");
			foreach (FamilyDirectorCardCategorySelection item3 in list)
			{
				if (!totalFamilies.ContainsKey(item3.selectionChatString))
				{
					totalFamilies.Add(item3.selectionChatString.Replace(",", ""), GetFamilyName(item3));
				}
			}
			SavedConfig.AddDefault(def, "Interactables", JoinAndOrderBy(dictionary3, (KeyValuePair<InteractableSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "") + "=" + x.Value, (KeyValuePair<InteractableSpawnCard, float> x) => ((Object)x.Key).name.Replace(",", "")), "list of shrines, chests and other interactables to spawn. Format: NAME=WEIGHT, separated by commas.");
			foreach (KeyValuePair<InteractableSpawnCard, float> item4 in dictionary3)
			{
				if (!totalInteractables.ContainsKey(((Object)item4.Key).name))
				{
					totalInteractables.Add(((Object)item4.Key).name.Replace(",", ""), GetInteractableName(item4.Key));
				}
			}
			Finalize_();
		}

		public static void Finalize_()
		{
			//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)
			processedScenes++;
			if (processedScenes >= SceneCatalog.allStageSceneDefs.Length)
			{
				Main.Log.LogInfo((object)"Finalizing Load");
				string text = JoinAndOrderBy(totalMonsters, (KeyValuePair<string, string> x) => x.Key + "=" + x.Value, (KeyValuePair<string, string> x) => x.Value);
				Main.Config.Bind<string>("!! General", "List of Enemies", text, "for convenience, changing this field does not do anything").Value = string.Join(", ", totalMonsters.Select((KeyValuePair<string, string> x) => x.Key));
				string text2 = JoinAndOrderBy(totalFamilies, (KeyValuePair<string, string> x) => x.Key + "=" + x.Value, (KeyValuePair<string, string> x) => x.Value);
				Main.Config.Bind<string>("!! General", "List of Family Events", text2, "for convenience, changing this field does not do anything").Value = string.Join(", ", totalFamilies.Select((KeyValuePair<string, string> x) => x.Key));
				string text3 = JoinAndOrderBy(totalInteractables, (KeyValuePair<string, string> x) => x.Key + "=" + x.Value, (KeyValuePair<string, string> x) => x.Value);
				Main.Config.Bind<string>("!! General", "List of Interactables", text3, "for convenience, changing this field does not do anything").Value = string.Join(", ", totalInteractables.Select((KeyValuePair<string, string> x) => x.Key));
				SavedConfig.Save(text, text2, text3);
				Main.ResetConfig.Value = false;
				Main.ResetConfig2.Value = false;
				Object.DestroyImmediate((Object)(object)Main.box.rootObject);
				DisplayEndMessage();
			}
		}

		public static async void DisplayEndMessage()
		{
			await Task.Delay(250);
			Main.box = SimpleDialogBox.Create((MPEventSystem)null);
			Main.box.headerToken = new TokenParamsPair("Scan Complete", Array.Empty<object>());
			Main.box.descriptionToken = new TokenParamsPair("Config files have been generated!\nA restart is required for the change to take effect.", Array.Empty<object>());
			SimpleDialogBox box = Main.box;
			object obj = <>c.<>9__6_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					((Component)GameObject.Find("MainMenu").GetComponent<MainMenuController>().titleMenuScreen).GetComponent<TitleMenuController>().consoleFunctions.SubmitCmd("quit");
				};
				<>c.<>9__6_0 = val;
				obj = (object)val;
			}
			box.AddActionButton((UnityAction)obj, "Close Game", true, Array.Empty<object>());
		}

		public static string JoinAndOrderBy(IEnumerable<string> arr, string joiner = ", ")
		{
			return JoinAndOrderBy(arr, (string x) => x, (string x) => x, joiner);
		}

		public static string JoinAndOrderBy<T>(IEnumerable<T> arr, Func<T, string> fn, Func<T, string> cmp, string joiner = ", ")
		{
			List<T> list = arr.ToList();
			list.Sort((T a, T b) => cmp(a).CompareTo(cmp(b)));
			return string.Join(joiner, list.Select(fn));
		}

		public static string GetStageName(SceneDef def)
		{
			return Language.GetString(def.nameToken).Replace("\n", "").Replace("\t", "")
				.Replace("\\", "")
				.Replace("\"", "")
				.Replace("'", "")
				.Replace("[", "")
				.Replace("]", "") + " (" + def.cachedName + ")";
		}

		public static string GetEnemyName(CharacterSpawnCard csc)
		{
			if (IDToKey.ContainsKey(csc))
			{
				return "OBJECT_" + IDToKey[csc];
			}
			if (Object.op_Implicit((Object)(object)csc) && Object.op_Implicit((Object)(object)((SpawnCard)csc).prefab) && Object.op_Implicit((Object)(object)((SpawnCard)csc).prefab.GetComponent<CharacterMaster>()) && Object.op_Implicit((Object)(object)((SpawnCard)csc).prefab.GetComponent<CharacterMaster>().bodyPrefab) && Object.op_Implicit((Object)(object)((SpawnCard)csc).prefab.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>()))
			{
				return Language.GetString(((SpawnCard)csc).prefab.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>().baseNameToken).Trim();
			}
			string text = ((Object)((SpawnCard)csc).prefab).name.Trim();
			if (string.IsNullOrEmpty(text))
			{
				IDToKey.Add(csc, ID);
				ID++;
				return "OBJECT_" + IDToKey[csc];
			}
			return text;
		}

		public static string GetFamilyName(FamilyDirectorCardCategorySelection dccs)
		{
			if (IDToKey.ContainsKey(dccs))
			{
				return "OBJECT_" + IDToKey[dccs];
			}
			string text = dccs.selectionChatString.ToLower();
			if (text.StartsWith("family_"))
			{
				string text2 = text;
				int length = "family_".Length;
				text = text2.Substring(length, text2.Length - length);
			}
			string text3 = ToTitleCase(text);
			if (string.IsNullOrEmpty(text3))
			{
				IDToKey.Add(dccs, ID);
				ID++;
				return "OBJECT_" + IDToKey[dccs];
			}
			return text3;
		}

		public static string ToTitleCase(string str)
		{
			str = str.ToLower();
			if (str.Length > 0)
			{
				string text = str.Substring(0, 1).ToUpper();
				object obj;
				if (str.Length <= 1)
				{
					obj = "";
				}
				else
				{
					string text2 = str;
					obj = text2.Substring(1, text2.Length - 1);
				}
				str = text + (string?)obj;
			}
			for (int i = 1; i < str.Length; i++)
			{
				if (str[i - 1] == ' ')
				{
					string text3 = str.Substring(0, i);
					string text4 = str;
					int num = i;
					string text5 = text4.Substring(num, i + 1 - num).ToUpper();
					object obj2;
					if (str.Length <= i + 1)
					{
						obj2 = "";
					}
					else
					{
						string text2 = str;
						num = i + 1;
						obj2 = text2.Substring(num, text2.Length - num);
					}
					str = text3 + text5 + (string?)obj2;
				}
			}
			return str.Trim();
		}

		public static string GetInteractableName(InteractableSpawnCard isc)
		{
			if (IDToKey.ContainsKey(isc))
			{
				return "OBJECT_" + IDToKey[isc];
			}
			if (Object.op_Implicit((Object)(object)isc) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab.GetComponent<PurchaseInteraction>()))
			{
				return Language.GetString(((SpawnCard)isc).prefab.GetComponent<PurchaseInteraction>().displayNameToken).Trim();
			}
			if (Object.op_Implicit((Object)(object)isc) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab.GetComponent<BarrelInteraction>()))
			{
				return Language.GetString(((SpawnCard)isc).prefab.GetComponent<BarrelInteraction>().displayNameToken).Trim();
			}
			if (Object.op_Implicit((Object)(object)isc) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab.GetComponent<MultiShopController>()) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab.GetComponent<MultiShopController>().terminalPrefab) && Object.op_Implicit((Object)(object)((SpawnCard)isc).prefab.GetComponent<MultiShopController>().terminalPrefab.GetComponent<PurchaseInteraction>()))
			{
				return Language.GetString(((SpawnCard)isc).prefab.GetComponent<MultiShopController>().terminalPrefab.GetComponent<PurchaseInteraction>().displayNameToken).Trim();
			}
			string text = ((Object)((SpawnCard)isc).prefab).name.Trim();
			if (string.IsNullOrEmpty(text))
			{
				IDToKey.Add(isc, ID);
				ID++;
				return "OBJECT_" + IDToKey[isc];
			}
			return text;
		}

		public static DirectorCardCategorySelection GetMainDCCS(DccsPool dp)
		{
			if ((Object)(object)dp == (Object)null || dp.poolCategories == null)
			{
				return null;
			}
			Category[] poolCategories = dp.poolCategories;
			foreach (Category val in poolCategories)
			{
				bool flag = false;
				List<ConditionalPoolEntry> list = val.includedIfConditionsMet.ToList();
				list.Sort((ConditionalPoolEntry a, ConditionalPoolEntry b) => DLCList(b).CompareTo(DLCList(a)));
				foreach (ConditionalPoolEntry item in list)
				{
					if (HasDLC(item))
					{
						flag = true;
						if (!(((PoolEntry)item).dccs is FamilyDirectorCardCategorySelection))
						{
							return ((PoolEntry)item).dccs;
						}
					}
				}
				if (!flag)
				{
					PoolEntry[] includedIfNoConditionsMet = val.includedIfNoConditionsMet;
					foreach (PoolEntry val2 in includedIfNoConditionsMet)
					{
						if (!(val2.dccs is FamilyDirectorCardCategorySelection))
						{
							return val2.dccs;
						}
					}
				}
				PoolEntry[] alwaysIncluded = val.alwaysIncluded;
				foreach (PoolEntry val3 in alwaysIncluded)
				{
					if (!(val3.dccs is FamilyDirectorCardCategorySelection))
					{
						return val3.dccs;
					}
				}
			}
			return null;
		}

		public static FamilyDirectorCardCategorySelection[] GetFamilyDCCS(DccsPool dp)
		{
			if ((Object)(object)dp == (Object)null || dp.poolCategories == null)
			{
				return Array.Empty<FamilyDirectorCardCategorySelection>();
			}
			List<FamilyDirectorCardCategorySelection> list = new List<FamilyDirectorCardCategorySelection>();
			Category[] poolCategories = dp.poolCategories;
			foreach (Category val in poolCategories)
			{
				PoolEntry[] alwaysIncluded = val.alwaysIncluded;
				foreach (PoolEntry val2 in alwaysIncluded)
				{
					if (val2.dccs is FamilyDirectorCardCategorySelection)
					{
						DirectorCardCategorySelection dccs = val2.dccs;
						list.Add((FamilyDirectorCardCategorySelection)(object)((dccs is FamilyDirectorCardCategorySelection) ? dccs : null));
					}
				}
				bool flag = false;
				ConditionalPoolEntry[] includedIfConditionsMet = val.includedIfConditionsMet;
				foreach (ConditionalPoolEntry val3 in includedIfConditionsMet)
				{
					if (HasDLC(val3))
					{
						flag = true;
						if (((PoolEntry)val3).dccs is FamilyDirectorCardCategorySelection)
						{
							DirectorCardCategorySelection dccs2 = ((PoolEntry)val3).dccs;
							list.Add((FamilyDirectorCardCategorySelection)(object)((dccs2 is FamilyDirectorCardCategorySelection) ? dccs2 : null));
						}
					}
				}
				if (flag)
				{
					continue;
				}
				PoolEntry[] includedIfNoConditionsMet = val.includedIfNoConditionsMet;
				foreach (PoolEntry val4 in includedIfNoConditionsMet)
				{
					if (val4.dccs is FamilyDirectorCardCategorySelection)
					{
						DirectorCardCategorySelection dccs3 = val4.dccs;
						list.Add((FamilyDirectorCardCategorySelection)(object)((dccs3 is FamilyDirectorCardCategorySelection) ? dccs3 : null));
					}
				}
			}
			return list.ToArray();
		}

		public static int DLCList(ConditionalPoolEntry entry)
		{
			int num = 0;
			if (entry.requiredExpansions.Any((ExpansionDef x) => ((Object)x).name == "DLC1"))
			{
				num++;
			}
			if (entry.requiredExpansions.Any((ExpansionDef x) => ((Object)x).name == "DLC2"))
			{
				num += 2;
			}
			return num;
		}

		public static bool HasDLC(ConditionalPoolEntry entry)
		{
			return entry.requiredExpansions.All(delegate(ExpansionDef x)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Invalid comparison between Unknown and I4
				if (((Object)x).name == "DLC1")
				{
					return (int)SceneCatalog.FindSceneIndex("snowyforest") != -1;
				}
				if (((Object)x).name == "DLC2")
				{
					return (int)SceneCatalog.FindSceneIndex("habitat") != -1;
				}
				Main.Log.LogWarning((object)("unchecked DLC found: " + ((Object)x).name + "! let prod know of this."));
				return false;
			});
		}
	}
}