Decompiled source of EnemyRandomizer v1.3.1

EnemyRandomizer.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LBoL.Base;
using LBoL.Base.Extensions;
using LBoL.ConfigData;
using LBoL.Core;
using LBoL.Core.Battle;
using LBoL.Core.Battle.BattleActions;
using LBoL.Core.Stations;
using LBoL.Core.StatusEffects;
using LBoL.Core.Units;
using LBoL.EntityLib.EnemyUnits.Character;
using LBoL.EntityLib.EnemyUnits.Normal;
using LBoL.EntityLib.EnemyUnits.Normal.Bats;
using LBoL.EntityLib.EnemyUnits.Normal.Drones;
using LBoL.EntityLib.EnemyUnits.Normal.Guihuos;
using LBoL.EntityLib.EnemyUnits.Normal.Maoyus;
using LBoL.EntityLib.EnemyUnits.Normal.Ravens;
using LBoL.EntityLib.EnemyUnits.Normal.Shenlings;
using LBoL.EntityLib.EnemyUnits.Normal.Yinyangyus;
using LBoLEntitySideloader;
using LBoLEntitySideloader.Attributes;
using LBoLEntitySideloader.Entities;
using LBoLEntitySideloader.PersistentValues;
using LBoLEntitySideloader.Resource;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("LBoL.Base")]
[assembly: IgnoresAccessChecksTo("LBoL.ConfigData")]
[assembly: IgnoresAccessChecksTo("LBoL.Core")]
[assembly: IgnoresAccessChecksTo("LBoL.EntityLib")]
[assembly: IgnoresAccessChecksTo("LBoL.Presentation")]
[assembly: IgnoresAccessChecksTo("Untitled.ConfigDataBuilder.Base")]
[assembly: AssemblyCompany("EnemyRandomizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3963626210047116635d081a7311f9d44ae4af32")]
[assembly: AssemblyProduct("EnemyRandomizer")]
[assembly: AssemblyTitle("EnemyRandomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace EnemyRandomizer
{
	[BepInPlugin("cramps-enemyrandomizer", "EnemyRandomizer", "1.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("LBoL.exe")]
	public class BepinexPlugin : BaseUnityPlugin
	{
		private static readonly Harmony harmony = PInfo.harmony;

		internal static ManualLogSource log;

		internal static TemplateSequenceTable sequenceTable = new TemplateSequenceTable(0);

		internal static IResourceSource embeddedSource = (IResourceSource)new EmbeddedSource(Assembly.GetExecutingAssembly());

		internal static DirectorySource directorySource = new DirectorySource("cramps-enemyrandomizer", "");

		internal static BatchLocalization jadeboxLoc = new BatchLocalization((IResourceSource)(object)directorySource, typeof(JadeBoxTemplate), "jadebox", (Locale)0, false);

		internal static BatchLocalization StatusEffectsBatchLoc = new BatchLocalization((IResourceSource)(object)directorySource, typeof(StatusEffectTemplate), "statusEffect", (Locale)0, false);

		internal static string CUSTOM_EIGHT_FORMATION = "8custom";

		internal static CustomGameRunSaveData previousEncounterSaveData = (CustomGameRunSaveData)(object)new PreviousEncounterSaveData();

		private void Awake()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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)
			log = ((BaseUnityPlugin)this).Logger;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			EntityManager.RegisterSelf();
			previousEncounterSaveData.RegisterSelf("cramps-enemyrandomizer");
			harmony.PatchAll();
			EnemyGroupTemplate.AddFormation(CUSTOM_EIGHT_FORMATION, new Dictionary<int, Vector2>
			{
				{
					0,
					new Vector2(-1f, 2f)
				},
				{
					1,
					new Vector2(-1f, -1f)
				},
				{
					2,
					new Vector2(0.5f, 0.5f)
				},
				{
					3,
					new Vector2(2f, 2f)
				},
				{
					4,
					new Vector2(2f, -1f)
				},
				{
					5,
					new Vector2(3.5f, 0.5f)
				},
				{
					6,
					new Vector2(5f, 2f)
				},
				{
					7,
					new Vector2(5f, -1f)
				}
			}, (Assembly)null);
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class PInfo
	{
		public const string GUID = "cramps-enemyrandomizer";

		public const string Name = "EnemyRandomizer";

		public const string version = "1.3.1";

		public static readonly Harmony harmony = new Harmony("cramps-enemyrandomizer");
	}
	public sealed class EndOfTurnFpSeDef : StatusEffectTemplate
	{
		public override IdContainer GetId()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			string name = ((object)this).GetType().Name;
			return IdContainer.op_Implicit(name.Remove(name.Length - 3));
		}

		public override LocalizationOption LoadLocalization()
		{
			return (LocalizationOption)(object)BepinexPlugin.StatusEffectsBatchLoc.AddEntity((EntityDefinition)(object)this);
		}

		public override Sprite LoadSprite()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = ResourceLoader.LoadSprite(IdContainer.op_Implicit(((EntityDefinition)this).GetId()) + ".png", BepinexPlugin.embeddedSource, (Rect?)null, 1, (Vector2?)null);
			if ((Object)(object)val == (Object)null)
			{
				return ResourceLoader.LoadSprite("dummyicon.png", BepinexPlugin.embeddedSource, (Rect?)null, 1, (Vector2?)null);
			}
			return val;
		}

		public override StatusEffectConfig MakeConfig()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			return new StatusEffectConfig(0, "", 17, (StatusEffectType)0, false, true, (int?)null, true, (StackType?)(StackType)0, false, (StackType?)(StackType)0, (DurationDecreaseTiming)0, false, (StackType?)(StackType)3, (StackType?)(StackType)3, false, (Keyword)0, (IReadOnlyList<string>)new List<string>(), (string)null, "Default", "Default", "Default");
		}
	}
	[EntityLogic(typeof(EndOfTurnFpSeDef))]
	public sealed class EndOfTurnFpSe : StatusEffect
	{
		protected override void OnAdded(Unit unit)
		{
			((StatusEffect)this).ReactOwnerEvent<GameEventArgs>(((StatusEffect)this).Battle.AllEnemyTurnEnded, (EventSequencedReactor<GameEventArgs>)OnAllEnemyTurnEnded);
		}

		private IEnumerable<BattleAction> OnAllEnemyTurnEnded(GameEventArgs args)
		{
			if (!((StatusEffect)this).Battle.BattleShouldEnd)
			{
				((StatusEffect)this).NotifyActivating();
				yield return (BattleAction)(object)new ApplyStatusEffectAction<Firepower>(((StatusEffect)this).Owner, (int?)((StatusEffect)this).Level, (int?)null, (int?)null, (int?)null, 0f, true);
				yield return (BattleAction)new RemoveStatusEffectAction((StatusEffect)(object)this, true, 0.1f);
			}
		}
	}
	[HarmonyPatch]
	internal class EnemyPatches
	{
		[HarmonyPatch(typeof(Sunny), "OnEnterBattle")]
		private static bool Prefix(Sunny __instance)
		{
			if (!((GameEntity)__instance).GameRun.HasJadeBox<EnemyRandomizerJadebox>())
			{
				return true;
			}
			((LightFairy)__instance).Spell();
			return false;
		}

		[HarmonyPatch(typeof(Unit), "OnEnterBattle")]
		private static bool Prefix(Unit __instance)
		{
			if (!((GameEntity)__instance).GameRun.HasJadeBox<EnemyRandomizerJadebox>())
			{
				return true;
			}
			LightFairy val = (LightFairy)(object)((__instance is LightFairy) ? __instance : null);
			if (val != null)
			{
				val.Spell();
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal class EnemyRandomizer
	{
		internal struct EnemyActWeights
		{
			public int Act1;

			public int Act2;

			public int Act3;

			public EnemyActWeights(int act1, int act2, int act3)
			{
				Act1 = act1;
				Act2 = act2;
				Act3 = act3;
			}

			public int GetWeight(int act)
			{
				if (1 == 0)
				{
				}
				int result = act switch
				{
					1 => Act1, 
					2 => Act2, 
					3 => Act3, 
					_ => -1, 
				};
				if (1 == 0)
				{
				}
				return result;
			}
		}

		private const int MAX_POTENTIAL_ENCOUNTERS = 25;

		private const int MAX_ROLLS = 500;

		internal static List<Type> previousEncounter = new List<Type>();

		internal static List<List<Type>> allSeenEncounters = new List<List<Type>>();

		internal static Dictionary<string, int> actWeights = new Dictionary<string, int>
		{
			{ "1-1", 40 },
			{ "1-2", 60 },
			{ "1-3", 70 },
			{ "1-e", 100 },
			{ "2-1", 110 },
			{ "2-2", 125 },
			{ "2-3", 140 },
			{ "2-e", 190 },
			{ "3-1", 210 },
			{ "3-2", 230 },
			{ "3-3", 250 },
			{ "3-e", 360 }
		};

		internal static Dictionary<Type, EnemyActWeights> enemyWeights = new Dictionary<Type, EnemyActWeights>
		{
			{
				typeof(WhiteFairy),
				new EnemyActWeights(40, 40, 40)
			},
			{
				typeof(RavenWen),
				new EnemyActWeights(15, 20, 25)
			},
			{
				typeof(RavenGuo),
				new EnemyActWeights(15, 20, 25)
			},
			{
				typeof(GuihuoBlue),
				new EnemyActWeights(20, 25, 30)
			},
			{
				typeof(GuihuoGreen),
				new EnemyActWeights(20, 25, 30)
			},
			{
				typeof(GuihuoRed),
				new EnemyActWeights(30, 35, 40)
			},
			{
				typeof(SickGirl),
				new EnemyActWeights(20, 25, 30)
			},
			{
				typeof(YinyangyuRed),
				new EnemyActWeights(20, 20, 20)
			},
			{
				typeof(YinyangyuBlue),
				new EnemyActWeights(30, 35, 40)
			},
			{
				typeof(DollBlue),
				new EnemyActWeights(50, 75, 100)
			},
			{
				typeof(DollPurple),
				new EnemyActWeights(50, 75, 100)
			},
			{
				typeof(FraudRabbit),
				new EnemyActWeights(40, 60, 80)
			},
			{
				typeof(BlackFairy),
				new EnemyActWeights(60, 70, 80)
			},
			{
				typeof(Bat),
				new EnemyActWeights(25, 40, 55)
			},
			{
				typeof(MaoyuBlue),
				new EnemyActWeights(10, 10, 10)
			},
			{
				typeof(Maoyu),
				new EnemyActWeights(15, 15, 15)
			},
			{
				typeof(MaoyuRed),
				new EnemyActWeights(10, 10, 10)
			},
			{
				typeof(MaoyuBlack),
				new EnemyActWeights(25, 25, 25)
			},
			{
				typeof(Sunny),
				new EnemyActWeights(40, 40, 40)
			},
			{
				typeof(Luna),
				new EnemyActWeights(45, 60, 75)
			},
			{
				typeof(Star),
				new EnemyActWeights(45, 75, 100)
			},
			{
				typeof(Aya),
				new EnemyActWeights(70, 85, 100)
			},
			{
				typeof(Rin),
				new EnemyActWeights(70, 70, 70)
			},
			{
				typeof(Purifier),
				new EnemyActWeights(50, 65, 80)
			},
			{
				typeof(Scout),
				new EnemyActWeights(50, 65, 80)
			},
			{
				typeof(WaterGirl),
				new EnemyActWeights(-1, 100, 120)
			},
			{
				typeof(Yaoshi),
				new EnemyActWeights(45, 60, 75)
			},
			{
				typeof(Fox),
				new EnemyActWeights(-1, 120, 180)
			},
			{
				typeof(BatLord),
				new EnemyActWeights(60, 80, 100)
			},
			{
				typeof(HetongKailang),
				new EnemyActWeights(60, 80, 100)
			},
			{
				typeof(HetongYinchen),
				new EnemyActWeights(40, 40, 40)
			},
			{
				typeof(ShenlingPurple),
				new EnemyActWeights(30, 30, 30)
			},
			{
				typeof(ShenlingWhite),
				new EnemyActWeights(30, 30, 30)
			},
			{
				typeof(Nitori),
				new EnemyActWeights(-1, 130, 150)
			},
			{
				typeof(Youmu),
				new EnemyActWeights(-1, 130, 150)
			},
			{
				typeof(Kokoro),
				new EnemyActWeights(-1, 130, 150)
			},
			{
				typeof(YaTiangou),
				new EnemyActWeights(-1, 130, 150)
			},
			{
				typeof(LangTiangou),
				new EnemyActWeights(-1, 130, 150)
			},
			{
				typeof(LoveGirl),
				new EnemyActWeights(-1, 190, 230)
			},
			{
				typeof(Terminator),
				new EnemyActWeights(-1, 100, 120)
			},
			{
				typeof(HardworkRabbit),
				new EnemyActWeights(-1, 150, 180)
			},
			{
				typeof(LazyRabbit),
				new EnemyActWeights(-1, 150, 180)
			},
			{
				typeof(KanakoLimao),
				new EnemyActWeights(-1, 140, 160)
			},
			{
				typeof(SuwakoLimao),
				new EnemyActWeights(-1, 120, 150)
			},
			{
				typeof(Clownpiece),
				new EnemyActWeights(-1, -1, 240)
			},
			{
				typeof(Siji),
				new EnemyActWeights(-1, -1, 240)
			},
			{
				typeof(Doremy),
				new EnemyActWeights(-1, -1, 240)
			}
		};

		private static List<Type> supportEnemies = new List<Type>
		{
			typeof(GuihuoBlue),
			typeof(GuihuoGreen),
			typeof(GuihuoRed),
			typeof(SickGirl),
			typeof(YinyangyuBlue),
			typeof(FraudRabbit),
			typeof(Bat),
			typeof(Luna),
			typeof(Star),
			typeof(Purifier),
			typeof(Scout),
			typeof(Fox),
			typeof(BatLord),
			typeof(HetongKailang),
			typeof(HetongYinchen),
			typeof(SuwakoLimao)
		};

		private static List<Type> summonerEnemies = new List<Type>
		{
			typeof(Rin),
			typeof(Nitori),
			typeof(Kokoro),
			typeof(KanakoLimao),
			typeof(Clownpiece),
			typeof(Siji),
			typeof(Doremy)
		};

		private static List<Type> gloomyKappaRequirements = new List<Type>
		{
			typeof(Purifier),
			typeof(Scout),
			typeof(Terminator),
			typeof(Nitori)
		};

		[HarmonyPatch(typeof(BattleStation), "OnEnter")]
		private static void Postfix(BattleStation __instance)
		{
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Expected O, but got Unknown
			//IL_0702: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0736: Unknown result type (might be due to invalid IL or missing references)
			//IL_0740: Expected O, but got Unknown
			if (!(__instance is EnemyStation) && !(__instance is EliteEnemyStation))
			{
				BepinexPlugin.log.LogInfo((object)"Not enemy or elite station");
				return;
			}
			if (!((Station)__instance).GameRun.HasJadeBox<EnemyRandomizerJadebox>())
			{
				BepinexPlugin.log.LogInfo((object)"Jadebox not enabled");
				return;
			}
			BepinexPlugin.log.LogInfo((object)"===NEW COMBAT===");
			BepinexPlugin.log.LogInfo((object)("Act: " + ((Station)__instance).Stage.Level + " - Act section: " + ((Station)__instance).Act));
			int maxActWeight = GetActWeight(((Station)__instance).Stage.Level, ((Station)__instance).Act, __instance is EliteEnemyStation);
			BepinexPlugin.log.LogInfo((object)("Max Act weight: " + maxActWeight));
			int num = maxActWeight - 10 - maxActWeight / 8;
			BepinexPlugin.log.LogInfo((object)("Min weight leeway: " + num));
			BepinexPlugin.log.LogInfo((object)("Previous encounter: " + string.Join(", ", previousEncounter.ConvertAll((Type t) => t.Name))));
			BepinexPlugin.log.LogInfo((object)"Previous formations: ");
			allSeenEncounters.ForEach(delegate(List<Type> se)
			{
				BepinexPlugin.log.LogInfo((object)(" - " + string.Join(", ", se.ConvertAll((Type t) => t.Name))));
			});
			List<List<(Type, int)>> list = new List<List<(Type, int)>>();
			int num2 = 0;
			do
			{
				List<(Type, int)> list2 = new List<(Type, int)>();
				int firstEnemyMinWeight = ((Station)__instance).GameRun.StationRng.NextInt(0, maxActWeight);
				int num3 = ((Station)__instance).GameRun.StationRng.NextInt(1, 3);
				int num4 = ((Station)__instance).GameRun.StationRng.NextInt(3, 5);
				BepinexPlugin.log.LogInfo((object)("First enemy min weight: " + firstEnemyMinWeight + " - min enemies: " + num3 + " - max enemies: " + num4 + " - num roll: " + num2));
				do
				{
					KeyValuePair<Type, EnemyActWeights> keyValuePair = CollectionsExtensions.SampleOrDefault<KeyValuePair<Type, EnemyActWeights>>(enemyWeights.Where((KeyValuePair<Type, EnemyActWeights> w) => w.Value.GetWeight(((Station)__instance).Stage.Level) >= firstEnemyMinWeight && w.Value.GetWeight(((Station)__instance).Stage.Level) <= maxActWeight), ((Station)__instance).GameRun.StationRng);
					firstEnemyMinWeight = 0;
					if (!(keyValuePair.Key == null))
					{
						int weight = keyValuePair.Value.GetWeight(((Station)__instance).Stage.Level);
						list2.Add((keyValuePair.Key, weight));
						BepinexPlugin.log.LogInfo((object)("chosen cand: " + keyValuePair.Key.Name + " - " + weight + " - sum: " + list2.Sum<(Type, int)>(((Type type, int weight) c) => c.weight)));
					}
				}
				while (list2.Sum<(Type, int)>(((Type type, int weight) c) => c.weight) < maxActWeight && list2.Count < num4);
				if (list2.Sum<(Type, int)>(((Type type, int weight) c) => c.weight) > maxActWeight)
				{
					(Type, int) item = list2.Last();
					BepinexPlugin.log.LogInfo((object)("To remove: " + item.Item1.Name));
					list2.Remove(item);
				}
				if (++num2 > 500)
				{
					break;
				}
				BepinexPlugin.log.LogInfo((object)("Total weight: " + list2.Sum<(Type, int)>(((Type type, int weight) c) => c.weight)));
				if (list2.Sum<(Type, int)>(((Type type, int weight) c) => c.weight) < num)
				{
					BepinexPlugin.log.LogInfo((object)"===INVALID: Below min weight===");
				}
				else if (list2.Count < num3)
				{
					BepinexPlugin.log.LogInfo((object)"===INVALID: Less than min enemies===");
				}
				else if (IsValidEncounter(list2))
				{
					BepinexPlugin.log.LogInfo((object)"===Added enemy group===");
					list.Add(list2);
				}
			}
			while (list.Count < 25);
			if (list.Count <= 0)
			{
				BepinexPlugin.log.LogInfo((object)"===Potential encounters empty===");
				return;
			}
			List<EntrySource> list3 = new List<EntrySource>();
			List<int> list4 = new List<int> { 3, 4, 5, 6, 7 };
			previousEncounter.Clear();
			foreach (var (type, num5) in CollectionsExtensions.Sample<List<(Type, int)>>((IEnumerable<List<(Type, int)>>)list, ((Station)__instance).GameRun.StationRng))
			{
				previousEncounter.Add(type);
				int num6 = CollectionsExtensions.SampleOrDefault<int>((IEnumerable<int>)list4, ((Station)__instance).GameRun.StationRng);
				if (num6 == 0)
				{
					break;
				}
				list4.Remove(num6);
				list3.Add(new EntrySource(type, num6));
			}
			allSeenEncounters.Add(list3.Select((EntrySource es) => es.Type).ToList());
			EnemyGroup enemyGroup = __instance.EnemyGroup;
			__instance.EnemyGroup = new EnemyGroup(enemyGroup.Id, (IEnumerable<EntrySource>)list3, enemyGroup.EnemyType, BepinexPlugin.CUSTOM_EIGHT_FORMATION, enemyGroup.PlayerRootV2, enemyGroup.PreBattleDialogName, enemyGroup.PostBattleDialogName, enemyGroup.Hidden, enemyGroup.DebutTime, enemyGroup.Environment);
			foreach (EnemyUnit item2 in __instance.EnemyGroup)
			{
				((Unit)item2).EnterGameRun(((Station)__instance).GameRun);
			}
		}

		internal static int GetActWeight(int act, int actSection, bool isElite)
		{
			return isElite ? actWeights[act + "-e"] : actWeights[act + "-" + actSection];
		}

		private static bool IsValidEncounter(List<(Type type, int weight)> candidates)
		{
			if (previousEncounter.Any((Type pe) => candidates.Select(((Type type, int weight) c) => c.type).Contains(pe)))
			{
				BepinexPlugin.log.LogInfo((object)"===INVALID: matches 1 or more enemy types from previous encounter===");
				return false;
			}
			if (candidates.Count == 1 && candidates.Any(((Type type, int weight) c) => supportEnemies.Contains(c.type)))
			{
				BepinexPlugin.log.LogInfo((object)"===INVALID: solo support unit===");
				return false;
			}
			if (candidates.Where(((Type type, int weight) c) => summonerEnemies.Contains(c.type)).Count() > 1)
			{
				BepinexPlugin.log.LogInfo((object)"===INVALID: more than 1 summoner===");
				return false;
			}
			if (candidates.Any(((Type type, int weight) c) => c.type == typeof(HetongYinchen)) && !candidates.Any(((Type type, int weight) c) => gloomyKappaRequirements.Contains(c.type)))
			{
				BepinexPlugin.log.LogInfo((object)"==INVALID: gloomy kappa without drone or nitori===");
				return false;
			}
			if (allSeenEncounters.Any((List<Type> se) => se.OrderBy((Type se2) => se2.Name).SequenceEqual(from c in candidates
				select c.type into c
				orderby c.Name
				select c)))
			{
				BepinexPlugin.log.LogInfo((object)"==INVALID: matches a formation seen previously this run===");
				return false;
			}
			return true;
		}
	}
	public sealed class EnemyRandomizerJadeboxDef : JadeBoxTemplate
	{
		public override IdContainer GetId()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return IdContainer.op_Implicit("EnemyRandomizerJadebox");
		}

		public override LocalizationOption LoadLocalization()
		{
			return (LocalizationOption)(object)BepinexPlugin.jadeboxLoc.AddEntity((EntityDefinition)(object)this);
		}

		public override JadeBoxConfig MakeConfig()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			return new JadeBoxConfig(0, "", 10, (IReadOnlyList<string>)new List<string>(), (int?)null, (int?)null, (int?)null, (ManaGroup?)null, (Keyword)0, (IReadOnlyList<string>)new List<string>(), (IReadOnlyList<string>)new List<string>());
		}
	}
	[EntityLogic(typeof(EnemyRandomizerJadeboxDef))]
	public sealed class EnemyRandomizerJadebox : JadeBox
	{
		protected override void OnEnterBattle()
		{
			if (((GameEntity)this).GameRun.CurrentStation is EnemyStation || ((GameEntity)this).GameRun.CurrentStation is EliteEnemyStation)
			{
				((JadeBox)this).HandleBattleEvent<GameEventArgs>(((JadeBox)this).Battle.BattleStarted, (GameEventHandler<GameEventArgs>)OnBattleStarted);
				((JadeBox)this).ReactBattleEvent<StatusEffectApplyEventArgs>(((Unit)((JadeBox)this).Battle.Player).StatusEffectAdding, (EventSequencedReactor<StatusEffectApplyEventArgs>)OnPlayerStatusEffectAdding);
				((JadeBox)this).HandleBattleEvent<DieEventArgs>(((JadeBox)this).Battle.EnemyPointGenerating, (GameEventHandler<DieEventArgs>)OnEnemyPointGenerating);
			}
		}

		private void OnEnemyPointGenerating(DieEventArgs args)
		{
			int actWeight = EnemyRandomizer.GetActWeight(((GameEntity)this).GameRun.CurrentStage.Level, 0, isElite: true);
			if (EnemyRandomizer.enemyWeights.TryGetValue(((object)args.Unit).GetType(), out var value))
			{
				int weight = value.GetWeight(((GameEntity)this).GameRun.CurrentStage.Level);
				if (weight >= 0)
				{
					float num = (float)weight / (float)actWeight;
					BepinexPlugin.log.LogInfo((object)("Act max weight: " + actWeight + " - Enemy weight: " + weight + " - Percentage: " + num));
					int num2 = ((GameEntity)this).GameRun.BattleRng.NextInt(1, 3);
					int num3 = (int)(30f * num);
					BepinexPlugin.log.LogInfo((object)("New enemy power: " + num3 + " - Bonus power: " + num2));
					args.Power = num3 + num2;
				}
			}
		}

		private IEnumerable<BattleAction> OnPlayerStatusEffectAdding(StatusEffectApplyEventArgs args)
		{
			if (args.Effect is LockedOn)
			{
				GameEntity actionSource = ((GameEventArgs)args).ActionSource;
				Star s = (Star)(object)((actionSource is Star) ? actionSource : null);
				if (s != null)
				{
					((GameEventArgs)args).ForceCancelBecause((CancelCause)4096);
					yield return (BattleAction)(object)new ApplyStatusEffectAction<EnemyLockedOn>((Unit)(object)s, args.Level, (int?)null, (int?)null, (int?)null, 0f, true);
				}
			}
		}

		private void OnBattleStarted(GameEventArgs args)
		{
			foreach (EnemyUnit allAliveEnemy in ((JadeBox)this).Battle.AllAliveEnemies)
			{
				((JadeBox)this).ReactBattleEvent<StatusEffectApplyEventArgs>(((Unit)allAliveEnemy).StatusEffectAdding, (EventSequencedReactor<StatusEffectApplyEventArgs>)OnEnemyStatusEffectAdding);
			}
			((JadeBox)this).HandleBattleEvent<UnitEventArgs>(((JadeBox)this).Battle.EnemySpawned, (GameEventHandler<UnitEventArgs>)OnEnemySpawned);
		}

		private void OnEnemySpawned(UnitEventArgs args)
		{
			((JadeBox)this).ReactBattleEvent<StatusEffectApplyEventArgs>(args.Unit.StatusEffectAdding, (EventSequencedReactor<StatusEffectApplyEventArgs>)OnEnemyStatusEffectAdding);
		}

		private IEnumerable<BattleAction> OnEnemyStatusEffectAdding(StatusEffectApplyEventArgs args)
		{
			if (args.Effect is Firepower && !(((GameEventArgs)args).ActionSource is EndOfTurnFpSe))
			{
				((GameEventArgs)args).ForceCancelBecause((CancelCause)4096);
				yield return (BattleAction)(object)new ApplyStatusEffectAction<EndOfTurnFpSe>(args.Unit, args.Level, (int?)null, (int?)null, (int?)null, 0f, true);
			}
		}
	}
	public sealed class PreviousEncounterSaveData : CustomGameRunSaveData
	{
		public List<Type> previousEncounter = new List<Type>();

		public List<List<Type>> allSeenEncounters = new List<List<Type>>();

		public override string Name => ((object)this).GetType().Name;

		public override void Restore(GameRunController gameRun)
		{
			EnemyRandomizer.previousEncounter.Clear();
			EnemyRandomizer.previousEncounter.AddRange(previousEncounter);
			EnemyRandomizer.allSeenEncounters.Clear();
			EnemyRandomizer.allSeenEncounters.AddRange(allSeenEncounters);
		}

		public override void Save(GameRunController gameRun)
		{
			previousEncounter.Clear();
			previousEncounter.AddRange(EnemyRandomizer.previousEncounter);
			allSeenEncounters.Clear();
			allSeenEncounters.AddRange(EnemyRandomizer.allSeenEncounters);
		}

		public override void OnGamerunEnded()
		{
			EnemyRandomizer.previousEncounter.Clear();
			EnemyRandomizer.allSeenEncounters.Clear();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}