Decompiled source of EvolutionEquipment v1.0.3

plugins/EvolutionEquipment.dll

Decompiled 6 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.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using IL.RoR2;
using IL.RoR2.Artifacts;
using IL.RoR2.UI;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.UI;
using RoR2;
using RoR2.Artifacts;
using RoR2.CharacterAI;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Chinchi")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Enemies get an equipment with the Artifact of Evolution and in Simulacrum")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+435760dfc9a420a46979465fdddf85ecf6bf45af")]
[assembly: AssemblyProduct("EvolutionEquipment")]
[assembly: AssemblyTitle("EvolutionEquipment")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/schinchi/EvolutionEquipment")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[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 EvolutionEquipment
{
	internal class Configuration
	{
		internal static ConfigEntry<bool> isSimulacrumEnabled;

		internal static ConfigEntry<bool> rerollLunar;

		internal static ConfigEntry<float> humanDistanceThreshold;

		internal static ConfigEntry<float> humanHealthThreshold;

		internal static ConfigEntry<float> golemDistanceThreshold;

		internal static ConfigEntry<float> golemHealthThreshold;

		internal static ConfigEntry<float> queenDistanceThreshold;

		internal static ConfigEntry<float> queenHealthThreshold;

		internal static ConfigEntry<int> minStagesCleared;

		internal static ConfigEntry<int> stepStagesCleared;

		internal static ConfigEntry<int> minWavesCleared;

		internal static ConfigEntry<int> stepWavesCleared;

		internal static ConfigEntry<int> humanUsesLimit;

		internal static ConfigEntry<int> golemUsesLimit;

		internal static ConfigEntry<int> queenUsesLimit;

		internal static ConfigEntry<string> blacklistedEquipment;

		internal static ConfigEntry<string> blacklistedEquipmentMoon;

		internal static ConfigEntry<string> blacklistedMonsters;

		internal static void Init(ConfigFile config)
		{
			humanDistanceThreshold = config.Bind<float>("AI.Basic", "humanDistanceThreshold", 50f, "The maximum distance for basic monsters to activate their equipment");
			humanHealthThreshold = config.Bind<float>("AI.Basic", "humanHealthThreshold", 0.75f, "The maximum normalised health for basic monsters to activate their equipment");
			humanUsesLimit = config.Bind<int>("AI.Basic", "humanUsesLimit", -1, "The number of times a basic monster can activate their equipment. -1 is for unlimited");
			golemDistanceThreshold = config.Bind<float>("AI.Miniboss", "golemDistanceThreshold", 65f, "The maximum distance for minibosses to activate their equipment");
			golemHealthThreshold = config.Bind<float>("AI.Miniboss", "golemHealthThreshold", 0.5f, "The maximum normalised health for minibosses to activate their equipment");
			golemUsesLimit = config.Bind<int>("AI.Miniboss", "golemUsesLimit", -1, "The number of times a miniboss can activate their equipment. -1 is for unlimited");
			queenDistanceThreshold = config.Bind<float>("AI.Champion", "queenDistanceThreshold", 80f, "The maximum distance for champions to activate their equipment");
			queenHealthThreshold = config.Bind<float>("AI.Champion", "queenHealthThreshold", 0.25f, "The maximum normalised health for champions to activate their equipment");
			queenUsesLimit = config.Bind<int>("AI.Champion", "queenUsesLimit", -1, "The number of times a champion can activate their equipment. -1 is for unlimited");
			blacklistedEquipment = config.Bind<string>("Blacklist", "blacklistedEquipment", "BFG,Blackhole,CommandMissile,DroneBackup,FireBallDash,GoldGat,Lightning,Saw", "Blacklisted equipment. Use 'list_equip' from DebugToolkit for internal names");
			blacklistedEquipmentMoon = config.Bind<string>("Blacklist", "blacklistedEquipmentMoon", "Fruit,PassiveHealing", "Additional blacklisted equipment for Commencement. Intended to avoid any softlocks with Mithrix.");
			blacklistedMonsters = config.Bind<string>("Blacklist", "blacklistedMonsters", "", "Monsters whose AI is not modified to use equipment. Use 'list_ai' from DebugToolkit for internal names");
			minStagesCleared = config.Bind<int>("Evolution", "minStagesCleared", 0, "The minimum stages cleared required before selecting an equipment");
			stepStagesCleared = config.Bind<int>("Evolution", "stepStagesCleared", 1, "The equipment will be rerolled every this many stages after 'minStagesCleared'");
			rerollLunar = config.Bind<bool>("General", "rerollLunar", true, "Reroll for a Lunar Equipment if the player holds Eulogy of Zero.");
			isSimulacrumEnabled = config.Bind<bool>("Simulacrum", "isSimulacrumEnabled", true, "Enable equipment giving for Simulacrum. If enabled, it overrides any Evolution settings for the game mode");
			minWavesCleared = config.Bind<int>("Simulacrum", "minWavesCleared", 4, "The minimum number of Simulacrum waves required before selecting an equipment");
			stepWavesCleared = config.Bind<int>("Simulacrum", "stepWavesCleared", 5, "The equipment will be rerolled every this many Simulacrum waves after 'minWavesCleared'");
			minStagesCleared.Value = Math.Max(minStagesCleared.Value, 0);
			stepStagesCleared.Value = Math.Max(stepStagesCleared.Value, 1);
			minWavesCleared.Value = Math.Max(minWavesCleared.Value, 0);
			stepWavesCleared.Value = Math.Max(stepWavesCleared.Value, 1);
		}
	}
	[BepInPlugin("Chinchi.EvolutionEquipment", "EvolutionEquipment", "1.0.3")]
	public class EvolutionEquipment : BaseUnityPlugin
	{
		public const string PluginGUID = "Chinchi.EvolutionEquipment";

		public const string PluginAuthor = "Chinchi";

		public const string PluginName = "EvolutionEquipment";

		public const string PluginVersion = "1.0.3";

		internal static ManualLogSource Logger;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Configuration.Init(((BaseUnityPlugin)this).Config);
			Hooks.Init();
			Language.collectLanguageRootFolders += AddLanguageFolder;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(PatchAI));
		}

		private void AddLanguageFolder(List<string> languageFolders)
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "languages");
			if (Directory.Exists(text))
			{
				languageFolders.Add(text);
			}
		}

		private void PatchAI()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			HashSet<string> hashSet = new HashSet<string>(from x in Configuration.blacklistedMonsters.Value.Split(new char[1] { ',' })
				select x.Trim());
			foreach (CharacterMaster allAiMaster in MasterCatalog.allAiMasters)
			{
				if (hashSet.Contains(((Object)((Component)allAiMaster).gameObject).name) || (Object)(object)allAiMaster.bodyPrefab == (Object)null || (Object)(object)allAiMaster.bodyPrefab.GetComponent<EquipmentSlot>() == (Object)null)
				{
					continue;
				}
				AISkillDriver[] components = ((Component)allAiMaster).GetComponents<AISkillDriver>();
				if (components.Any((AISkillDriver x) => x.shouldFireEquipment))
				{
					continue;
				}
				HullClassification hullClassification = allAiMaster.bodyPrefab.GetComponent<CharacterBody>().hullClassification;
				float value;
				float value2;
				int value3;
				if ((int)hullClassification != 0)
				{
					if ((int)hullClassification == 1)
					{
						value = Configuration.golemHealthThreshold.Value;
						value2 = Configuration.golemDistanceThreshold.Value;
						value3 = Configuration.golemUsesLimit.Value;
					}
					else
					{
						value = Configuration.queenHealthThreshold.Value;
						value2 = Configuration.queenDistanceThreshold.Value;
						value3 = Configuration.queenUsesLimit.Value;
					}
				}
				else
				{
					value = Configuration.humanHealthThreshold.Value;
					value2 = Configuration.humanDistanceThreshold.Value;
					value3 = Configuration.humanUsesLimit.Value;
				}
				AISkillDriver obj = ((Component)allAiMaster).gameObject.AddComponent<AISkillDriver>();
				obj.customName = "FireEquipment";
				obj.skillSlot = (SkillSlot)(-1);
				obj.requireEquipmentReady = true;
				obj.maxUserHealthFraction = value;
				obj.maxDistance = value2;
				obj.selectionRequiresTargetLoS = true;
				obj.selectionRequiresAimTarget = true;
				obj.activationRequiresTargetLoS = true;
				obj.activationRequiresAimConfirmation = true;
				obj.shouldFireEquipment = true;
				obj.aimType = (AimType)1;
				obj.moveTargetType = (TargetType)0;
				obj.movementType = (MovementType)1;
				obj.noRepeat = true;
				obj.maxTimesSelected = value3;
				AISkillDriver[] array = components;
				foreach (AISkillDriver val in array)
				{
					Component obj2 = ((Component)allAiMaster).gameObject.AddComponent(((object)val).GetType());
					FieldInfo[] fields = ((object)val).GetType().GetFields();
					foreach (FieldInfo fieldInfo in fields)
					{
						fieldInfo.SetValue(obj2, fieldInfo.GetValue(val));
					}
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}
	}
	internal static class Hooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<Run> <0>__FilterRunEquipment;

			public static hook_Awake <1>__CreateEquipmentPanel;

			public static Manipulator <2>__UpdateEquipmentPanel;

			public static hook_OnDestroy <3>__RemoveInfoPanel;

			public static hook_EnsureMonsterItemCountMatchesStageCount <4>__RollStageEquipment;

			public static hook_AdvanceWave <5>__RollWaveEquipment;

			public static Manipulator <6>__GiveMonsterEquipmentClassic;

			public static Manipulator <7>__GiveMonsterEquipmentSimulacrum;

			public static Action <8>__RefreshPanelPosition;
		}

		private static Sprite backgroundSprite;

		private static readonly List<EquipmentIndex> availableEquipment = new List<EquipmentIndex>();

		private static readonly List<EquipmentIndex> availableLunarEquipment = new List<EquipmentIndex>();

		private static readonly List<EquipmentIndex> availableEquipmentMoon = new List<EquipmentIndex>();

		private static readonly List<EquipmentIndex> availableLunarEquipmentMoon = new List<EquipmentIndex>();

		private static readonly Dictionary<EnemyInfoPanel, Tuple<GameObject, UIElementAllocator<RawImage>>> enemyInfoPanels = new Dictionary<EnemyInfoPanel, Tuple<GameObject, UIElementAllocator<RawImage>>>();

		private static readonly Xoroshiro128Plus rng = new Xoroshiro128Plus(0uL);

		internal static void Init()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d0: 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_00db: Expected O, but got Unknown
			//IL_0105: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			Run.onRunStartGlobal += FilterRunEquipment;
			object obj = <>O.<1>__CreateEquipmentPanel;
			if (obj == null)
			{
				hook_Awake val = CreateEquipmentPanel;
				<>O.<1>__CreateEquipmentPanel = val;
				obj = (object)val;
			}
			EnemyInfoPanel.Awake += (hook_Awake)obj;
			object obj2 = <>O.<2>__UpdateEquipmentPanel;
			if (obj2 == null)
			{
				Manipulator val2 = UpdateEquipmentPanel;
				<>O.<2>__UpdateEquipmentPanel = val2;
				obj2 = (object)val2;
			}
			EnemyInfoPanel.SetDisplayDataForViewer += (Manipulator)obj2;
			object obj3 = <>O.<3>__RemoveInfoPanel;
			if (obj3 == null)
			{
				hook_OnDestroy val3 = RemoveInfoPanel;
				<>O.<3>__RemoveInfoPanel = val3;
				obj3 = (object)val3;
			}
			EnemyInfoPanel.OnDestroy += (hook_OnDestroy)obj3;
			object obj4 = <>O.<4>__RollStageEquipment;
			if (obj4 == null)
			{
				hook_EnsureMonsterItemCountMatchesStageCount val4 = RollStageEquipment;
				<>O.<4>__RollStageEquipment = val4;
				obj4 = (object)val4;
			}
			MonsterTeamGainsItemsArtifactManager.EnsureMonsterItemCountMatchesStageCount += (hook_EnsureMonsterItemCountMatchesStageCount)obj4;
			object obj5 = <>O.<5>__RollWaveEquipment;
			if (obj5 == null)
			{
				hook_AdvanceWave val5 = RollWaveEquipment;
				<>O.<5>__RollWaveEquipment = val5;
				obj5 = (object)val5;
			}
			InfiniteTowerRun.AdvanceWave += (hook_AdvanceWave)obj5;
			object obj6 = <>O.<6>__GiveMonsterEquipmentClassic;
			if (obj6 == null)
			{
				Manipulator val6 = GiveMonsterEquipmentClassic;
				<>O.<6>__GiveMonsterEquipmentClassic = val6;
				obj6 = (object)val6;
			}
			MonsterTeamGainsItemsArtifactManager.OnServerCardSpawnedGlobal += (Manipulator)obj6;
			object obj7 = <>O.<7>__GiveMonsterEquipmentSimulacrum;
			if (obj7 == null)
			{
				Manipulator val7 = GiveMonsterEquipmentSimulacrum;
				<>O.<7>__GiveMonsterEquipmentSimulacrum = val7;
				obj7 = (object)val7;
			}
			InfiniteTowerWaveController.OnCombatSquadMemberDiscovered += (Manipulator)obj7;
			AsyncOperationHandle<Sprite> val8 = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/UI/texUICutOffCorner.png");
			val8.Completed += delegate(AsyncOperationHandle<Sprite> operation)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)operation.Status == 1)
				{
					backgroundSprite = operation.Result;
				}
			};
		}

		private static void FilterRunEquipment(Run run)
		{
			HashSet<string> blacklist2 = new HashSet<string>(from x in Configuration.blacklistedEquipment.Value.Split(new char[1] { ',' })
				select x.Trim());
			InitAvailableEquipment(ToEquipmentIndex(run.availableEquipmentDropList), availableEquipment, blacklist2);
			InitAvailableEquipment(ToEquipmentIndex(run.availableLunarEquipmentDropList), availableLunarEquipment, blacklist2);
			HashSet<string> blacklist3 = new HashSet<string>(from x in Configuration.blacklistedEquipmentMoon.Value.Split(new char[1] { ',' })
				select x.Trim());
			InitAvailableEquipment(availableEquipment, availableEquipmentMoon, blacklist3);
			InitAvailableEquipment(availableLunarEquipment, availableLunarEquipmentMoon, blacklist3);
			static void InitAvailableEquipment(List<EquipmentIndex> original, List<EquipmentIndex> filtered, HashSet<string> blacklist)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				filtered.Clear();
				foreach (EquipmentIndex item in original)
				{
					EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(item);
					if ((Object)(object)equipmentDef != (Object)null && !blacklist.Contains(((Object)equipmentDef).name))
					{
						filtered.Add(item);
					}
				}
			}
			static List<EquipmentIndex> ToEquipmentIndex(List<PickupIndex> droplist)
			{
				return droplist.Select((PickupIndex x) => PickupCatalog.GetPickupDef(x).equipmentIndex).ToList();
			}
		}

		private static void CreateEquipmentPanel(orig_Awake orig, EnemyInfoPanel self)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: 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_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			Transform child = ((Component)self).transform.GetChild(0);
			GameObject val = new GameObject("EquipmentContainer");
			val.SetActive(false);
			VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			RectTransform rectTransform = ((LayoutGroup)val2).rectTransform;
			((Transform)rectTransform).SetParent(child, false);
			((Transform)rectTransform).localPosition = new Vector3(((Transform)rectTransform).localPosition.x, ((Transform)rectTransform).localPosition.y, 0f);
			((Transform)rectTransform).localEulerAngles = Vector3.zero;
			((Transform)rectTransform).localScale = Vector3.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition3D = new Vector3(73f, -99f, 0f);
			rectTransform.offsetMin = new Vector2(0f, -106f);
			rectTransform.offsetMax = new Vector2(146f, -93f);
			GameObject val3 = new GameObject("EquipmentLabel");
			HGTextMeshProUGUI val4 = val3.AddComponent<HGTextMeshProUGUI>();
			((TMP_Text)val4).fontSize = 12f;
			((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
			val3.SetActive(false);
			val3.AddComponent<LanguageTextMeshController>().token = "HUD_MONSTER_EQUIPMENT_LABEL";
			val3.SetActive(true);
			rectTransform = ((TMP_Text)val4).rectTransform;
			((Transform)rectTransform).SetParent((Transform)(object)((LayoutGroup)val2).rectTransform, false);
			((Transform)rectTransform).localPosition = new Vector3(((Transform)rectTransform).localPosition.x, ((Transform)rectTransform).localPosition.y, 0f);
			((Transform)rectTransform).localEulerAngles = Vector3.zero;
			((Transform)rectTransform).localScale = Vector3.one;
			GameObject val5 = new GameObject("EquipmentDisplay");
			Image obj = val5.AddComponent<Image>();
			((Graphic)obj).color = new Color(0f, 0f, 0f, 0.5411f);
			obj.sprite = backgroundSprite;
			obj.type = (Type)1;
			GridLayoutGroup obj2 = val5.AddComponent<GridLayoutGroup>();
			obj2.cellSize = new Vector2(32f, 32f);
			obj2.spacing = new Vector2(2f, 2f);
			((LayoutGroup)obj2).childAlignment = (TextAnchor)4;
			((LayoutGroup)obj2).padding = new RectOffset(2, 2, 2, 2);
			rectTransform = ((LayoutGroup)obj2).rectTransform;
			((Transform)rectTransform).SetParent((Transform)(object)((LayoutGroup)val2).rectTransform, false);
			((Transform)rectTransform).localPosition = new Vector3(((Transform)rectTransform).localPosition.x, ((Transform)rectTransform).localPosition.y, 0f);
			((Transform)rectTransform).localEulerAngles = Vector3.zero;
			((Transform)rectTransform).localScale = Vector3.one;
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition3D = new Vector3(73f, -12f, 0f);
			rectTransform.offsetMin = new Vector2(0f, -84f);
			rectTransform.offsetMax = new Vector2(146f, -12f);
			enemyInfoPanels[self] = Tuple.Create<GameObject, UIElementAllocator<RawImage>>(val, new UIElementAllocator<RawImage>(rectTransform, self.iconPrefab, true, false));
		}

		private static void UpdateEquipmentPanel(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00b0: 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.MatchLdloc(x, 0)
			}))
			{
				EvolutionEquipment.Logger.LogError((object)"Failed to patch EnemyInfoPanel.SetDisplayDataForViewer #1");
				return;
			}
			val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)delegate(bool shouldDisplay)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Invalid comparison between Unknown and I4
				Inventory enemyInventory2 = GetEnemyInventory();
				return shouldDisplay || (Object.op_Implicit((Object)(object)enemyInventory2) && (int)enemyInventory2.currentEquipmentIndex != -1);
			});
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<EnemyInfoPanel>(x, "TrySetItems")
			}))
			{
				EvolutionEquipment.Logger.LogError((object)"Failed to patch EnemyInfoPanel.SetDisplayDataForViewer #2");
				return;
			}
			val.Emit(OpCodes.Ldloc_1);
			val.EmitDelegate<Action<EnemyInfoPanel>>((Action<EnemyInfoPanel>)delegate(EnemyInfoPanel panel)
			{
				//IL_0055: 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_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Invalid comparison between Unknown and I4
				//IL_0062: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: 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)
				if (!enemyInfoPanels.TryGetValue(panel, out var value))
				{
					EvolutionEquipment.Logger.LogWarning((object)("Equipment icon allocator not found: " + (object)panel.hud.targetMaster));
				}
				else
				{
					UIElementAllocator<RawImage> item = value.Item2;
					Inventory enemyInventory = GetEnemyInventory();
					EquipmentIndex val2 = (EquipmentIndex)((!((Object)(object)enemyInventory != (Object)null)) ? (-1) : ((int)enemyInventory.currentEquipmentIndex));
					if ((int)val2 != -1)
					{
						EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val2);
						item.AllocateElements(1);
						item.elements[0].texture = equipmentDef.pickupIconTexture;
						TooltipProvider obj = ((Component)item.elements[0]).gameObject.AddComponent<TooltipProvider>();
						obj.titleColor = Color32.op_Implicit(ColorCatalog.GetColor(equipmentDef.colorIndex));
						obj.titleToken = equipmentDef.nameToken;
						obj.bodyToken = equipmentDef.descriptionToken;
						value.Item1.SetActive(true);
						RoR2Application.onNextUpdate += RefreshPanelPosition;
					}
					else
					{
						item.AllocateElements(0);
						value.Item1.SetActive(false);
					}
				}
			});
			static Inventory GetEnemyInventory()
			{
				if (Run.instance is InfiniteTowerRun && Configuration.isSimulacrumEnabled.Value)
				{
					Run instance = Run.instance;
					return ((InfiniteTowerRun)((instance is InfiniteTowerRun) ? instance : null)).enemyInventory;
				}
				if (RunArtifactManager.instance.IsArtifactEnabled(Artifacts.MonsterTeamGainsItems))
				{
					return MonsterTeamGainsItemsArtifactManager.monsterTeamInventory;
				}
				return null;
			}
		}

		private static void RefreshPanelPosition()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			foreach (Tuple<GameObject, UIElementAllocator<RawImage>> value in enemyInfoPanels.Values)
			{
				if (value.Item1.activeSelf)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)value.Item1.transform.parent);
				}
			}
		}

		private static void RemoveInfoPanel(orig_OnDestroy orig, EnemyInfoPanel self)
		{
			orig.Invoke(self);
			enemyInfoPanels.Remove(self);
		}

		private static void RollStageEquipment(orig_EnsureMonsterItemCountMatchesStageCount orig)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke();
			if (Object.op_Implicit((Object)(object)Run.instance) && !(Run.instance is InfiniteTowerRun))
			{
				int num = Run.instance.stageClearCount - Configuration.minStagesCleared.Value;
				EquipmentIndex val = (EquipmentIndex)(-1);
				if (num >= 0)
				{
					val = RollEquipment(num / Configuration.stepStagesCleared.Value);
				}
				Inventory monsterTeamInventory = MonsterTeamGainsItemsArtifactManager.monsterTeamInventory;
				if (monsterTeamInventory.currentEquipmentIndex != val)
				{
					monsterTeamInventory.SetEquipmentIndex(val);
				}
			}
		}

		private static void RollWaveEquipment(orig_AdvanceWave orig, InfiniteTowerRun self)
		{
			//IL_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_004c->IL004c: Incompatible stack types: O vs I4
			//IL_003b->IL004c: Incompatible stack types: I4 vs O
			//IL_003b->IL004c: Incompatible stack types: O vs I4
			orig.Invoke(self);
			if (!Configuration.isSimulacrumEnabled.Value)
			{
				return;
			}
			Run instance = Run.instance;
			object obj = ((instance is InfiniteTowerRun) ? instance : null);
			int num = ((InfiniteTowerRun)obj)._waveIndex - 1 - Configuration.minWavesCleared.Value;
			int num2;
			if (num >= 0)
			{
				obj = RollEquipment(num / Configuration.stepWavesCleared.Value);
				num2 = (int)obj;
			}
			else
			{
				num2 = -1;
				obj = num2;
				num2 = (int)obj;
			}
			EquipmentIndex val = (EquipmentIndex)obj;
			Inventory enemyInventory = ((InfiniteTowerRun)num2).enemyInventory;
			if (enemyInventory.currentEquipmentIndex != val)
			{
				enemyInventory.SetEquipmentIndex(val);
				PickupDef pickupDef = PickupCatalog.GetPickupDef(PickupCatalog.FindPickupIndex(val));
				if (pickupDef != null)
				{
					Chat.SendBroadcastChat((ChatMessageBase)new PlayerPickupChatMessage
					{
						baseToken = "INFINITETOWER_ADD_ITEM",
						pickupToken = pickupDef.nameToken,
						pickupColor = Color32.op_Implicit(pickupDef.baseColor)
					});
				}
			}
		}

		private static EquipmentIndex RollEquipment(int seedOffset)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			rng.ResetSeed(Run.instance.seed + (ulong)seedOffset);
			string cachedName = SceneCatalog.currentSceneDef.cachedName;
			bool flag = cachedName == "moon2" || cachedName == "moon";
			List<EquipmentIndex> list = ((!flag) ? availableEquipment : availableEquipmentMoon);
			EquipmentIndex result = (EquipmentIndex)((list.Count <= 0) ? (-1) : ((int)rng.NextElementUniform<EquipmentIndex>(list)));
			if (Configuration.rerollLunar.Value)
			{
				int itemCountGlobal = Util.GetItemCountGlobal(Items.RandomlyLunar.itemIndex, false, false);
				if (itemCountGlobal > 0 && rng.nextNormalizedFloat < 0.05f * (float)itemCountGlobal)
				{
					list = ((!flag) ? availableLunarEquipment : availableLunarEquipmentMoon);
					result = (EquipmentIndex)((list.Count <= 0) ? (-1) : ((int)rng.NextElementUniform<EquipmentIndex>(list)));
				}
			}
			return result;
		}

		private static void GiveMonsterEquipmentClassic(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0049: 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.MatchCallvirt<Inventory>(x, "AddItemsFrom")
			}))
			{
				EvolutionEquipment.Logger.LogError((object)"Failed to patch RoR2.Artifacts.MonsterTeamGainsItemsArtifactManager");
				return;
			}
			val.Emit(OpCodes.Ldloc_0);
			val.EmitDelegate<Action<CharacterMaster>>((Action<CharacterMaster>)delegate(CharacterMaster master)
			{
				GiveMasterEquipment(master, MonsterTeamGainsItemsArtifactManager.monsterTeamInventory);
			});
		}

		private static void GiveMonsterEquipmentSimulacrum(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<Inventory>(x, "AddItemsFrom")
			}))
			{
				EvolutionEquipment.Logger.LogError((object)"Failed to patch RoR2.InfiniteTowerWaveController.OnCombatSquadMemberDiscovered");
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldarg_1);
			val.EmitDelegate<Action<InfiniteTowerWaveController, CharacterMaster>>((Action<InfiniteTowerWaveController, CharacterMaster>)delegate(InfiniteTowerWaveController waveController, CharacterMaster master)
			{
				GiveMasterEquipment(master, waveController.enemyInventory);
			});
		}

		private static void GiveMasterEquipment(CharacterMaster master, Inventory enemyInventory)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			EquipmentIndex currentEquipmentIndex = enemyInventory.currentEquipmentIndex;
			if ((int)master.inventory.currentEquipmentIndex == -1 && (int)currentEquipmentIndex != -1 && (Object)(object)((Component)master).GetComponent<ScavengerItemGranter>() == (Object)null && master.inventory.GetItemCount(Items.GummyCloneIdentifier) == 0)
			{
				GivePickupsOnStart component = ((Component)master).GetComponent<GivePickupsOnStart>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.equipmentDef == (Object)null || string.IsNullOrEmpty(component.equipmentString))
				{
					master.inventory.SetEquipmentIndex(currentEquipmentIndex);
				}
			}
		}
	}
}