Decompiled source of ProperLoop v1.0.11

ProperLoop.dll

Decompiled 3 months 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 AccurateEnemies.Hooks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates.ScavBackpack;
using HarmonyLib;
using IL.RoR2;
using IL.RoR2.Achievements;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using ProperSave;
using RoR2;
using TPDespair.ZetArtifacts;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ProperLoop")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+07e12796bcb1655fb334f8463580325dc5e91a85")]
[assembly: AssemblyProduct("ProperLoop")]
[assembly: AssemblyTitle("ProperLoop")]
[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 ProperLoop
{
	public class AccurateEnemiesFix
	{
		[HarmonyPatch]
		public class BeetleGuardFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(BeetleGuard));
			}
		}

		[HarmonyPatch]
		public class BronzongFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Bronzong));
			}
		}

		[HarmonyPatch]
		public class ClayBossFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(ClayBoss));
			}
		}

		[HarmonyPatch]
		public class ClayGrenadierFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(ClayGrenadier));
			}
		}

		[HarmonyPatch]
		public class FlyingVerminFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(FlyingVermin));
			}
		}

		[HarmonyPatch]
		public class GreaterWispFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(GreaterWisp));
			}
		}

		[HarmonyPatch]
		public class GrovetenderFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Grovetender));
			}
		}

		[HarmonyPatch]
		public class LemurianFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Lemurian));
			}
		}

		[HarmonyPatch]
		public class LemurianBruiserFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(LemurianBruiser));
			}
		}

		[HarmonyPatch]
		public class LunarExploderFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(LunarExploder));
			}
		}

		[HarmonyPatch]
		public class MinorConstructFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(MinorConstruct));
			}
		}

		[HarmonyPatch]
		public class RoboBallBossFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(RoboBallBoss));
			}
		}

		[HarmonyPatch]
		public class ScavengerFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Scavenger));
			}
		}

		[HarmonyPatch]
		public class VagrantFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Vagrant));
			}
		}

		[HarmonyPatch]
		public class VoidJailerFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(VoidJailer));
			}
		}

		[HarmonyPatch]
		public class VultureFix
		{
			public static void ILManipulator(ILContext il)
			{
				Patch(il);
			}

			public static MethodBase TargetMethod()
			{
				return GetMethod(typeof(Vulture));
			}
		}

		public static void Init()
		{
			Main.Harmony.PatchAll(typeof(BeetleGuardFix));
			Main.Harmony.PatchAll(typeof(BronzongFix));
			Main.Harmony.PatchAll(typeof(ClayBossFix));
			Main.Harmony.PatchAll(typeof(ClayGrenadierFix));
			Main.Harmony.PatchAll(typeof(FlyingVerminFix));
			Main.Harmony.PatchAll(typeof(GreaterWispFix));
			Main.Harmony.PatchAll(typeof(GrovetenderFix));
			Main.Harmony.PatchAll(typeof(LemurianFix));
			Main.Harmony.PatchAll(typeof(LemurianBruiserFix));
			Main.Harmony.PatchAll(typeof(LunarExploderFix));
			Main.Harmony.PatchAll(typeof(MinorConstructFix));
			Main.Harmony.PatchAll(typeof(RoboBallBossFix));
			Main.Harmony.PatchAll(typeof(ScavengerFix));
			Main.Harmony.PatchAll(typeof(VagrantFix));
			Main.Harmony.PatchAll(typeof(VoidJailerFix));
			Main.Harmony.PatchAll(typeof(VultureFix));
		}

		public static void Patch(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<Run>(x, "stageClearCount")
			}))
			{
				val.Emit(OpCodes.Pop);
				val.EmitDelegate<Func<int>>((Func<int>)(() => (Main.loops > 0) ? 5 : 0));
			}
		}

		public static MethodBase GetMethod(Type t)
		{
			return AccessTools.DeclaredMethod(t.GetNestedType("<>c", AccessTools.all), "<Init>b__3_1", (Type[])null, (Type[])null) ?? AccessTools.DeclaredMethod(t.GetNestedType("<>c", AccessTools.all), "<Init>b__3_0", (Type[])null, (Type[])null);
		}
	}
	internal class J
	{
		public static void load()
		{
			Loading.OnLoadingEnded += delegate
			{
				load(Main.savePath);
			};
			static void load(string path)
			{
				string[][] source = File.ReadAllLines(path).ToList().ConvertAll((string x) => x.Split(','))
					.ToArray();
				Main.loops = int.Parse(source.FirstOrDefault((string[] x) => x[0] == "loops")[1]);
				Main.stage = int.Parse(source.FirstOrDefault((string[] x) => x[0] == "stage")[1]);
				if (Main.ScavItemCountScale.Value)
				{
					Opening.maxItemDropCount = Main.loops * Run.stagesPerLoop + Main.stage + 1;
				}
			}
		}
	}
	[BepInPlugin("prodzpod.ProperLoop", "ProperLoop", "1.0.11")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		[HarmonyPatch]
		public class PatchLoopGetter
		{
			public static bool Prefix(ref int __result)
			{
				__result = loops;
				return false;
			}

			public static MethodBase TargetMethod()
			{
				return typeof(Run).GetProperty("loopClearCount").GetGetMethod();
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Start <>9__30_0;

			public static Func<Instruction, bool> <>9__30_10;

			public static Func<int> <>9__30_11;

			public static Manipulator <>9__30_1;

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

			public static Action<Stage> <>9__30_2;

			public static hook_PlaceTeleporter <>9__30_3;

			public static Func<Instruction, bool> <>9__30_13;

			public static Func<int> <>9__30_14;

			public static Manipulator <>9__30_4;

			public static Func<Instruction, bool> <>9__30_15;

			public static Func<DirectorCard, string> <>9__30_24;

			public static Func<Category, string> <>9__30_23;

			public static Func<Instruction, bool> <>9__30_17;

			public static Func<Instruction, bool> <>9__30_18;

			public static Func<MonsterFamily, int> <>9__30_19;

			public static Func<Instruction, bool> <>9__30_20;

			public static Func<Instruction, bool> <>9__30_21;

			public static Func<MonsterFamily, int> <>9__30_22;

			public static Func<Instruction, bool> <>9__30_25;

			public static Func<Instruction, bool> <>9__30_26;

			public static Func<DirectorCard, int> <>9__30_27;

			public static Manipulator <>9__30_6;

			public static Converter<string, string> <>9__30_28;

			public static Func<EliteRules, bool> <>9__30_31;

			public static Func<EliteRules, bool> <>9__30_32;

			public static Func<EliteDef, bool> <>9__30_37;

			public static Func<EliteRules, bool> <>9__30_33;

			public static Func<EliteRules, bool> <>9__30_34;

			public static Func<EliteRules, bool> <>9__30_39;

			public static Comparison<EliteTierDef> <>9__30_29;

			public static Func<EliteDef, string> <>9__30_40;

			public static Func<EliteTierDef, string> <>9__30_30;

			public static Action <>9__30_7;

			public static Func<Instruction, bool> <>9__30_41;

			public static Func<Instruction, bool> <>9__30_42;

			public static Func<Instruction, bool> <>9__30_43;

			public static Func<Instruction, bool> <>9__30_44;

			public static Func<EliteDef, bool> <>9__30_48;

			public static Action<CombatDirector> <>9__30_45;

			public static Func<Instruction, bool> <>9__30_46;

			public static Func<CombatDirector, EliteDef> <>9__30_47;

			public static Manipulator <>9__30_8;

			public static hook_SetEquipmentIndex <>9__30_9;

			public static Action<Dictionary<string, object>> <>9__36_0;

			internal void <Awake>b__30_0(orig_Start orig, Run self)
			{
				loops = 0;
				stage = 0;
				if (ScavItemCountScale.Value)
				{
					Opening.maxItemDropCount = 1;
				}
				orig.Invoke(self);
			}

			internal void <Awake>b__30_1(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				val.GotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<Run>(x, "stageClearCount")
				});
				val.Emit(OpCodes.Pop);
				val.EmitDelegate<Func<int>>((Func<int>)(() => loops * Run.stagesPerLoop + stage));
			}

			internal bool <Awake>b__30_10(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<Run>(x, "stageClearCount");
			}

			internal int <Awake>b__30_11()
			{
				return loops * Run.stagesPerLoop + stage;
			}

			internal void <Awake>b__30_2(Stage _)
			{
				GameObject? obj = ((IEnumerable<GameObject>)Object.FindObjectsOfType<GameObject>()).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => (Object)(object)x.GetComponent<TeleporterInteraction>() != (Object)null));
				TeleporterInteraction val = ((obj != null) ? obj.GetComponent<TeleporterInteraction>() : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)null))
				{
					stage++;
					if (((Object)((Component)val).gameObject).name.Contains("LunarTeleporter"))
					{
						stage = 0;
						loops++;
					}
					if (ScavItemCountScale.Value)
					{
						Opening.maxItemDropCount = loops * Run.stagesPerLoop + stage + 1;
					}
				}
			}

			internal bool <Awake>b__30_12(GameObject x)
			{
				return (Object)(object)x.GetComponent<TeleporterInteraction>() != (Object)null;
			}

			internal void <Awake>b__30_3(orig_PlaceTeleporter orig, SceneDirector self)
			{
				if ((Object)(object)self.teleporterSpawnCard != (Object)null)
				{
					self.teleporterSpawnCard = (SpawnCard)(object)((stage == Run.stagesPerLoop - 1) ? lunarTP : TP);
				}
				orig.Invoke(self);
			}

			internal void <Awake>b__30_4(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0)
				});
				val.Emit(OpCodes.Pop);
				val.EmitDelegate<Func<int>>((Func<int>)(() => loops));
			}

			internal bool <Awake>b__30_13(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdcI4(x, 0);
			}

			internal int <Awake>b__30_14()
			{
				return loops;
			}

			internal bool <Awake>b__30_15(Instruction x)
			{
				return ILPatternMatchingExt.MatchStfld<ClassicStageInfo>(x, "modifiableMonsterCategories");
			}

			internal string <Awake>b__30_23(Category x)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return GeneralExtensions.Join<DirectorCard>((IEnumerable<DirectorCard>)x.cards, (Func<DirectorCard, string>)delegate(DirectorCard y)
				{
					SpawnCard spawnCard = y.spawnCard;
					return (((spawnCard != null) ? ((Object)spawnCard).name : null) ?? "Null") + $" ({y.minimumStageCompletions})";
				}, ", ");
			}

			internal string <Awake>b__30_24(DirectorCard y)
			{
				SpawnCard spawnCard = y.spawnCard;
				return (((spawnCard != null) ? ((Object)spawnCard).name : null) ?? "Null") + $" ({y.minimumStageCompletions})";
			}

			internal bool <Awake>b__30_17(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<MonsterFamily>(x, "minimumStageCompletion");
			}

			internal bool <Awake>b__30_18(Instruction x)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBgt(x, ref val);
			}

			internal int <Awake>b__30_19(MonsterFamily self)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return StageCheck(self.minimumStageCompletion + 1) ? 1 : 0;
			}

			internal bool <Awake>b__30_20(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<MonsterFamily>(x, "maximumStageCompletion");
			}

			internal bool <Awake>b__30_21(Instruction x)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBle(x, ref val);
			}

			internal int <Awake>b__30_22(MonsterFamily self)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return StageCheckMax(self.maximumStageCompletion + 1) ? 1 : 0;
			}

			internal void <Awake>b__30_6(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<DirectorCard>(x, "minimumStageCompletions")
				});
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchClt(x)
				});
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<DirectorCard, int>>((Func<DirectorCard, int>)((DirectorCard self) => StageCheck(self.minimumStageCompletions + 1) ? 1 : 0));
				val.Emit(OpCodes.Ldc_I4_1);
			}

			internal bool <Awake>b__30_25(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<DirectorCard>(x, "minimumStageCompletions");
			}

			internal bool <Awake>b__30_26(Instruction x)
			{
				return ILPatternMatchingExt.MatchClt(x);
			}

			internal int <Awake>b__30_27(DirectorCard self)
			{
				return StageCheck(self.minimumStageCompletions + 1) ? 1 : 0;
			}

			internal void <Awake>b__30_7()
			{
				//IL_0340: Unknown result type (might be due to invalid IL or missing references)
				//IL_0347: Expected O, but got Unknown
				//IL_0356: Unknown result type (might be due to invalid IL or missing references)
				//IL_035b: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass30_1 CS$<>8__locals0 = new <>c__DisplayClass30_1();
				if (_thisInitialized)
				{
					return;
				}
				Log.LogDebug((object)"EliteAPI, amarite?");
				List<string> list = EliteDisables.Value.Split(',').ToList().ConvertAll((string x) => x.Trim());
				CS$<>8__locals0.T1s = new string[4] { "edLightning", "edIce", "edFire", "edEarth" };
				CS$<>8__locals0.T1Honors = new string[4] { "edLightningHonor", "edIceHonor", "edFireHonor", "edEarthHonor" };
				CS$<>8__locals0.T2s = new string[2] { "edPoison", "edHaunted" };
				float costMultiplier = CombatDirector.baseEliteCostMultiplier * PerfectedCost.Value;
				List<EliteTierDef> list2 = new List<EliteTierDef>();
				for (int i = 0; i < CombatDirector.eliteTiers.Length; i++)
				{
					EliteTierDef val = CombatDirector.eliteTiers[i];
					if (val.eliteTypes.Any((EliteDef x) => CS$<>8__locals0.T2s.Contains((x != null) ? ((Object)x).name : null)))
					{
						list2.Add(val);
						val.costMultiplier *= T2Cost.Value / 6f;
						val.isAvailable = (EliteRules rules) => (T2OnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(T2OnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
					}
					else if (val.eliteTypes.Any((EliteDef x) => CS$<>8__locals0.T1Honors.Contains((x != null) ? ((Object)x).name : null)))
					{
						val.costMultiplier *= T1Cost.Value;
						val.isAvailable = (EliteRules rules) => CombatDirector.IsEliteOnlyArtifactActive() && StageCheck(T1OnLevel.Value, HonorMultiplier.Value);
					}
					else if (PerfectedOnLevel.Value > 0 && val.eliteTypes.Any((EliteDef x) => "edLunar" == ((x != null) ? ((Object)x).name : null)))
					{
						Log.LogDebug((object)"PerfectedLoop2 in Motion...");
						val.costMultiplier *= T1Cost.Value;
						val.isAvailable = (EliteRules rules) => (int)rules == 2 && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
					}
					else if (val.eliteTypes.Any((EliteDef x) => CS$<>8__locals0.T1s.Contains((x != null) ? ((Object)x).name : null)))
					{
						list2.Add(val);
						val.costMultiplier *= T1Cost.Value;
						costMultiplier = val.costMultiplier;
						val.isAvailable = (EliteRules rules) => CombatDirector.NotEliteOnlyArtifactActive() && (int)rules == 0 && StageCheck(T1OnLevel.Value);
					}
					CombatDirector.eliteTiers[i] = val;
				}
				EliteTierDef val2 = new EliteTierDef();
				val2.eliteTypes = (EliteDef[])(object)new EliteDef[1] { Addressables.LoadAssetAsync<EliteDef>((object)"RoR2/Base/EliteLunar/edLunar.asset").WaitForCompletion() };
				val2.costMultiplier = costMultiplier;
				val2.isAvailable = (EliteRules rules) => (PerfectedOnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
				val2.canSelectWithoutAvailableEliteDef = false;
				list2.Add(val2);
				List<EliteTierDef> list3 = CombatDirector.eliteTiers.ToList();
				list3.RemoveAll(list2.Contains);
				list2.Sort((EliteTierDef a, EliteTierDef b) => (int)Mathf.Sign(a.costMultiplier - b.costMultiplier));
				list3.InsertRange(1, list2);
				CombatDirector.eliteTiers = list3.ToArray();
				_thisInitialized = true;
				Log.LogDebug((object)("Elites:\n\n" + GeneralExtensions.Join<EliteTierDef>((IEnumerable<EliteTierDef>)CombatDirector.eliteTiers, (Func<EliteTierDef, string>)((EliteTierDef x) => GeneralExtensions.Join<EliteDef>((IEnumerable<EliteDef>)x.eliteTypes, (Func<EliteDef, string>)((EliteDef y) => (y != null) ? ((Object)y).name : null), ", ") + $"({x.costMultiplier})"), "\n")));
			}

			internal string <Awake>b__30_28(string x)
			{
				return x.Trim();
			}

			internal bool <Awake>b__30_31(EliteRules rules)
			{
				return (T2OnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(T2OnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
			}

			internal bool <Awake>b__30_32(EliteRules rules)
			{
				return CombatDirector.IsEliteOnlyArtifactActive() && StageCheck(T1OnLevel.Value, HonorMultiplier.Value);
			}

			internal bool <Awake>b__30_37(EliteDef x)
			{
				return "edLunar" == ((x != null) ? ((Object)x).name : null);
			}

			internal bool <Awake>b__30_33(EliteRules rules)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				return (int)rules == 2 && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
			}

			internal bool <Awake>b__30_34(EliteRules rules)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return CombatDirector.NotEliteOnlyArtifactActive() && (int)rules == 0 && StageCheck(T1OnLevel.Value);
			}

			internal bool <Awake>b__30_39(EliteRules rules)
			{
				return (PerfectedOnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
			}

			internal int <Awake>b__30_29(EliteTierDef a, EliteTierDef b)
			{
				return (int)Mathf.Sign(a.costMultiplier - b.costMultiplier);
			}

			internal string <Awake>b__30_30(EliteTierDef x)
			{
				return GeneralExtensions.Join<EliteDef>((IEnumerable<EliteDef>)x.eliteTypes, (Func<EliteDef, string>)((EliteDef y) => (y != null) ? ((Object)y).name : null), ", ") + $"({x.costMultiplier})";
			}

			internal string <Awake>b__30_40(EliteDef y)
			{
				return (y != null) ? ((Object)y).name : null;
			}

			internal void <Awake>b__30_8(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				ILLabel val2 = null;
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Card {0} cannot be elite. Skipping elite procedure.")
				});
				val.GotoPrev(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(CombatDirector), "cvDirectorCombatEnableInternalLogs")
				});
				int index = val.Index;
				ILLabel val5 = default(ILLabel);
				val.GotoPrev((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSpawnCard>(x, "noElites"),
					(Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val5)
				});
				val.MoveAfterLabels();
				val.RemoveRange(index - val.Index);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<CombatDirector>>((Action<CombatDirector>)delegate(CombatDirector self)
				{
					//IL_0025: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
					int num = 1;
					float num2 = 0f;
					for (int i = 1; i < CombatDirector.eliteTiers.Length; i++)
					{
						EliteTierDef val3 = CombatDirector.eliteTiers[i];
						if (!val3.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
						{
							if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
							{
								Debug.LogFormat("Elite tier index {0} is unavailable", new object[1] { i });
							}
						}
						else
						{
							float num3 = (float)self.currentMonsterCard.cost * val3.costMultiplier * self.eliteBias;
							if (num3 <= self.monsterCredit)
							{
								num = i + 1;
								num2 = val3.costMultiplier;
								if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
								{
									Debug.LogFormat("Found valid elite tier index {0}", new object[1] { i });
								}
							}
							else if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
							{
								Debug.LogFormat("Elite tier index {0} is too expensive ({1}/{2})", new object[3] { i, num3, self.monsterCredit });
							}
						}
					}
					if (num > 1)
					{
						int num4 = num;
						EliteSelection.Clear();
						while (num4 > 0)
						{
							num4--;
							EliteTierDef val4 = CombatDirector.eliteTiers[num4];
							if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
							{
								ManualLogSource log = Log;
								EliteDef obj = val4.eliteTypes[0];
								log.LogDebug((object)$"Testing {((obj != null) ? ((Object)obj).name : null)}: {num2} ({val4.costMultiplier == num2})");
							}
							if (val4.costMultiplier > num2 || !val4.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
							{
								break;
							}
							EliteSelection.AddChoice(val4, (float)val4.eliteTypes.Count((EliteDef x) => Object.op_Implicit((Object)(object)x) && x.IsAvailable()));
						}
						self.currentActiveEliteTier = EliteSelection.Evaluate(self.rng.nextNormalizedFloat);
					}
					else
					{
						self.currentActiveEliteTier = CombatDirector.eliteTiers[0];
					}
				});
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStfld(x, typeof(CombatDirector), "currentActiveEliteDef")
				});
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<CombatDirector, EliteDef>>((Func<CombatDirector, EliteDef>)delegate(CombatDirector self)
				{
					EliteDef randomAvailableEliteDef = self.currentActiveEliteTier.GetRandomAvailableEliteDef(self.rng);
					if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
					{
						if ((Object)(object)self.currentActiveEliteTier.eliteTypes[0] != (Object)null)
						{
							Log.LogInfo((object)("Current EliteTier: " + ((Object)self.currentActiveEliteTier.eliteTypes[0]).name));
						}
						if ((Object)(object)randomAvailableEliteDef != (Object)null)
						{
							Log.LogInfo((object)("Current Elite: " + ((Object)randomAvailableEliteDef).name));
						}
					}
					return randomAvailableEliteDef;
				});
			}

			internal bool <Awake>b__30_41(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdstr(x, "Card {0} cannot be elite. Skipping elite procedure.");
			}

			internal bool <Awake>b__30_42(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdsfld(x, typeof(CombatDirector), "cvDirectorCombatEnableInternalLogs");
			}

			internal bool <Awake>b__30_43(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<CharacterSpawnCard>(x, "noElites");
			}

			internal bool <Awake>b__30_44(Instruction x)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBrtrue(x, ref val);
			}

			internal void <Awake>b__30_45(CombatDirector self)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
				int num = 1;
				float num2 = 0f;
				for (int i = 1; i < CombatDirector.eliteTiers.Length; i++)
				{
					EliteTierDef val = CombatDirector.eliteTiers[i];
					if (!val.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
					{
						if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
						{
							Debug.LogFormat("Elite tier index {0} is unavailable", new object[1] { i });
						}
						continue;
					}
					float num3 = (float)self.currentMonsterCard.cost * val.costMultiplier * self.eliteBias;
					if (num3 <= self.monsterCredit)
					{
						num = i + 1;
						num2 = val.costMultiplier;
						if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
						{
							Debug.LogFormat("Found valid elite tier index {0}", new object[1] { i });
						}
					}
					else if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
					{
						Debug.LogFormat("Elite tier index {0} is too expensive ({1}/{2})", new object[3] { i, num3, self.monsterCredit });
					}
				}
				if (num > 1)
				{
					int num4 = num;
					EliteSelection.Clear();
					while (num4 > 0)
					{
						num4--;
						EliteTierDef val2 = CombatDirector.eliteTiers[num4];
						if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
						{
							ManualLogSource log = Log;
							EliteDef obj = val2.eliteTypes[0];
							log.LogDebug((object)$"Testing {((obj != null) ? ((Object)obj).name : null)}: {num2} ({val2.costMultiplier == num2})");
						}
						if (val2.costMultiplier > num2 || !val2.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
						{
							break;
						}
						EliteSelection.AddChoice(val2, (float)val2.eliteTypes.Count((EliteDef x) => Object.op_Implicit((Object)(object)x) && x.IsAvailable()));
					}
					self.currentActiveEliteTier = EliteSelection.Evaluate(self.rng.nextNormalizedFloat);
				}
				else
				{
					self.currentActiveEliteTier = CombatDirector.eliteTiers[0];
				}
			}

			internal bool <Awake>b__30_48(EliteDef x)
			{
				return Object.op_Implicit((Object)(object)x) && x.IsAvailable();
			}

			internal bool <Awake>b__30_46(Instruction x)
			{
				return ILPatternMatchingExt.MatchStfld(x, typeof(CombatDirector), "currentActiveEliteDef");
			}

			internal EliteDef <Awake>b__30_47(CombatDirector self)
			{
				EliteDef randomAvailableEliteDef = self.currentActiveEliteTier.GetRandomAvailableEliteDef(self.rng);
				if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
				{
					if ((Object)(object)self.currentActiveEliteTier.eliteTypes[0] != (Object)null)
					{
						Log.LogInfo((object)("Current EliteTier: " + ((Object)self.currentActiveEliteTier.eliteTypes[0]).name));
					}
					if ((Object)(object)randomAvailableEliteDef != (Object)null)
					{
						Log.LogInfo((object)("Current Elite: " + ((Object)randomAvailableEliteDef).name));
					}
				}
				return randomAvailableEliteDef;
			}

			internal void <Awake>b__30_9(orig_SetEquipmentIndex orig, Inventory self, EquipmentIndex equipmentIndex)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: 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)
				CharacterMaster component = ((Component)self).gameObject.GetComponent<CharacterMaster>();
				Log.LogDebug((object)("setting equipment for:" + ((Object)component).name));
				if (!(((Object)component).name == "ArtifactShellMaster") || equipmentIndex != Equipment.AffixLunar.equipmentIndex)
				{
					orig.Invoke(self, equipmentIndex);
				}
			}

			internal void <ProperlySave>b__36_0(Dictionary<string, object> _)
			{
				<ProperlySave>g__save|36_1(savePath);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass30_1
		{
			public string[] T2s;

			public string[] T1Honors;

			public string[] T1s;

			public Func<EliteDef, bool> <>9__35;

			public Func<EliteDef, bool> <>9__36;

			public Func<EliteDef, bool> <>9__38;

			internal bool <Awake>b__35(EliteDef x)
			{
				return T2s.Contains((x != null) ? ((Object)x).name : null);
			}

			internal bool <Awake>b__36(EliteDef x)
			{
				return T1Honors.Contains((x != null) ? ((Object)x).name : null);
			}

			internal bool <Awake>b__38(EliteDef x)
			{
				return T1s.Contains((x != null) ? ((Object)x).name : null);
			}
		}

		public const string PluginGUID = "prodzpod.ProperLoop";

		public const string PluginAuthor = "prodzpod";

		public const string PluginName = "ProperLoop";

		public const string PluginVersion = "1.0.11";

		public static ManualLogSource Log;

		public static PluginInfo pluginInfo;

		public static Harmony Harmony;

		public static ConfigFile Config;

		public static ConfigEntry<int> ScavCost;

		public static ConfigEntry<int> ScavOnLevel;

		public static ConfigEntry<bool> ScavItemCountScale;

		public static ConfigEntry<string> EliteDisables;

		public static ConfigEntry<float> T1Cost;

		public static ConfigEntry<int> T1OnLevel;

		public static ConfigEntry<float> T2Cost;

		public static ConfigEntry<int> T2OnLevel;

		public static ConfigEntry<bool> T2OnHonor;

		public static ConfigEntry<int> LoopBossesOnLevel;

		public static ConfigEntry<int> LoopEnemiesOnLevel;

		public static ConfigEntry<int> PerfectedOnLevel;

		public static ConfigEntry<bool> PerfectedOnHonor;

		public static ConfigEntry<float> PerfectedCost;

		public static ConfigEntry<float> HonorMultiplier;

		public static ConfigEntry<float> SanctionMultiplier;

		public static InteractableSpawnCard TP;

		public static InteractableSpawnCard lunarTP;

		private static bool _thisInitialized = false;

		private static WeightedSelection<EliteTierDef> EliteSelection = new WeightedSelection<EliteTierDef>(8);

		public static int loops = 0;

		public static int stage = 0;

		public static string savePath = Path.Combine(Application.persistentDataPath, "ProperSave", "Saves") + "\\ProperLoop.csv";

		public void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			//IL_02bd: 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_02c8: Expected O, but got Unknown
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Expected O, but got Unknown
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Expected O, but got Unknown
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Expected O, but got Unknown
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Expected O, but got Unknown
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Expected O, but got Unknown
			pluginInfo = ((BaseUnityPlugin)this).Info;
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony = new Harmony("prodzpod.ProperLoop");
			Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "prodzpod.ProperLoop.cfg"), true);
			ScavCost = Config.Bind<int>("General", "Scavenger Cost", 2000, "Lower if you want scavs to spawn early. Vanilla by default.");
			ScavOnLevel = Config.Bind<int>("General", "Scavenger Stage", 6, "5 per Proper Loop. 0 to disable.");
			ScavItemCountScale = Config.Bind<bool>("General", "Scavenger Item Count Scale", true, "Make scavenger sacks drop items proportional to current stage number.");
			T1Cost = Config.Bind<float>("General", "Tier 1 Director Cost Multiplier", 1f, "Perfected on Moon also uses this.");
			T1OnLevel = Config.Bind<int>("General", "Tier 1 Elites Stage", 1, "5 per Proper Loop. 0 to disable. May break modded artifacts if changed.");
			T2Cost = Config.Bind<float>("General", "Tier 2 Director Cost Multiplier", 6f, "Vanilla value: 6.");
			T2OnLevel = Config.Bind<int>("General", "Tier 2 Elites Stage", 6, "5 per Proper Loop. 0 to disable. May break modded artifacts if changed.");
			T2OnHonor = Config.Bind<bool>("General", "Tier 2 on Honor", true, "add T2 Elites to Honor. extra chaos!");
			LoopBossesOnLevel = Config.Bind<int>("General", "Loop Bosses Stage", 6, "5 per Proper Loop. 0 to disable.");
			LoopEnemiesOnLevel = Config.Bind<int>("General", "Loop Enemies Stage", 6, "5 per Proper Loop. 0 to disable.");
			PerfectedOnLevel = Config.Bind<int>("General", "Perfected Elite Stage", 6, "5 per Proper Loop. 0 to disable. Enables perfected loop by default.");
			PerfectedOnHonor = Config.Bind<bool>("General", "Perfected on Honor", true, "add Perfected Elites to Honor. extra chaos!");
			PerfectedCost = Config.Bind<float>("General", "Perfected Director Cost Multiplier", 6f, "By default, equal to T2.");
			HonorMultiplier = Config.Bind<float>("General", "Artifact of Honor Stage Multiplier", 1f, "Rounded up.");
			SanctionMultiplier = Config.Bind<float>("General", "Artifact of Sanction Stage Multiplier", 0.5f, "Epic zetartifacts compat");
			EliteDisables = Config.Bind<string>("General", "Elite Disables", "", "List of EliteDef names to blacklist, separated by comma. Check log for names.");
			if (Chainloader.PluginInfos.ContainsKey("com.Moffein.AccurateEnemies"))
			{
				AccurateEnemiesFix.Init();
			}
			object obj = <>c.<>9__30_0;
			if (obj == null)
			{
				hook_Start val = delegate(orig_Start orig, Run self)
				{
					loops = 0;
					stage = 0;
					if (ScavItemCountScale.Value)
					{
						Opening.maxItemDropCount = 1;
					}
					orig.Invoke(self);
				};
				<>c.<>9__30_0 = val;
				obj = (object)val;
			}
			Run.Start += (hook_Start)obj;
			if (Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ProperSave"))
			{
				ProperlySave();
			}
			object obj2 = <>c.<>9__30_1;
			if (obj2 == null)
			{
				Manipulator val2 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val23 = new ILCursor(il);
					val23.GotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdfld<Run>(x, "stageClearCount")
					});
					val23.Emit(OpCodes.Pop);
					val23.EmitDelegate<Func<int>>((Func<int>)(() => loops * Run.stagesPerLoop + stage));
				};
				<>c.<>9__30_1 = val2;
				obj2 = (object)val2;
			}
			TeleporterInteraction.Start += (Manipulator)obj2;
			TP = LegacyResourcesAPI.Load<InteractableSpawnCard>("SpawnCards/InteractableSpawnCard/iscTeleporter");
			lunarTP = LegacyResourcesAPI.Load<InteractableSpawnCard>("SpawnCards/InteractableSpawnCard/iscLunarTeleporter");
			Stage.onServerStageComplete += delegate
			{
				GameObject? obj9 = ((IEnumerable<GameObject>)Object.FindObjectsOfType<GameObject>()).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => (Object)(object)x.GetComponent<TeleporterInteraction>() != (Object)null));
				TeleporterInteraction val22 = ((obj9 != null) ? obj9.GetComponent<TeleporterInteraction>() : null);
				if (!((Object)(object)val22 == (Object)null) && !((Object)(object)val22 == (Object)null))
				{
					stage++;
					if (((Object)((Component)val22).gameObject).name.Contains("LunarTeleporter"))
					{
						stage = 0;
						loops++;
					}
					if (ScavItemCountScale.Value)
					{
						Opening.maxItemDropCount = loops * Run.stagesPerLoop + stage + 1;
					}
				}
			};
			object obj3 = <>c.<>9__30_3;
			if (obj3 == null)
			{
				hook_PlaceTeleporter val3 = delegate(orig_PlaceTeleporter orig, SceneDirector self)
				{
					if ((Object)(object)self.teleporterSpawnCard != (Object)null)
					{
						self.teleporterSpawnCard = (SpawnCard)(object)((stage == Run.stagesPerLoop - 1) ? lunarTP : TP);
					}
					orig.Invoke(self);
				};
				<>c.<>9__30_3 = val3;
				obj3 = (object)val3;
			}
			SceneDirector.PlaceTeleporter += (hook_PlaceTeleporter)obj3;
			object obj4 = <>c.<>9__30_4;
			if (obj4 == null)
			{
				Manipulator val4 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val21 = new ILCursor(il);
					val21.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0)
					});
					val21.Emit(OpCodes.Pop);
					val21.EmitDelegate<Func<int>>((Func<int>)(() => loops));
				};
				<>c.<>9__30_4 = val4;
				obj4 = (object)val4;
			}
			LoopOnceAchievement.Check += (Manipulator)obj4;
			CharacterSpawnCard scav = LegacyResourcesAPI.Load<CharacterSpawnCard>("SpawnCards/CharacterSpawnCards/cscScav");
			ClassicStageInfo.RebuildCards += (Manipulator)delegate(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_017e: Unknown result type (might be due to invalid IL or missing references)
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val16 = new ILCursor(il);
				val16.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStfld<ClassicStageInfo>(x, "modifiableMonsterCategories")
				});
				val16.EmitDelegate<Func<DirectorCardCategorySelection, DirectorCardCategorySelection>>((Func<DirectorCardCategorySelection, DirectorCardCategorySelection>)delegate(DirectorCardCategorySelection orig)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_00fe: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
					for (int k = 0; k < orig.categories.Length; k++)
					{
						Category val19 = orig.categories[k];
						for (int l = 0; l < val19.cards.Length; l++)
						{
							DirectorCard val20 = val19.cards[l];
							if (val20.spawnCard is CharacterSpawnCard)
							{
								if ((Object)(object)val20.spawnCard == (Object)(object)scav)
								{
									val20.minimumStageCompletions = ScavOnLevel.Value - 1;
									val20.spawnCard.directorCreditCost = ScavCost.Value;
								}
								else if (val20.minimumStageCompletions > stage)
								{
									val20.minimumStageCompletions = Mathf.Max(0, val20.minimumStageCompletions + ((val19.name == "Champions") ? LoopBossesOnLevel.Value : LoopEnemiesOnLevel.Value) - 6);
								}
								val19.cards[l] = val20;
							}
						}
						orig.categories[k] = val19;
					}
					Log.LogDebug((object)("Enemy Stage Completion\n" + GeneralExtensions.Join<Category>((IEnumerable<Category>)orig.categories, (Func<Category, string>)((Category x) => GeneralExtensions.Join<DirectorCard>((IEnumerable<DirectorCard>)x.cards, (Func<DirectorCard, string>)delegate(DirectorCard y)
					{
						SpawnCard spawnCard = y.spawnCard;
						return (((spawnCard != null) ? ((Object)spawnCard).name : null) ?? "Null") + $" ({y.minimumStageCompletions})";
					}, ", ")), "\n")));
					return orig;
				});
				val16.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<MonsterFamily>(x, "minimumStageCompletion")
				});
				ILLabel val18 = default(ILLabel);
				val16.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchBgt(x, ref val18)
				});
				val16.Emit(OpCodes.Pop);
				val16.Emit(OpCodes.Pop);
				val16.Emit(OpCodes.Ldloc, 12);
				val16.EmitDelegate<Func<MonsterFamily, int>>((Func<MonsterFamily, int>)((MonsterFamily self) => StageCheck(self.minimumStageCompletion + 1) ? 1 : 0));
				val16.Emit(OpCodes.Ldc_I4_1);
				val16.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<MonsterFamily>(x, "maximumStageCompletion")
				});
				ILLabel val17 = default(ILLabel);
				val16.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchBle(x, ref val17)
				});
				val16.Emit(OpCodes.Pop);
				val16.Emit(OpCodes.Pop);
				val16.Emit(OpCodes.Ldloc, 12);
				val16.EmitDelegate<Func<MonsterFamily, int>>((Func<MonsterFamily, int>)((MonsterFamily self) => StageCheckMax(self.maximumStageCompletion + 1) ? 1 : 0));
				val16.Emit(OpCodes.Ldc_I4_1);
			};
			object obj5 = <>c.<>9__30_6;
			if (obj5 == null)
			{
				Manipulator val5 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_0067: Unknown result type (might be due to invalid IL or missing references)
					//IL_0073: Unknown result type (might be due to invalid IL or missing references)
					//IL_007f: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val15 = new ILCursor(il);
					val15.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdfld<DirectorCard>(x, "minimumStageCompletions")
					});
					val15.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchClt(x)
					});
					val15.Emit(OpCodes.Pop);
					val15.Emit(OpCodes.Pop);
					val15.Emit(OpCodes.Ldarg_0);
					val15.EmitDelegate<Func<DirectorCard, int>>((Func<DirectorCard, int>)((DirectorCard self) => StageCheck(self.minimumStageCompletions + 1) ? 1 : 0));
					val15.Emit(OpCodes.Ldc_I4_1);
				};
				<>c.<>9__30_6 = val5;
				obj5 = (object)val5;
			}
			DirectorCard.IsAvailable += (Manipulator)obj5;
			Harmony.PatchAll(typeof(PatchLoopGetter));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				//IL_0340: Unknown result type (might be due to invalid IL or missing references)
				//IL_0347: Expected O, but got Unknown
				//IL_0356: Unknown result type (might be due to invalid IL or missing references)
				//IL_035b: Unknown result type (might be due to invalid IL or missing references)
				if (!_thisInitialized)
				{
					Log.LogDebug((object)"EliteAPI, amarite?");
					List<string> list = EliteDisables.Value.Split(',').ToList().ConvertAll((string x) => x.Trim());
					string[] T1s = new string[4] { "edLightning", "edIce", "edFire", "edEarth" };
					string[] T1Honors = new string[4] { "edLightningHonor", "edIceHonor", "edFireHonor", "edEarthHonor" };
					string[] T2s = new string[2] { "edPoison", "edHaunted" };
					float costMultiplier = CombatDirector.baseEliteCostMultiplier * PerfectedCost.Value;
					List<EliteTierDef> list2 = new List<EliteTierDef>();
					for (int j = 0; j < CombatDirector.eliteTiers.Length; j++)
					{
						EliteTierDef val13 = CombatDirector.eliteTiers[j];
						if (val13.eliteTypes.Any((EliteDef x) => T2s.Contains((x != null) ? ((Object)x).name : null)))
						{
							list2.Add(val13);
							val13.costMultiplier *= T2Cost.Value / 6f;
							val13.isAvailable = (EliteRules rules) => (T2OnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(T2OnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
						}
						else if (val13.eliteTypes.Any((EliteDef x) => T1Honors.Contains((x != null) ? ((Object)x).name : null)))
						{
							val13.costMultiplier *= T1Cost.Value;
							val13.isAvailable = (EliteRules rules) => CombatDirector.IsEliteOnlyArtifactActive() && StageCheck(T1OnLevel.Value, HonorMultiplier.Value);
						}
						else if (PerfectedOnLevel.Value > 0 && val13.eliteTypes.Any((EliteDef x) => "edLunar" == ((x != null) ? ((Object)x).name : null)))
						{
							Log.LogDebug((object)"PerfectedLoop2 in Motion...");
							val13.costMultiplier *= T1Cost.Value;
							val13.isAvailable = (EliteRules rules) => (int)rules == 2 && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
						}
						else if (val13.eliteTypes.Any((EliteDef x) => T1s.Contains((x != null) ? ((Object)x).name : null)))
						{
							list2.Add(val13);
							val13.costMultiplier *= T1Cost.Value;
							costMultiplier = val13.costMultiplier;
							val13.isAvailable = (EliteRules rules) => CombatDirector.NotEliteOnlyArtifactActive() && (int)rules == 0 && StageCheck(T1OnLevel.Value);
						}
						CombatDirector.eliteTiers[j] = val13;
					}
					EliteTierDef val14 = new EliteTierDef();
					val14.eliteTypes = (EliteDef[])(object)new EliteDef[1] { Addressables.LoadAssetAsync<EliteDef>((object)"RoR2/Base/EliteLunar/edLunar.asset").WaitForCompletion() };
					val14.costMultiplier = costMultiplier;
					val14.isAvailable = (EliteRules rules) => (PerfectedOnHonor.Value || CombatDirector.NotEliteOnlyArtifactActive()) && StageCheck(PerfectedOnLevel.Value, CombatDirector.IsEliteOnlyArtifactActive() ? HonorMultiplier.Value : 1f);
					val14.canSelectWithoutAvailableEliteDef = false;
					list2.Add(val14);
					List<EliteTierDef> list3 = CombatDirector.eliteTiers.ToList();
					list3.RemoveAll(list2.Contains);
					list2.Sort((EliteTierDef a, EliteTierDef b) => (int)Mathf.Sign(a.costMultiplier - b.costMultiplier));
					list3.InsertRange(1, list2);
					CombatDirector.eliteTiers = list3.ToArray();
					_thisInitialized = true;
					Log.LogDebug((object)("Elites:\n\n" + GeneralExtensions.Join<EliteTierDef>((IEnumerable<EliteTierDef>)CombatDirector.eliteTiers, (Func<EliteTierDef, string>)((EliteTierDef x) => GeneralExtensions.Join<EliteDef>((IEnumerable<EliteDef>)x.eliteTypes, (Func<EliteDef, string>)((EliteDef y) => (y != null) ? ((Object)y).name : null), ", ") + $"({x.costMultiplier})"), "\n")));
				}
			});
			object obj6 = <>c.<>9__30_8;
			if (obj6 == null)
			{
				Manipulator val6 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
					//IL_0139: Unknown result type (might be due to invalid IL or missing references)
					//IL_0145: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val8 = new ILCursor(il);
					ILLabel val9 = null;
					val8.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Card {0} cannot be elite. Skipping elite procedure.")
					});
					val8.GotoPrev(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(CombatDirector), "cvDirectorCombatEnableInternalLogs")
					});
					int index = val8.Index;
					ILLabel val12 = default(ILLabel);
					val8.GotoPrev((MoveType)2, new Func<Instruction, bool>[2]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSpawnCard>(x, "noElites"),
						(Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val12)
					});
					val8.MoveAfterLabels();
					val8.RemoveRange(index - val8.Index);
					val8.Emit(OpCodes.Ldarg_0);
					val8.EmitDelegate<Action<CombatDirector>>((Action<CombatDirector>)delegate(CombatDirector self)
					{
						//IL_0025: Unknown result type (might be due to invalid IL or missing references)
						//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
						int num = 1;
						float num2 = 0f;
						for (int i = 1; i < CombatDirector.eliteTiers.Length; i++)
						{
							EliteTierDef val10 = CombatDirector.eliteTiers[i];
							if (!val10.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
							{
								if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
								{
									Debug.LogFormat("Elite tier index {0} is unavailable", new object[1] { i });
								}
							}
							else
							{
								float num3 = (float)self.currentMonsterCard.cost * val10.costMultiplier * self.eliteBias;
								if (num3 <= self.monsterCredit)
								{
									num = i + 1;
									num2 = val10.costMultiplier;
									if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
									{
										Debug.LogFormat("Found valid elite tier index {0}", new object[1] { i });
									}
								}
								else if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
								{
									Debug.LogFormat("Elite tier index {0} is too expensive ({1}/{2})", new object[3] { i, num3, self.monsterCredit });
								}
							}
						}
						if (num > 1)
						{
							int num4 = num;
							EliteSelection.Clear();
							while (num4 > 0)
							{
								num4--;
								EliteTierDef val11 = CombatDirector.eliteTiers[num4];
								if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
								{
									ManualLogSource log = Log;
									EliteDef obj8 = val11.eliteTypes[0];
									log.LogDebug((object)$"Testing {((obj8 != null) ? ((Object)obj8).name : null)}: {num2} ({val11.costMultiplier == num2})");
								}
								if (val11.costMultiplier > num2 || !val11.CanSelect(self.currentMonsterCard.spawnCard.eliteRules))
								{
									break;
								}
								EliteSelection.AddChoice(val11, (float)val11.eliteTypes.Count((EliteDef x) => Object.op_Implicit((Object)(object)x) && x.IsAvailable()));
							}
							self.currentActiveEliteTier = EliteSelection.Evaluate(self.rng.nextNormalizedFloat);
						}
						else
						{
							self.currentActiveEliteTier = CombatDirector.eliteTiers[0];
						}
					});
					val8.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchStfld(x, typeof(CombatDirector), "currentActiveEliteDef")
					});
					val8.Emit(OpCodes.Pop);
					val8.Emit(OpCodes.Ldarg_0);
					val8.EmitDelegate<Func<CombatDirector, EliteDef>>((Func<CombatDirector, EliteDef>)delegate(CombatDirector self)
					{
						EliteDef randomAvailableEliteDef = self.currentActiveEliteTier.GetRandomAvailableEliteDef(self.rng);
						if (CombatDirector.cvDirectorCombatEnableInternalLogs.value)
						{
							if ((Object)(object)self.currentActiveEliteTier.eliteTypes[0] != (Object)null)
							{
								Log.LogInfo((object)("Current EliteTier: " + ((Object)self.currentActiveEliteTier.eliteTypes[0]).name));
							}
							if ((Object)(object)randomAvailableEliteDef != (Object)null)
							{
								Log.LogInfo((object)("Current Elite: " + ((Object)randomAvailableEliteDef).name));
							}
						}
						return randomAvailableEliteDef;
					});
				};
				<>c.<>9__30_8 = val6;
				obj6 = (object)val6;
			}
			CombatDirector.PrepareNewMonsterWave += (Manipulator)obj6;
			object obj7 = <>c.<>9__30_9;
			if (obj7 == null)
			{
				hook_SetEquipmentIndex val7 = delegate(orig_SetEquipmentIndex orig, Inventory self, EquipmentIndex equipmentIndex)
				{
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0040: 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)
					CharacterMaster component = ((Component)self).gameObject.GetComponent<CharacterMaster>();
					Log.LogDebug((object)("setting equipment for:" + ((Object)component).name));
					if (!(((Object)component).name == "ArtifactShellMaster") || equipmentIndex != Equipment.AffixLunar.equipmentIndex)
					{
						orig.Invoke(self, equipmentIndex);
					}
				};
				<>c.<>9__30_9 = val7;
				obj7 = (object)val7;
			}
			Inventory.SetEquipmentIndex += (hook_SetEquipmentIndex)obj7;
		}

		public static bool StageCheck(int onLevel, float multiplier = 1f)
		{
			if (onLevel == 0)
			{
				return false;
			}
			if (Chainloader.PluginInfos.ContainsKey("com.TPDespair.ZetArtifacts") && EarlifactActive())
			{
				multiplier *= SanctionMultiplier.Value;
			}
			onLevel = Mathf.CeilToInt((float)onLevel * multiplier) - 1;
			return loops > onLevel / Run.stagesPerLoop || (loops == onLevel / Run.stagesPerLoop && stage >= onLevel % Run.stagesPerLoop);
		}

		public static bool StageCheckMax(int onLevel, float multiplier = 1f)
		{
			if (onLevel == 0)
			{
				return false;
			}
			if (Chainloader.PluginInfos.ContainsKey("com.TPDespair.ZetArtifacts") && EarlifactActive())
			{
				multiplier *= SanctionMultiplier.Value;
			}
			onLevel = Mathf.CeilToInt((float)onLevel * multiplier) - 1;
			return loops < onLevel / Run.stagesPerLoop || (loops == onLevel / Run.stagesPerLoop && stage < onLevel % Run.stagesPerLoop);
		}

		public static bool EarlifactActive()
		{
			return RunArtifactManager.instance.IsArtifactEnabled(ZetEarlifact.ArtifactDef);
		}

		public static void ProperlySave()
		{
			SaveFile.OnGatherSaveData += delegate
			{
				save(savePath);
			};
			if (File.Exists(savePath))
			{
				J.load();
			}
			static void save(string path)
			{
				File.WriteAllText(path, $"loops,{loops}\nstage,{stage}");
			}
		}

		[CompilerGenerated]
		internal static void <ProperlySave>g__save|36_1(string path)
		{
			File.WriteAllText(path, $"loops,{loops}\nstage,{stage}");
		}
	}
}