Decompiled source of RiskOfInsanity v2.0.0

RoR2Randomizer.dll

Decompiled 3 days ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.BrotherMonster;
using EntityStates.Engi.EngiWeapon;
using EntityStates.FalseSonBoss;
using EntityStates.Loader;
using EntityStates.MeridianEvent;
using EntityStates.Missions.BrotherEncounter;
using EntityStates.Missions.Goldshores;
using EntityStates.Missions.LunarScavengerEncounter;
using EntityStates.NewtMonster;
using EntityStates.ScavMonster;
using EntityStates.SolusWing2;
using EntityStates.Toolbot;
using EntityStates.VoidRaidCrab;
using HG;
using HG.GeneralSerializer;
using HG.Reflection;
using HarmonyLib;
using IL.EntityStates.BeetleQueenMonster;
using IL.EntityStates.BrotherMonster;
using IL.EntityStates.CaptainSupplyDrop;
using IL.EntityStates.Commando.CommandoWeapon;
using IL.EntityStates.Engi.EngiWeapon;
using IL.EntityStates.GoldGat;
using IL.EntityStates.MinePod;
using IL.EntityStates.Missions.BrotherEncounter;
using IL.EntityStates.Missions.Goldshores;
using IL.EntityStates.Missions.SuperRoboBallEncounter;
using IL.EntityStates.NewtMonster;
using IL.EntityStates.ParentEgg;
using IL.EntityStates.RoboBallBoss.Weapon;
using IL.EntityStates.ScavMonster;
using IL.EntityStates.Scrapper;
using IL.EntityStates.VoidJailer;
using IL.EntityStates.VoidRaidCrab;
using IL.RoR2;
using IL.RoR2.Artifacts;
using IL.RoR2.CharacterSpeech;
using IL.RoR2.Items;
using IL.RoR2.Orbs;
using IL.RoR2.Projectile;
using IL.RoR2.UI;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.EntityStates;
using On.EntityStates.BrotherMonster;
using On.EntityStates.MeridianEvent;
using On.EntityStates.Missions.BrotherEncounter;
using On.EntityStates.Missions.Goldshores;
using On.EntityStates.Missions.LunarScavengerEncounter;
using On.EntityStates.ScavMonster;
using On.EntityStates.SolusWing2;
using On.EntityStates.Toolbot;
using On.EntityStates.VoidRaidCrab;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.Orbs;
using On.RoR2.Projectile;
using On.RoR2.UI;
using On.RoR2.UI.MainMenu;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.CharacterSpeech;
using RoR2.ContentManagement;
using RoR2.EntitlementManagement;
using RoR2.ExpansionManagement;
using RoR2.Items;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using RoR2.UI.MainMenu;
using RoR2Randomizer.BodyAnimationMirroring;
using RoR2Randomizer.CharacterLimiter;
using RoR2Randomizer.ChildTransformAdditions;
using RoR2Randomizer.Configuration;
using RoR2Randomizer.Configuration.ConfigValue;
using RoR2Randomizer.Configuration.ConfigValue.ParsedList;
using RoR2Randomizer.CustomContent;
using RoR2Randomizer.Extensions;
using RoR2Randomizer.ModCompatibility;
using RoR2Randomizer.Networking;
using RoR2Randomizer.Networking.BossRandomizer;
using RoR2Randomizer.Networking.CharacterReplacements;
using RoR2Randomizer.Networking.DamageOrbTargetDummy;
using RoR2Randomizer.Networking.EffectRandomizer;
using RoR2Randomizer.Networking.ExplicitSpawnRandomizer;
using RoR2Randomizer.Networking.Generic;
using RoR2Randomizer.Networking.Generic.Chunking;
using RoR2Randomizer.Networking.ItemRandomizer;
using RoR2Randomizer.Networking.ItemTierRandomizer;
using RoR2Randomizer.Networking.ProjectileRandomizer;
using RoR2Randomizer.Networking.ProjectileRandomizer.Bullet;
using RoR2Randomizer.Networking.ProjectileRandomizer.Orbs;
using RoR2Randomizer.Networking.ProjectileRandomizer.Orbs.GenericDamage;
using RoR2Randomizer.Networking.ProjectileRandomizer.Orbs.Lightning;
using RoR2Randomizer.Networking.ProjectileRandomizer.SpiteBomb;
using RoR2Randomizer.Networking.SniperWeakPointRandomizer;
using RoR2Randomizer.Networking.SurvivorPodRandomizer;
using RoR2Randomizer.Patches;
using RoR2Randomizer.Patches.BossRandomizer;
using RoR2Randomizer.Patches.BossRandomizer.AlloyWorshipUnit;
using RoR2Randomizer.Patches.BossRandomizer.Aurelionite;
using RoR2Randomizer.Patches.BossRandomizer.FalseSon;
using RoR2Randomizer.Patches.BossRandomizer.LunarScav;
using RoR2Randomizer.Patches.BossRandomizer.Mithrix;
using RoR2Randomizer.Patches.BossRandomizer.SolusWing;
using RoR2Randomizer.Patches.BossRandomizer.Voidling;
using RoR2Randomizer.Patches.ExplicitSpawnRandomizer;
using RoR2Randomizer.Patches.OrbEffectOverrideTarget;
using RoR2Randomizer.Patches.ProjectileParentChainTrackerPatches;
using RoR2Randomizer.Patches.ProjectileRandomizer.Orbs;
using RoR2Randomizer.Patches.ProjectileRandomizer.SpiteBomb;
using RoR2Randomizer.Patches.Reverse;
using RoR2Randomizer.PrefabMarkers;
using RoR2Randomizer.Properties;
using RoR2Randomizer.RandomizerControllers;
using RoR2Randomizer.RandomizerControllers.Boss;
using RoR2Randomizer.RandomizerControllers.Boss.BossReplacementInfo;
using RoR2Randomizer.RandomizerControllers.Buff;
using RoR2Randomizer.RandomizerControllers.Effect;
using RoR2Randomizer.RandomizerControllers.ExplicitSpawn;
using RoR2Randomizer.RandomizerControllers.Item;
using RoR2Randomizer.RandomizerControllers.Item_Tier;
using RoR2Randomizer.RandomizerControllers.Projectile;
using RoR2Randomizer.RandomizerControllers.Projectile.BulletAttackHandling;
using RoR2Randomizer.RandomizerControllers.Projectile.Orbs;
using RoR2Randomizer.RandomizerControllers.Projectile.Orbs.DamageOrbHandling;
using RoR2Randomizer.RandomizerControllers.Projectile.Orbs.LightningOrbHandling;
using RoR2Randomizer.RandomizerControllers.SniperWeakPoint;
using RoR2Randomizer.RandomizerControllers.Stage;
using RoR2Randomizer.RandomizerControllers.SurvivorPod;
using RoR2Randomizer.Utility;
using RoR2Randomizer.Utility.Catalog;
using RoR2Randomizer.Utility.Comparers;
using RoR2Randomizer.Utility.EnemyInfoEquipmentDisplay;
using RoR2Randomizer.Utility.Patching;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityModdingUtility;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("HGUnityUtils")]
[assembly: IgnoresAccessChecksTo("RoR2")]
[assembly: AssemblyCompany("RoR2Randomizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3b1c7f3e26352eead8b86684335b3989af48174b")]
[assembly: AssemblyProduct("RoR2Randomizer")]
[assembly: AssemblyTitle("RoR2Randomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 RoR2Randomizer
{
	public static class LanguageTokens
	{
		private const string TOKEN_PREFIX = "Gorakh.RoR2Randomizer_";

		public const string MOD_INFO_POPUP_HEADER = "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_HEADER";

		public const string MOD_INFO_POPUP_DESCRIPTION = "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_DESCRIPTION";

		public const string MOD_INFO_POPUP_DISMISS = "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_DISMISS";

		private static readonly Dictionary<string, string> _tokenPairs = new Dictionary<string, string>
		{
			{ "ARCHWISP_BODY_NAME", "Arch Wisp" },
			{ "BEETLE_CRYSTAL_BODY_NAME", "Crystal Beetle" },
			{ "MAJORCONSTRUCT_BODY_NAME", "Major Construct" },
			{ "MAJORCONSTRUCT_BODY_SUBTITLE", "Defense System" },
			{ "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_HEADER", "Welcome to Risk of Rain 2 Randomizer!" },
			{ "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_DESCRIPTION", "Thank you for wanting to play with my silly little mod! Before you start playing though, please check the mod settings (Settings -> Mod Options) if you don't want absolute chaos (almost all randomizers are enabled by default), or don't, up to you :)" },
			{ "Gorakh.RoR2Randomizer_MOD_INFO_POPUP_DISMISS", "OK" }
		};

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			LanguageAPI.Add(_tokenPairs);
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("RoR2Randomizer");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "RoR2Randomizer".Length + 1);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		internal static void Error(string data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			Error_NoCallerPrefix(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data);
		}

		internal static void Error_NoCallerPrefix(string data)
		{
			_logSource.LogError((object)data);
		}

		internal static void Fatal(string data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			Fatal_NoCallerPrefix(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data);
		}

		internal static void Fatal_NoCallerPrefix(string data)
		{
			_logSource.LogFatal((object)data);
		}

		internal static void Info(string data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			Info_NoCallerPrefix(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data);
		}

		internal static void Info_NoCallerPrefix(string data)
		{
			_logSource.LogInfo((object)data);
		}

		internal static void Message(string data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			Message_NoCallerPrefix(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data);
		}

		internal static void Message_NoCallerPrefix(string data)
		{
			_logSource.LogMessage((object)data);
		}

		internal static void Warning(string data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			Warning_NoCallerPrefix(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data);
		}

		internal static void Warning_NoCallerPrefix(string data)
		{
			_logSource.LogWarning((object)data);
		}

		internal static void LogType(string data, LogLevel level)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, (object)data);
			}
		}
	}
	[BepInPlugin("Gorakh.RoR2Randomizer", "RoR2Randomizer", "0.9.0")]
	[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.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.RoR2Randomizer";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "RoR2Randomizer";

		public const string PluginVersion = "0.9.0";

		public static Main Instance { get; private set; }

		private void Awake()
		{
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = this;
			CustomNetworkMessageManager.RegisterMessages();
			if (InitializeOnAccess<bool>.op_Implicit(RiskOfOptionsCompat.IsEnabled))
			{
				RiskOfOptionsCompat.Setup();
			}
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
			InitializationManager.Init();
			new ContentPackManager().Init();
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F1} seconds");
		}

		private void OnDestroy()
		{
			InitializationManager.Cleanup();
			CharacterReplacements.Uninitialize();
			NetworkingManager.Uninitialize();
		}
	}
}
namespace RoR2Randomizer.Utility
{
	public static class Caches
	{
		public static class Masters
		{
			public static MasterIndex Gup { get; private set; } = MasterIndex.none;

			public static MasterIndex Heretic { get; private set; } = MasterIndex.none;

			public static MasterIndex MalachiteUrchin { get; private set; } = MasterIndex.none;

			public static MasterIndex VoidInfestor { get; private set; } = MasterIndex.none;

			public static MasterIndex SoulWisp { get; private set; } = MasterIndex.none;

			public static MasterIndex HealingCore { get; private set; } = MasterIndex.none;

			public static MasterIndex ShopkeeperNewt { get; private set; } = MasterIndex.none;

			[SystemInitializer(new Type[] { typeof(MasterCatalog) })]
			private static void Init()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: 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)
				Gup = MasterCatalog.FindMasterIndex("GupMaster");
				Heretic = MasterCatalog.FindMasterIndex("HereticMonsterMaster");
				MalachiteUrchin = MasterCatalog.FindMasterIndex("UrchinTurretMaster");
				VoidInfestor = MasterCatalog.FindMasterIndex("VoidInfestorMaster");
				SoulWisp = MasterCatalog.FindMasterIndex("WispSoulMaster");
				HealingCore = MasterCatalog.FindMasterIndex("AffixEarthHealerMaster");
				ShopkeeperNewt = MasterCatalog.FindMasterIndex("ShopkeeperMaster");
			}
		}

		public static class Bodies
		{
			public static BodyIndex VoidlingBaseBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex VoidlingPhase1BodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex VoidlingPhase2BodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex VoidlingPhase3BodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex BeetleQueenBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex ClayBossBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex LunarGolemBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex HereticBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex SquidTurretBodyIndex { get; private set; } = (BodyIndex)(-1);

			public static BodyIndex MinorConstructOnKillBodyIndex { get; private set; } = (BodyIndex)(-1);

			[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
			private static void Init()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				VoidlingBaseBodyIndex = BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyBase");
				VoidlingPhase1BodyIndex = BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyPhase1");
				VoidlingPhase2BodyIndex = BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyPhase2");
				VoidlingPhase3BodyIndex = BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyPhase3");
				BeetleQueenBodyIndex = BodyCatalog.FindBodyIndex("BeetleQueen2Body");
				ClayBossBodyIndex = BodyCatalog.FindBodyIndex("ClayBossBody");
				LunarGolemBodyIndex = BodyCatalog.FindBodyIndex("LunarGolemBody");
				HereticBodyIndex = BodyCatalog.FindBodyIndex("HereticBody");
				SquidTurretBodyIndex = BodyCatalog.FindBodyIndex("SquidTurretBody");
				MinorConstructOnKillBodyIndex = BodyCatalog.FindBodyIndex("MinorConstructOnKillBody");
			}
		}

		public static class Scene
		{
			public static SceneIndex ArtifactTrialSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex NewtShopSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex GoldShoresSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex ObliterateSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex LunarScavFightSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex CommencementSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex VoidlingFightSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex VoidLocusSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex AbandonedAqueductSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex OldCommencementSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex AITestSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static SceneIndex TestSceneSceneIndex { get; private set; } = (SceneIndex)(-1);

			public static ReadOnlyArray<SceneIndex> SimulacrumStageIndices { get; private set; }

			public static ReadOnlyArray<SceneIndex> PossibleStartingStagesIndices { get; private set; }

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public static bool IsSimulacrumStage(SceneDef scene)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return IsSimulacrumStage(scene.sceneDefIndex);
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public static bool IsSimulacrumStage(SceneIndex index)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return ReadOnlyArray<SceneIndex>.BinarySearch(SimulacrumStageIndices, index) >= 0;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public static bool IsPossibleStartingStage(SceneDef scene)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return IsPossibleStartingStage(scene.sceneDefIndex);
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public static bool IsPossibleStartingStage(SceneIndex index)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return ReadOnlyArray<SceneIndex>.BinarySearch(PossibleStartingStagesIndices, index) >= 0;
			}

			[SystemInitializer(new Type[]
			{
				typeof(SceneCatalog),
				typeof(GameModeCatalog)
			})]
			private static void Init()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Expected I4, but got Unknown
				ArtifactTrialSceneIndex = SceneCatalog.FindSceneIndex("artifactworld");
				NewtShopSceneIndex = SceneCatalog.FindSceneIndex("bazaar");
				GoldShoresSceneIndex = SceneCatalog.FindSceneIndex("goldshores");
				ObliterateSceneIndex = SceneCatalog.FindSceneIndex("mysteryspace");
				LunarScavFightSceneIndex = SceneCatalog.FindSceneIndex("limbo");
				CommencementSceneIndex = SceneCatalog.FindSceneIndex("moon2");
				VoidlingFightSceneIndex = SceneCatalog.FindSceneIndex("voidraid");
				VoidLocusSceneIndex = SceneCatalog.FindSceneIndex("voidstage");
				AbandonedAqueductSceneIndex = SceneCatalog.FindSceneIndex("goolake");
				OldCommencementSceneIndex = SceneCatalog.FindSceneIndex("moon");
				AITestSceneIndex = SceneCatalog.FindSceneIndex("ai_test");
				TestSceneSceneIndex = SceneCatalog.FindSceneIndex("testscene");
				HashSet<SceneIndex> stageIndices = new HashSet<SceneIndex>();
				Run val = GameModeCatalog.FindGameModePrefabComponent("InfiniteTowerRun");
				if (Object.op_Implicit((Object)(object)val))
				{
					SceneCollection startingSceneGroup = val.startingSceneGroup;
					if (Object.op_Implicit((Object)(object)startingSceneGroup))
					{
						handleCollection(startingSceneGroup, new HashSet<SceneCollection>(), in stageIndices);
					}
				}
				else
				{
					Log.Warning("Unable to find run prefab 'InfiniteTowerRun'", "C:\\Users\\michi\\source\\repos\\RoR2Randomizer\\RoR2Randomizer\\RoR2Randomizer\\Utility\\Caches.cs", "Init", 361);
				}
				SimulacrumStageIndices = new ReadOnlyArray<SceneIndex>((from i in stageIndices
					where (int)i != -1
					orderby i
					select i).ToArray());
				SceneIndex[] array = Array.Empty<SceneIndex>();
				Run val2 = GameModeCatalog.FindGameModePrefabComponent("ClassicRun");
				if (Object.op_Implicit((Object)(object)val2))
				{
					SceneCollection startingSceneGroup2 = val2.startingSceneGroup;
					if (Object.op_Implicit((Object)(object)startingSceneGroup2))
					{
						ReadOnlyArray<SceneEntry> sceneEntries = startingSceneGroup2.sceneEntries;
						array = (SceneIndex[])(object)new SceneIndex[sceneEntries.Length];
						for (int num = 0; num < sceneEntries.Length; num++)
						{
							array[num] = (SceneIndex)(int)((SceneEntry)sceneEntries[num]).sceneDef.sceneDefIndex;
						}
					}
				}
				else
				{
					Log.Warning("Unable to find run prefab 'ClassicRun'", "C:\\Users\\michi\\source\\repos\\RoR2Randomizer\\RoR2Randomizer\\RoR2Randomizer\\Utility\\Caches.cs", "Init", 385);
				}
				PossibleStartingStagesIndices = new ReadOnlyArray<SceneIndex>((from i in array.Where((SceneIndex i) => (int)i != -1).Distinct()
					orderby i
					select i).ToArray());
				static void handleCollection(SceneCollection collection, in HashSet<SceneCollection> alreadyHandledCollections, in HashSet<SceneIndex> reference)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: Unknown result type (might be due to invalid IL or missing references)
					if (alreadyHandledCollections.Add(collection))
					{
						Enumerator<SceneEntry> enumerator = collection.sceneEntries.GetEnumerator();
						try
						{
							while (enumerator.MoveNext())
							{
								SceneDef sceneDef = enumerator.Current.sceneDef;
								if (Object.op_Implicit((Object)(object)sceneDef))
								{
									reference.Add(sceneDef.sceneDefIndex);
									SceneCollection destinationsGroup = sceneDef.destinationsGroup;
									if (Object.op_Implicit((Object)(object)destinationsGroup))
									{
										handleCollection(destinationsGroup, in alreadyHandledCollections, in reference);
									}
								}
							}
						}
						finally
						{
							((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
						}
					}
				}
			}
		}

		public static class DLC
		{
			public static ExpansionDef SOTV { get; private set; }

			[SystemInitializer(new Type[] { typeof(ExpansionCatalog) })]
			private static void Init()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				SOTV = ((IEnumerable<ExpansionDef>)(object)ExpansionCatalog.expansionDefs).FirstOrDefault((Func<ExpansionDef, bool>)((ExpansionDef e) => ((Object)e).name == "DLC1"));
			}
		}

		public static readonly InitializeOnAccessDictionary<string, CharacterMaster> MasterPrefabs = new InitializeOnAccessDictionary<string, CharacterMaster>((Func<string, CharacterMaster>)delegate(string name)
		{
			GameObject obj = MasterCatalog.FindMasterPrefab(name);
			return (obj == null) ? null : obj.GetComponent<CharacterMaster>();
		});

		public static readonly InitializeOnAccessDictionary<GameObject, float> CharacterBodyRadius = new InitializeOnAccessDictionary<GameObject, float>((ValueSelectorTryGet<GameObject, float>)delegate(GameObject bodyPrefab, out float radius)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody val = default(CharacterBody);
			if (!bodyPrefab.TryGetComponent<CharacterBody>(ref val) || (int)val.bodyIndex == -1 || (val.bodyIndex != Bodies.BeetleQueenBodyIndex && val.bodyIndex != Bodies.ClayBossBodyIndex && val.bodyIndex != Bodies.LunarGolemBodyIndex))
			{
				Collider[] components = bodyPrefab.GetComponents<Collider>();
				foreach (Collider val2 in components)
				{
					if (val2.enabled && tryGetRadius(val2, out radius))
					{
						return true;
					}
					static bool tryGetRadius(Collider collider, out float reference)
					{
						SphereCollider val4 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
						if (val4 != null)
						{
							reference = val4.radius;
							return true;
						}
						CapsuleCollider val5 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
						if (val5 != null)
						{
							reference = Mathf.Max(val5.radius, val5.height);
							return true;
						}
						reference = -1f;
						return false;
					}
				}
			}
			ModelLocator val3 = default(ModelLocator);
			if (((Component)val).TryGetComponent<ModelLocator>(ref val3))
			{
				Transform modelTransform = val3.modelTransform;
				CharacterModel root = default(CharacterModel);
				if (Object.op_Implicit((Object)(object)modelTransform) && ((Component)modelTransform).TryGetComponent<CharacterModel>(ref root) && root.TryGetModelBounds(out var bounds))
				{
					Vector3 position = ((Component)val).transform.position;
					Vector3 max = ((Bounds)(ref bounds)).max;
					Vector3 min = ((Bounds)(ref bounds)).min;
					radius = (Mathf.Abs(position.x - max.x) + Mathf.Abs(position.x - min.x) + Mathf.Abs(position.y - max.y) + Mathf.Abs(position.y - min.y) + Mathf.Abs(position.z - max.z) + Mathf.Abs(position.z - min.z)) / 6f;
					return true;
				}
			}
			radius = -1f;
			return false;
		});
	}
	public static class Constants
	{
		public static class SceneNames
		{
			public const string ARTIFACT_TRIAL_SCENE_NAME = "artifactworld";

			public const string COMMENCEMENT_SCENE_NAME = "moon2";

			public const string GOLD_SHORES_SCENE_NAME = "goldshores";

			public const string OBLITERATE_SCENE_NAME = "mysteryspace";

			public const string LUNAR_SCAV_FIGHT_SCENE_NAME = "limbo";

			public const string VOIDLING_FIGHT_SCENE_NAME = "voidraid";

			public const string VOID_FIELDS_SCENE_NAME = "arena";

			public const string VOID_LOCUS_SCENE_NAME = "voidstage";

			public const string SIRENS_CALL_SCENE_NAME = "shipgraveyard";

			public const string ABANDONED_AQUEDUCT_SCENE_NAME = "goolake";

			public const string NEWT_SHOP_SCENE_NAME = "bazaar";

			public const string OLD_COMMENCEMENT_SCENE_NAME = "moon";

			public const string AI_TEST_SCENE_NAME = "ai_test";

			public const string TESTSCENE_SCENE_NAME = "testscene";
		}

		public static class BodyNames
		{
			public const string VOIDLING_BASE_NAME = "MiniVoidRaidCrabBodyBase";

			public const string VOIDLING_PHASE_1_NAME = "MiniVoidRaidCrabBodyPhase1";

			public const string VOIDLING_PHASE_2_NAME = "MiniVoidRaidCrabBodyPhase2";

			public const string VOIDLING_PHASE_3_NAME = "MiniVoidRaidCrabBodyPhase3";

			public const string HERETIC_NAME = "HereticBody";

			public const string BEETLE_QUEEN_NAME = "BeetleQueen2Body";

			public const string CLAY_BOSS_NAME = "ClayBossBody";

			public const string LUNAR_GOLEM_NAME = "LunarGolemBody";

			public const string SQUID_TURRET_NAME = "SquidTurretBody";

			public const string MINOR_CONSTRUCT_ON_KILL_NAME = "MinorConstructOnKillBody";
		}

		public static class MasterNames
		{
			public const string GUP_NAME = "GupMaster";

			public const string HERETIC_NAME = "HereticMonsterMaster";

			public const string MALACHITE_URCHIN_NAME = "UrchinTurretMaster";

			public const string VOID_INFESTOR_NAME = "VoidInfestorMaster";

			public const string SOUL_WISP_NAME = "WispSoulMaster";

			public const string HEALING_CORE_NAME = "AffixEarthHealerMaster";

			public const string SHOPKEEPER_NEWT_NAME = "ShopkeeperMaster";
		}

		public static class BuffNames
		{
			public const string VOIDSURVIVOR_CORRUPT_MODE_NAME = "bdVoidSurvivorCorruptMode";
		}

		public static class DLCNames
		{
			public const string SOTV_NAME = "DLC1";
		}

		public const string RISK_OF_OPTIONS_GUID = "com.rune580.riskofoptions";
	}
	public delegate bool TryConvertDelegate<T>(T input, out T output);
	public delegate bool TryConvertToNextValue<T>(ref T value);
	public static class EntityStateOwnerTracker
	{
		private static readonly Dictionary<EntityState, GenericSkill> _stateToOwnerCache = new Dictionary<EntityState, GenericSkill>();

		public static GenericSkill SkillOwnerForNextCall;

		public static void AddSkillOwner(GenericSkill skill, EntityState state)
		{
			if (Object.op_Implicit((Object)(object)skill) && state != null)
			{
				_stateToOwnerCache[state] = skill;
			}
		}

		public static GenericSkill GetOwner(EntityState state)
		{
			if (_stateToOwnerCache.TryGetValue(state, out var value))
			{
				return value;
			}
			ISkillState val = (ISkillState)(object)((state is ISkillState) ? state : null);
			if (val != null)
			{
				return val.activatorSkillSlot;
			}
			return null;
		}

		public static void SetNextOwnerToOwnerOfState(EntityState state)
		{
			GenericSkill owner = GetOwner(state);
			if (Object.op_Implicit((Object)(object)owner))
			{
				SkillOwnerForNextCall = owner;
			}
		}
	}
	public readonly struct IndexReplacementsCollection : IEnumerable<int>, IEnumerable, IEquatable<IndexReplacementsCollection>
	{
		public readonly int Length;

		private readonly int[] _replacementIndices;

		private readonly int[] _originalIndices;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static IndexReplacementsCollection Create<T>(ReplacementDictionary<T> input, int length) where T : Enum
		{
			return new IndexReplacementsCollection(new ReplacementDictionary<int>(input.ToDictionary((KeyValuePair<T, T> kvp) => (int)(object)kvp.Key, (KeyValuePair<T, T> kvp) => (int)(object)kvp.Value)), length);
		}

		public IndexReplacementsCollection(ReplacementDictionary<int> input, int length)
		{
			Length = length;
			_replacementIndices = new int[length];
			int[] replacementIndices = _replacementIndices;
			int num = -1;
			ArrayUtils.SetAll<int>(replacementIndices, ref num);
			_originalIndices = new int[length];
			int[] originalIndices = _originalIndices;
			num = -1;
			ArrayUtils.SetAll<int>(originalIndices, ref num);
			for (int i = 0; i < length; i++)
			{
				if (input.TryGetReplacement(i, out var replacement))
				{
					_replacementIndices[i] = replacement;
					_originalIndices[replacement] = i;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static IndexReplacementsCollection Create<T>(T[] replacementIndices) where T : Enum
		{
			return new IndexReplacementsCollection(Array.ConvertAll(replacementIndices, (T t) => (int)(object)t));
		}

		public IndexReplacementsCollection(int[] replacementIndices, int? length = null)
		{
			Length = length ?? replacementIndices.Length;
			_replacementIndices = replacementIndices;
			_originalIndices = new int[Length];
			int[] originalIndices = _originalIndices;
			int num = -1;
			ArrayUtils.SetAll<int>(originalIndices, ref num);
			for (int i = 0; i < Length; i++)
			{
				int num2 = _replacementIndices[i];
				if (num2 != -1)
				{
					_originalIndices[num2] = i;
				}
			}
		}

		public bool HasReplacement(int original)
		{
			int replacement;
			return TryGetReplacement(original, out replacement);
		}

		public bool TryGetReplacement(int original, out int replacement)
		{
			if (original < 0 || original >= Length)
			{
				replacement = -1;
				return false;
			}
			return (replacement = _replacementIndices[original]) != -1;
		}

		public bool HasOriginal(int replacement)
		{
			int original;
			return TryGetOriginal(replacement, out original);
		}

		public bool TryGetOriginal(int replacement, out int original)
		{
			if (replacement < 0 || replacement >= Length)
			{
				original = -1;
				return false;
			}
			return (original = _originalIndices[replacement]) != -1;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.WritePackedUInt32((uint)Length);
			int[] replacementIndices = _replacementIndices;
			foreach (int num in replacementIndices)
			{
				NetworkExtensions.WritePackedIndex32(writer, num);
			}
		}

		public static IndexReplacementsCollection Deserialize(NetworkReader reader)
		{
			uint num = reader.ReadPackedUInt32();
			int[] array = new int[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = NetworkExtensions.ReadPackedIndex32(reader);
			}
			return new IndexReplacementsCollection(array);
		}

		public IEnumerator<int> GetEnumerator()
		{
			return ((IEnumerable<int>)_replacementIndices).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _replacementIndices.GetEnumerator();
		}

		public bool Equals(IndexReplacementsCollection other)
		{
			if (Length == other.Length)
			{
				return _replacementIndices == other._replacementIndices;
			}
			return false;
		}
	}
	public static class InitializationManager
	{
		private static Harmony _harmonyInstance;

		private static GameObject _controllersRoot;

		public static void Init()
		{
			((MonoBehaviour)Main.Instance).StartCoroutine(DelayedInitialize());
		}

		public static IEnumerator DelayedInitialize()
		{
			yield return (object)new WaitForSeconds(1f);
			_harmonyInstance = new Harmony("Gorakh.RoR2Randomizer");
			_harmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
			PatchClassAttribute.ApplyAllPatches();
			_controllersRoot = new GameObject("RoR2Randomizer.Controllers");
			Object.DontDestroyOnLoad((Object)(object)_controllersRoot);
			((Object)_controllersRoot).hideFlags = (HideFlags)4;
			List<SearchableAttribute> instances = SearchableAttribute.GetInstances<RandomizerControllerAttribute>();
			if (instances != null)
			{
				foreach (SearchableAttribute item in instances)
				{
					if (item != null && item.target is Type type)
					{
						_controllersRoot.AddComponent(type);
					}
				}
			}
			OrbTargetDummyObjectMarker.InitNetworkPrefab();
		}

		public static void Cleanup()
		{
			Object.Destroy((Object)(object)_controllersRoot);
			_controllersRoot = null;
			_harmonyInstance.UnpatchSelf();
			_harmonyInstance = null;
			PatchClassAttribute.CleanupAllPatches();
		}
	}
	public static class MiscUtils
	{
		public static void AddItems<T>(ref T[] array, IEnumerable<T> items)
		{
			AddItems(ref array, (items is T[] array2) ? array2 : items.ToArray());
		}

		public static void AddItems<T>(ref T[] array, params T[] items)
		{
			int num = items.Length;
			if (num > 0)
			{
				int num2 = array.Length;
				Array.Resize(ref array, num2 + num);
				Array.Copy(items, 0, array, num2, num);
			}
		}

		public static bool ArrayEqual<T>(T[] a, T[] b, IEqualityComparer<T> equalityComparer = null)
		{
			if (a == null)
			{
				throw new ArgumentNullException("a");
			}
			if (b == null)
			{
				throw new ArgumentNullException("b");
			}
			if (equalityComparer == null)
			{
				equalityComparer = EqualityComparer<T>.Default;
			}
			if (a.Length != b.Length)
			{
				return false;
			}
			for (int i = 0; i < a.Length; i++)
			{
				if (!equalityComparer.Equals(a[i], b[i]))
				{
					return false;
				}
			}
			return true;
		}

		public static bool TryAssign<T>(ref T dest, T value, IEqualityComparer<T> comparer = null)
		{
			if ((comparer ?? EqualityComparer<T>.Default).Equals(dest, value))
			{
				return false;
			}
			dest = value;
			return true;
		}

		public static LinkedList<T> CreateReverseLinkedListFromLinks<T>(T value, TryConvertToNextValue<T> tryConvertToNext)
		{
			LinkedList<T> linkedList = new LinkedList<T>();
			do
			{
				linkedList.AddFirst(value);
			}
			while (tryConvertToNext(ref value));
			return linkedList;
		}

		public static LinkedList<T> CreateReverseLinkedListFromLinks<T>(T value, TryConvertDelegate<T> tryConvert)
		{
			return CreateReverseLinkedListFromLinks(value, tryConvert.ToConvertToNextValue());
		}

		public static LinkedList<T> CreateReverseLinkedListFromLinks<T>(T value, Func<T, T> tryGetNextValue) where T : class
		{
			return CreateReverseLinkedListFromLinks(value, tryGetNextValue.AddNullCheck());
		}

		public static void AppendDelegate<T>(ref T original, T additional) where T : Delegate
		{
			original = (T)Delegate.Combine(original, additional);
		}
	}
	public delegate void PrefabUndoModificationDelegate(GameObject prefab);
	public delegate PrefabUndoModificationDelegate PrefabPerformModificationDelegate(GameObject prefab);
	public class PrefabModificationTracker : MonoBehaviour
	{
		private readonly List<PrefabUndoModificationDelegate> _undoCallbacks = new List<PrefabUndoModificationDelegate>();

		public void PerformModification(PrefabPerformModificationDelegate modification)
		{
			if (modification == null)
			{
				throw new ArgumentNullException("modification");
			}
			PrefabUndoModificationDelegate prefabUndoModificationDelegate = modification(((Component)this).gameObject);
			if (prefabUndoModificationDelegate != null)
			{
				_undoCallbacks.Add(prefabUndoModificationDelegate);
			}
		}

		public void Undo()
		{
			foreach (PrefabUndoModificationDelegate undoCallback in _undoCallbacks)
			{
				undoCallback(((Component)this).gameObject);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	public class ProjectileParentChainNode : ISerializableObject
	{
		public ProjectileParentChainNode Parent;

		public ProjectileTypeIdentifier NodeIdentifier { get; private set; }

		public ProjectileParentChainNode(ProjectileTypeIdentifier nodeIdentifier)
		{
			NodeIdentifier = nodeIdentifier;
		}

		public ProjectileParentChainNode()
		{
		}

		public IEnumerable<ProjectileTypeIdentifier> ConstructChain()
		{
			return from n in MiscUtils.CreateReverseLinkedListFromLinks(this, (ProjectileParentChainNode t) => t.Parent)
				select n.NodeIdentifier;
		}

		public bool IsChildOf(ProjectileTypeIdentifier identifier)
		{
			if (identifier.IsValid)
			{
				return ConstructChain().Contains(identifier);
			}
			return false;
		}

		public void Deserialize(NetworkReader reader)
		{
			NodeIdentifier = new ProjectileTypeIdentifier(reader);
			if (reader.ReadBoolean())
			{
				Parent = new ProjectileParentChainNode();
				Parent.Deserialize(reader);
			}
		}

		public void Serialize(NetworkWriter writer)
		{
			NodeIdentifier.Serialize(writer);
			bool flag = Parent != null;
			writer.Write(flag);
			if (flag)
			{
				Parent.Serialize(writer);
			}
		}
	}
	[RequireComponent(typeof(ProjectileController))]
	public sealed class ProjectileParentChainTracker : MonoBehaviour
	{
		public ProjectileParentChainNode ChainNode { get; private set; }

		private void Awake()
		{
			ProjectileController component = ((Component)this).GetComponent<ProjectileController>();
			ChainNode = new ProjectileParentChainNode(new ProjectileTypeIdentifier(ProjectileType.OrdinaryProjectile, component.catalogIndex));
		}

		public void TrySetParent(GameObject parentObj)
		{
			ProjectileParentChainTracker projectileParentChainTracker = default(ProjectileParentChainTracker);
			if (parentObj.TryGetComponent<ProjectileParentChainTracker>(ref projectileParentChainTracker))
			{
				SetParent(projectileParentChainTracker.ChainNode);
			}
		}

		public void SetParent(ProjectileParentChainNode node)
		{
			ChainNode.Parent = node;
		}

		public bool IsChildOf(ProjectileTypeIdentifier identifier)
		{
			if (ChainNode != null)
			{
				return ChainNode.IsChildOf(identifier);
			}
			return false;
		}
	}
	public static class ReflectionUtils
	{
		public static MethodInfo FindImplicitConversion(Type from, Type to)
		{
			foreach (MethodInfo item in from.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public).Concat(to.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public)))
			{
				if (item.IsSpecialName && item.Name == "op_Implicit" && item.ReturnType == to)
				{
					ParameterInfo[] parameters = item.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType == from)
					{
						return item;
					}
				}
			}
			throw new MissingMethodException("No implicit conversion " + GeneralExtensions.FullDescription(from) + " -> " + GeneralExtensions.FullDescription(to) + " could be found");
		}

		public static LinkedList<Type> GetTypeHierarchyList(Type type)
		{
			return MiscUtils.CreateReverseLinkedListFromLinks(type, (Type t) => t.BaseType);
		}
	}
	public class ReplacementDictionary<T> : ReadOnlyDictionary<T, T>
	{
		private readonly InitializeOnAccess<ReadOnlyDictionary<T, T>> _reverseDictionary;

		public static ReplacementDictionary<T> CreateFrom<TSrc>(IEnumerable<TSrc> collection, Xoroshiro128Plus rng, Func<TSrc, T> converter, Func<TSrc, TSrc, bool> canReplaceFunc)
		{
			return CreateFrom(collection, rng, converter, canReplaceFunc, null);
		}

		public static ReplacementDictionary<T> CreateFrom<TSrc>(IEnumerable<TSrc> collection, Xoroshiro128Plus rng, Func<TSrc, T> converter, Func<TSrc, TSrc, bool> canReplaceFunc, Func<TSrc, TSrc, float> weightSelector)
		{
			Dictionary<T, T> dictionary = new Dictionary<T, T>();
			List<TSrc> list = new List<TSrc>(collection);
			List<TSrc> list2 = new List<TSrc>(list);
			bool flag = canReplaceFunc != null;
			bool flag2 = weightSelector != null;
			while (list.Count > 0)
			{
				TSrc key = list.GetAndRemoveAt(0);
				IEnumerable<TSrc> enumerable2;
				if (!flag)
				{
					IEnumerable<TSrc> enumerable = list2;
					enumerable2 = enumerable;
				}
				else
				{
					enumerable2 = list2.Where((TSrc v) => canReplaceFunc(key, v));
				}
				IEnumerable<TSrc> enumerable3 = enumerable2;
				if (enumerable3.Any())
				{
					TSrc val = ((!flag2) ? enumerable3.GetRandomOrDefault(rng) : enumerable3.PickWeighted(rng, (TSrc v) => weightSelector(key, v)));
					list2.Remove(val);
					dictionary.Add(converter(key), converter(val));
				}
				else
				{
					Log.Warning(string.Format("({0}={1}, {2}={3}) No valid replacement exists for key '{4}'. It will be excluded from the resulting dictionary", "T", typeof(T).Name, "TSrc", typeof(TSrc).Name, key), "C:\\Users\\michi\\source\\repos\\RoR2Randomizer\\RoR2Randomizer\\RoR2Randomizer\\Utility\\ReplacementDictionary.cs", "CreateFrom", 51);
					list2.Remove(key);
				}
			}
			return new ReplacementDictionary<T>(dictionary);
		}

		public static ReplacementDictionary<T> CreateFrom(IEnumerable<T> collection, Xoroshiro128Plus rng)
		{
			return CreateFrom(collection, rng, (Func<T, T, bool>)null, (Func<T, T, float>)null);
		}

		public static ReplacementDictionary<T> CreateFrom(IEnumerable<T> collection, Xoroshiro128Plus rng, Func<T, T, bool> canReplaceFunc, Func<T, T, float> weightSelector)
		{
			return CreateFrom(collection, rng, (T t) => t, canReplaceFunc, weightSelector);
		}

		public static ReplacementDictionary<T> CreateFrom(IEnumerable<T> collection, Xoroshiro128Plus rng, Func<T, T, bool> canReplaceFunc)
		{
			return CreateFrom(collection, rng, (T t) => t, canReplaceFunc, null);
		}

		public ReplacementDictionary(IDictionary<T, T> dict)
			: base(dict)
		{
			_reverseDictionary = (InitializeOnAccess<ReadOnlyDictionary<T, T>>)(object)new InitializeOnAccess<ReadOnlyDictionary<ReadOnlyDictionary<T, T>, ReadOnlyDictionary<T, T>>>((Func<ReadOnlyDictionary<ReadOnlyDictionary<T, T>, ReadOnlyDictionary<T, T>>>)(object)(Func<ReadOnlyDictionary<T, T>>)delegate
			{
				Dictionary<T, T> dictionary = new Dictionary<T, T>();
				using (IEnumerator<KeyValuePair<T, T>> enumerator = GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						KeyValuePair<T, T> current = enumerator.Current;
						dictionary[current.Value] = current.Key;
					}
				}
				return new ReadOnlyDictionary<T, T>(dictionary);
			});
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool TryGetReplacement(T original, out T replacement)
		{
			return TryGetValue(original, out replacement);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool HasReplacement(T original)
		{
			return ContainsKey(original);
		}

		public bool TryGetOriginal(T replacement, out T original)
		{
			return ((InitializeOnAccess<ReadOnlyDictionary<ReadOnlyDictionary<T, T>, ReadOnlyDictionary<T, T>>>)(object)_reverseDictionary).Get.TryGetValue(replacement, out original);
		}
	}
	public static class RNGManager
	{
		public static RunSpecific<Xoroshiro128Plus> RandomizerServerRNG { get; private set; }

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			RandomizerServerRNG = new RunSpecific<Xoroshiro128Plus>(delegate(out Xoroshiro128Plus result)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				if (NetworkServer.active)
				{
					result = new Xoroshiro128Plus(Run.instance.runRNG.Next());
					return true;
				}
				result = null;
				return false;
			}, 10);
		}
	}
	public class RunSpecific<T> : IDisposable
	{
		public delegate bool TryGetNewValueDelegate(out T value);

		private ulong? _callbackHandle;

		private readonly TryGetNewValueDelegate _getNewValue;

		private readonly T _defaultValue;

		private T _value;

		public bool HasValue { get; private set; }

		public T Value
		{
			get
			{
				return _value;
			}
			set
			{
				_value = value;
				bool flag = ((!(value is IEquatable<T> equatable)) ? ((!(_defaultValue is IEquatable<T> equatable2)) ? EqualityComparer<T>.Default.Equals(value, _defaultValue) : equatable2.Equals(value)) : equatable.Equals(_defaultValue));
				HasValue = !flag;
			}
		}

		public RunSpecific(int priority = 0, T defaultValue = default(T))
			: this((TryGetNewValueDelegate)null, priority, defaultValue)
		{
		}

		public RunSpecific(Func<T> getValueFunc, int priority = 0, T defaultValue = default(T))
			: this((TryGetNewValueDelegate)delegate(out T value)
			{
				value = getValueFunc();
				return true;
			}, priority, defaultValue)
		{
		}

		public RunSpecific(TryGetNewValueDelegate getNewValue, int priority = 0, T defaultValue = default(T))
		{
			_getNewValue = getNewValue;
			Value = (_defaultValue = defaultValue);
			HasValue = false;
			_callbackHandle = RunSpecificCallbacksManager.AddEntry(onRunStart, onRunEnd, priority);
		}

		~RunSpecific()
		{
			if (_callbackHandle.HasValue)
			{
				Dispose();
			}
		}

		private void onRunStart(Run instance)
		{
			if (_getNewValue != null && !HasValue)
			{
				if (_getNewValue(out var value))
				{
					Value = value;
				}
				else
				{
					Value = _defaultValue;
				}
			}
		}

		private void onRunEnd(Run instance)
		{
			Value = _defaultValue;
		}

		public void Dispose()
		{
			if (_callbackHandle.HasValue)
			{
				RunSpecificCallbacksManager.RemoveEntry(_callbackHandle.Value);
				_callbackHandle = null;
			}
		}

		public static implicit operator T(RunSpecific<T> runSpecific)
		{
			return runSpecific.Value;
		}
	}
	internal static class RunSpecificCallbacksManager
	{
		private readonly struct CallbackEntry
		{
			private class Comparer : IComparer<CallbackEntry>
			{
				int IComparer<CallbackEntry>.Compare(CallbackEntry x, CallbackEntry y)
				{
					return y._priority.CompareTo(x._priority);
				}
			}

			private static ulong _nextHandleIndex = 0uL;

			public readonly ulong Handle;

			public readonly Action<Run> OnStartRun;

			public readonly Action<Run> OnEndRun;

			private readonly int _priority;

			public static readonly IComparer<CallbackEntry> PriorityComparer = new Comparer();

			public CallbackEntry(int priority, Action<Run> onStartRun, Action<Run> onEndRun)
			{
				_priority = priority;
				OnStartRun = onStartRun;
				OnEndRun = onEndRun;
				Handle = _nextHandleIndex;
				checked
				{
					try
					{
						_nextHandleIndex++;
					}
					catch (OverflowException)
					{
						_nextHandleIndex = 0uL;
					}
				}
			}
		}

		private static readonly List<CallbackEntry> _callbackEntries;

		static RunSpecificCallbacksManager()
		{
			_callbackEntries = new List<CallbackEntry>();
			Run.onRunStartGlobal += onRunStart;
			Run.onRunDestroyGlobal += onRunEnd;
		}

		private static void onRunStart(Run instance)
		{
			foreach (CallbackEntry callbackEntry in _callbackEntries)
			{
				callbackEntry.OnStartRun?.Invoke(instance);
			}
		}

		private static void onRunEnd(Run instance)
		{
			foreach (CallbackEntry callbackEntry in _callbackEntries)
			{
				callbackEntry.OnEndRun?.Invoke(instance);
			}
		}

		public static ulong AddEntry(Action onStart, Action onEnd, int priority)
		{
			return AddEntry(convertToRunCallback(onStart), convertToRunCallback(onEnd), priority);
			static Action<Run> convertToRunCallback(Action original)
			{
				if (original == null)
				{
					return null;
				}
				return delegate
				{
					original();
				};
			}
		}

		public static ulong AddEntry(Action<Run> onStart, Action<Run> onEnd, int priority)
		{
			CallbackEntry item = new CallbackEntry(priority, onStart, onEnd);
			_callbackEntries.Add(item);
			_callbackEntries.Sort(CallbackEntry.PriorityComparer);
			return item.Handle;
		}

		public static void RemoveEntry(ulong callbackHandle)
		{
			int num = _callbackEntries.FindIndex((CallbackEntry c) => c.Handle == callbackHandle);
			if (num != -1)
			{
				_callbackEntries.RemoveAt(num);
			}
			else
			{
				Log.Warning($"Attempted to remove entry with handle {callbackHandle}, but it was not found in the list", "C:\\Users\\michi\\source\\repos\\RoR2Randomizer\\RoR2Randomizer\\RoR2Randomizer\\Utility\\RunSpecificCallbacksManager.cs", "RemoveEntry", 104);
			}
		}
	}
	public static class RunSpecificLanguageOverlay
	{
		private static readonly List<LanguageOverlay> _activeOverlays;

		static RunSpecificLanguageOverlay()
		{
			_activeOverlays = new List<LanguageOverlay>();
			Run.onRunDestroyGlobal += onRunEnd;
		}

		private static void onRunEnd(Run _)
		{
			foreach (LanguageOverlay activeOverlay in _activeOverlays)
			{
				activeOverlay.Remove();
			}
			_activeOverlays.Clear();
		}

		public static void AddRunLanguageOverlay(LanguageOverlay overlay)
		{
			_activeOverlays.Add(overlay);
		}
	}
	public static class SpawnCardTracker
	{
		public static SpawnCard MithrixNormalSpawnCard;

		public static SpawnCard MithrixHurtSpawnCard;

		public static SpawnCard[] MithrixPhase2SpawnCards;

		public static SpawnCard[] VoidlingPhasesSpawnCards;

		public static SpawnCard[] FalseSonPhasesSpawnCards;

		public static SpawnCard AurelioniteSpawnCard;

		public static SpawnCard SolusWingSpawnCard;

		public static MultiCharacterSpawnCard LunarScavSpawnCard;

		public static SpawnCard AlloyWorshipUnitSpawnCard;

		private static bool isPartOf(SpawnCard[] array, SpawnCard card, out int index)
		{
			if (array != null)
			{
				index = Array.IndexOf(array, card);
				return index != -1;
			}
			index = -1;
			return false;
		}

		public static bool IsPartOfMithrixPhase2(SpawnCard card)
		{
			int index;
			return isPartOf(MithrixPhase2SpawnCards, card, out index);
		}

		public static bool IsAnyVoidlingPhase(SpawnCard card)
		{
			int index;
			return isPartOf(VoidlingPhasesSpawnCards, card, out index);
		}

		public static bool IsAnyFalseSonPhase(SpawnCard card)
		{
			return ((Object)card).name.Contains("FalseSon");
		}
	}
	public class TempComponentsTracker : MonoBehaviour
	{
		private readonly List<Component> _trackedComponents = new List<Component>();

		private void track(Component component)
		{
			_trackedComponents.Add(component);
		}

		public void RemoveAll()
		{
			foreach (Component trackedComponent in _trackedComponents)
			{
				if (Object.op_Implicit((Object)(object)trackedComponent))
				{
					Object.Destroy((Object)(object)trackedComponent);
				}
			}
			Object.Destroy((Object)(object)this);
		}

		public bool TryRemove<T>() where T : Component
		{
			return TryRemove(typeof(T));
		}

		public bool TryRemove(Type componentType)
		{
			for (int num = _trackedComponents.Count - 1; num >= 0; num--)
			{
				if (Object.op_Implicit((Object)(object)_trackedComponents[num]))
				{
					if (((object)_trackedComponents[num]).GetType() == componentType)
					{
						Object.Destroy((Object)(object)_trackedComponents[num]);
						_trackedComponents.RemoveAt(num);
						if (_trackedComponents.Count == 0)
						{
							Object.Destroy((Object)(object)this);
						}
						return true;
					}
				}
				else
				{
					_trackedComponents.RemoveAt(num);
				}
			}
			if (_trackedComponents.Count == 0)
			{
				Object.Destroy((Object)(object)this);
			}
			return false;
		}

		public static T AddTempComponent<T>(MonoBehaviour owner) where T : Component
		{
			return (T)(object)AddTempComponent(owner, typeof(T));
		}

		public static Component AddTempComponent(MonoBehaviour owner, Type type)
		{
			GameObject gameObject = ((Component)owner).gameObject;
			Component val = gameObject.AddComponent(type);
			gameObject.GetOrAddComponent<TempComponentsTracker>().track(val);
			return val;
		}

		public static TempComponentsTracker AddTempComponents(MonoBehaviour owner, params Type[] componentTypes)
		{
			GameObject gameObject = ((Component)owner).gameObject;
			TempComponentsTracker orAddComponent = gameObject.GetOrAddComponent<TempComponentsTracker>();
			foreach (Type type in componentTypes)
			{
				orAddComponent.track(gameObject.AddComponent(type));
			}
			return orAddComponent;
		}

		public static bool RemoveAllTempComponents(MonoBehaviour owner)
		{
			TempComponentsTracker component = ((Component)owner).GetComponent<TempComponentsTracker>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			component.RemoveAll();
			return true;
		}

		public static bool TryRemoveTempComponent<T>(MonoBehaviour owner) where T : Component
		{
			return TryRemoveTempComponent(owner, typeof(T));
		}

		public static bool TryRemoveTempComponent(MonoBehaviour owner, Type componentType)
		{
			if (!Object.op_Implicit((Object)(object)owner))
			{
				return false;
			}
			TempComponentsTracker component = ((Component)owner).GetComponent<TempComponentsTracker>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return component.TryRemove(componentType);
			}
			return false;
		}
	}
	public readonly struct TimeoutActionResult
	{
		public readonly float TimeElapsed;

		public readonly TimeoutActionResultState State;

		public TimeoutActionResult(float timeElapsed, TimeoutActionResultState state)
		{
			TimeElapsed = timeElapsed;
			State = state;
		}
	}
	public enum TimeoutActionResultState : byte
	{
		Finished,
		TimedOut
	}
	public struct TrackedValue<T>
	{
		private readonly IEqualityComparer<T> _comparer;

		private T _value;

		public T Value
		{
			get
			{
				return _value;
			}
			set
			{
				if (MiscUtils.TryAssign(ref _value, value, _comparer))
				{
					this.OnChanged?.Invoke(value);
				}
			}
		}

		public event Action<T> OnChanged;

		public TrackedValue(T value = default(T), IEqualityComparer<T> comparer = null)
		{
			this.OnChanged = null;
			_value = value;
			_comparer = comparer;
		}

		public static implicit operator T(TrackedValue<T> tracked)
		{
			return tracked.Value;
		}
	}
}
namespace RoR2Randomizer.Utility.Patching
{
	internal static class Discard<T>
	{
		public static T Value;
	}
	public static class StaticReflectionCache
	{
		public static readonly MethodInfo Animator_GetFloat_name_MI = SymbolExtensions.GetMethodInfo<Animator>((Expression<Action<Animator>>)((Animator _) => _.GetFloat((string)null)));

		public static readonly MethodInfo Physics_Raycast_Ray_outRaycastHit_float_MI = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Physics.Raycast(default(Ray), ref Discard<RaycastHit>.Value, 0f)));

		public static readonly MethodInfo EntityState_get_skillLocator = AccessTools.PropertyGetter(typeof(EntityState), "skillLocator");

		public static readonly MethodInfo EntityStateCatalog_InstantiateState_Type_MI = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => EntityStateCatalog.InstantiateState((Type)null)));

		public static readonly MethodInfo EntityStateCatalog_InstantiateState_SerializableEntityStateType_MI = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => EntityStateCatalog.InstantiateState((EntityStateIndex)0)));
	}
}
namespace RoR2Randomizer.Utility.EnemyInfoEquipmentDisplay
{
	[RequireComponent(typeof(EnemyInfoPanel))]
	public class EnemyInfoPanelEquipmentDisplayController : MonoBehaviour
	{
		private EnemyInfoPanel _enemyInfoPanel;

		private GameObject _equipmentContainer;

		private EquipmentInventoryDisplay _equipmentDisplay;

		private EquipmentIndex[] _lastEquipmentIndices = Array.Empty<EquipmentIndex>();

		private const string EQUIPMENT_LABEL_TOKEN = "ARENA_HUD_MONSTER_EQUIPMENTS_LABEL";

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			LanguageAPI.Add("ARENA_HUD_MONSTER_EQUIPMENTS_LABEL", "Monsters' Equipment");
		}

		private void Awake()
		{
			_enemyInfoPanel = ((Component)this).GetComponent<EnemyInfoPanel>();
			initializeEquipmentContainer();
		}

		private void initializeEquipmentContainer()
		{
			_equipmentContainer = Object.Instantiate<GameObject>(_enemyInfoPanel.inventoryContainer, _enemyInfoPanel.inventoryContainer.transform.parent);
			((Object)_equipmentContainer).name = "EquipmentContainer";
			Transform obj = _equipmentContainer.transform.Find("InventoryLabel");
			((Object)obj).name = "EquipmentLabel";
			((Component)obj).GetComponent<LanguageTextMeshController>().token = "ARENA_HUD_MONSTER_EQUIPMENTS_LABEL";
			Transform val = _equipmentContainer.transform.Find("InventoryDisplay");
			((Object)val).name = "EquipmentDisplay";
			Object.Destroy((Object)(object)((Component)val).GetComponent<ItemInventoryDisplay>());
			_equipmentDisplay = ((Component)val).gameObject.AddComponent<EquipmentInventoryDisplay>();
			_equipmentContainer.SetActive(false);
		}

		public void TrySetEquipments(EquipmentIndex[] equipments)
		{
			if (!MiscUtils.ArrayEqual(_lastEquipmentIndices, equipments))
			{
				_equipmentContainer.SetActive(equipments.Length != 0);
				_lastEquipmentIndices = equipments;
				_equipmentDisplay.SetEquipments(equipments);
			}
		}
	}
	[RequireComponent(typeof(RectTransform))]
	public class EquipmentInventoryDisplay : UIBehaviour, ILayoutElement
	{
		private struct LayoutValues
		{
			public float Width;

			public float Height;

			public float IconSize;

			public int IconsPerRow;

			public float RowWidth;

			public int RowCount;

			public Vector3 IconLocalScale;

			public Vector3 TopLeftCorner;
		}

		private const float EQUIPMENT_ICON_PREFAB_WIDTH = 32f;

		private const float MAX_ICON_WIDTH = 32f;

		private const float MAX_HEIGHT = 256f;

		private const float VERTICAL_MARGIN = 8f;

		private RectTransform _rectTransform;

		private readonly List<GenericPickupIcon> _equipmentIcons = new List<GenericPickupIcon>();

		private EquipmentIndex[] _equipments;

		private float _currentIconScale = 1f;

		private float _previousWidth;

		private bool _updateRequestPending;

		private Inventory _inventory;

		private bool _inventoryWasValid;

		private bool isUninitialized => (Object)(object)_rectTransform == (Object)null;

		public float minWidth => preferredWidth;

		public float preferredWidth
		{
			get
			{
				//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)
				Rect rect = _rectTransform.rect;
				return ((Rect)(ref rect)).width;
			}
		}

		public float flexibleWidth => 0f;

		public float minHeight => preferredHeight;

		public float preferredHeight { get; set; }

		public float flexibleHeight => 0f;

		public int layoutPriority => 0;

		public void SetSubscribedInventory(Inventory newInventory)
		{
			if (!((Object)(object)_inventory == (Object)(object)newInventory) || Object.op_Implicit((Object)(object)_inventory) != _inventoryWasValid)
			{
				if ((Object)(object)_inventory != (Object)null)
				{
					_inventory.onInventoryChanged -= onInventoryChanged;
					_inventory = null;
				}
				_inventory = newInventory;
				_inventoryWasValid = Object.op_Implicit((Object)(object)_inventory);
				if (Object.op_Implicit((Object)(object)_inventory))
				{
					_inventory.onInventoryChanged += onInventoryChanged;
				}
				onInventoryChanged();
			}
		}

		private void onInventoryChanged()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected I4, but got Unknown
			if (!((Behaviour)this).isActiveAndEnabled)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_inventory))
			{
				int equipmentSlotCount = _inventory.GetEquipmentSlotCount();
				_equipments = (EquipmentIndex[])(object)new EquipmentIndex[equipmentSlotCount];
				for (uint num = 0u; num < equipmentSlotCount; num++)
				{
					_equipments[num] = (EquipmentIndex)(int)_inventory.GetEquipment(num).equipmentIndex;
				}
			}
			else
			{
				Array.Clear(_equipments, 0, _equipments.Length);
			}
			requestUpdateDisplay();
		}

		private void allocateIcons(int desiredItemCount)
		{
			if (desiredItemCount != _equipmentIcons.Count)
			{
				while (_equipmentIcons.Count > desiredItemCount)
				{
					Object.Destroy((Object)(object)((Component)_equipmentIcons[_equipmentIcons.Count - 1]).gameObject);
					_equipmentIcons.RemoveAt(_equipmentIcons.Count - 1);
				}
				calculateLayoutValues(out var v, desiredItemCount);
				while (_equipmentIcons.Count < desiredItemCount)
				{
					GenericPickupIcon component = Object.Instantiate<GameObject>(GenericPickupIcon.Prefab, (Transform)(object)_rectTransform).GetComponent<GenericPickupIcon>();
					_equipmentIcons.Add(component);
					layoutIndividualIcon(in v, _equipmentIcons.Count - 1);
				}
			}
			onIconCountChanged();
		}

		private float calculateIconScale(int iconCount)
		{
			//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)
			Rect rect = _rectTransform.rect;
			int num = (int)((Rect)(ref rect)).width;
			int num2 = 256;
			int num3 = 32;
			int num4 = num3;
			int num5 = num3 / 8;
			int num6 = Math.Max(num / num4, 1);
			int num7 = HGMath.IntDivCeil(iconCount, num6);
			while (num4 * num7 > num2)
			{
				num6++;
				num4 = Math.Min(num / num6, num3);
				num7 = HGMath.IntDivCeil(iconCount, num6);
				if (num4 <= num5)
				{
					num4 = num5;
					break;
				}
			}
			num4 = Math.Min(num4, 32);
			return (float)num4 / (float)num3;
		}

		private void onIconCountChanged()
		{
			float num = calculateIconScale(_equipmentIcons.Count);
			if (num != _currentIconScale)
			{
				_currentIconScale = num;
				onIconScaleChanged();
			}
		}

		private void onIconScaleChanged()
		{
			layoutAllIcons();
		}

		private void calculateLayoutValues(out LayoutValues v, int iconCount)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			float num = calculateIconScale(_equipmentIcons.Count);
			Rect rect = _rectTransform.rect;
			v.Width = ((Rect)(ref rect)).width;
			v.IconSize = 32f * num;
			v.IconsPerRow = Math.Max((int)v.Width / (int)v.IconSize, 1);
			v.RowWidth = (float)v.IconsPerRow * v.IconSize;
			float num2 = (v.Width - v.RowWidth) * 0.5f;
			v.RowCount = HGMath.IntDivCeil(_equipmentIcons.Count, v.IconsPerRow);
			v.IconLocalScale = new Vector3(num, num, 1f);
			v.TopLeftCorner = new Vector3(((Rect)(ref rect)).xMin + num2, ((Rect)(ref rect)).yMax - 8f);
			v.Height = v.IconSize * (float)v.RowCount + 16f;
		}

		private void layoutAllIcons()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			calculateLayoutValues(out var v, _equipmentIcons.Count);
			int num = _equipmentIcons.Count - (v.RowCount - 1) * v.IconsPerRow;
			int i = 0;
			int num2 = 0;
			for (; i < v.RowCount; i++)
			{
				Vector3 topLeftCorner = v.TopLeftCorner;
				topLeftCorner.y += (float)i * (0f - v.IconSize);
				int num3 = v.IconsPerRow;
				if (i == v.RowCount - 1)
				{
					num3 = num;
				}
				int num4 = 0;
				while (num4 < num3)
				{
					RectTransform rectTransform = _equipmentIcons[num2].rectTransform;
					((Transform)rectTransform).localScale = v.IconLocalScale;
					((Transform)rectTransform).localPosition = topLeftCorner;
					topLeftCorner.x += v.IconSize;
					num4++;
					num2++;
				}
			}
		}

		private void layoutIndividualIcon(in LayoutValues layoutValues, int i)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			int num = i / layoutValues.IconsPerRow;
			int num2 = i - num * layoutValues.IconsPerRow;
			Vector3 topLeftCorner = layoutValues.TopLeftCorner;
			topLeftCorner.x += (float)num2 * layoutValues.IconSize;
			topLeftCorner.y += (float)num * (0f - layoutValues.IconSize);
			RectTransform rectTransform = _equipmentIcons[i].rectTransform;
			((Transform)rectTransform).localPosition = topLeftCorner;
			((Transform)rectTransform).localScale = layoutValues.IconLocalScale;
		}

		private void cacheComponents()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			_rectTransform = (RectTransform)((Component)this).transform;
		}

		protected override void Awake()
		{
			((UIBehaviour)this).Awake();
			cacheComponents();
			_equipments = Array.Empty<EquipmentIndex>();
		}

		protected override void OnDestroy()
		{
			SetSubscribedInventory(null);
			((UIBehaviour)this).OnDestroy();
		}

		protected override void OnEnable()
		{
			((UIBehaviour)this).OnEnable();
			if (Object.op_Implicit((Object)(object)_inventory))
			{
				onInventoryChanged();
			}
			requestUpdateDisplay();
			layoutAllIcons();
		}

		private void requestUpdateDisplay()
		{
			if (!_updateRequestPending)
			{
				_updateRequestPending = true;
				RoR2Application.onNextUpdate += UpdateDisplay;
			}
		}

		public void UpdateDisplay()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			_updateRequestPending = false;
			if (Object.op_Implicit((Object)(object)this) && ((Behaviour)this).isActiveAndEnabled)
			{
				allocateIcons(_equipments.Length);
				for (int i = 0; i < _equipments.Length; i++)
				{
					_equipmentIcons[i].SetPickupIndex(PickupCatalog.FindPickupIndex(_equipments[i]));
				}
			}
		}

		public void SetEquipments(EquipmentIndex[] newEquipments)
		{
			_equipments = newEquipments;
			requestUpdateDisplay();
		}

		public void ResetEquipments()
		{
			Array.Clear(_equipments, 0, _equipments.Length);
			requestUpdateDisplay();
		}

		protected override void OnRectTransformDimensionsChange()
		{
			//IL_0019: 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)
			((UIBehaviour)this).OnRectTransformDimensionsChange();
			if (Object.op_Implicit((Object)(object)_rectTransform))
			{
				Rect rect = _rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				if (width != _previousWidth)
				{
					_previousWidth = width;
					layoutAllIcons();
				}
			}
		}

		public void CalculateLayoutInputHorizontal()
		{
		}

		public void CalculateLayoutInputVertical()
		{
			if (!isUninitialized)
			{
				calculateLayoutValues(out var v, _equipmentIcons.Count);
				preferredHeight = v.Height;
			}
		}

		protected void OnValidate()
		{
			cacheComponents();
		}
	}
	[RequireComponent(typeof(RectTransform))]
	public class GenericPickupIcon : MonoBehaviour
	{
		public static readonly GameObject Prefab;

		[SerializeField]
		private RawImage _glowImage;

		[SerializeField]
		private RawImage _image;

		[SerializeField]
		private TextMeshProUGUI _stackText;

		[SerializeField]
		private TooltipProvider _tooltipProvider;

		private PickupIndex _pickupIndex;

		private int _count;

		public RectTransform rectTransform { get; private set; }

		static GenericPickupIcon()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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)
			Prefab = Object.Instantiate<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/ItemIcon.prefab").WaitForCompletion());
			Object.DontDestroyOnLoad((Object)(object)Prefab);
			((Object)Prefab).hideFlags = (HideFlags)61;
			((Object)Prefab).name = "PickupIcon";
			ItemIcon component = Prefab.GetComponent<ItemIcon>();
			GenericPickupIcon genericPickupIcon = Prefab.AddComponent<GenericPickupIcon>();
			genericPickupIcon._glowImage = component.glowImage;
			genericPickupIcon._image = component.image;
			genericPickupIcon._stackText = component.stackText;
			genericPickupIcon._tooltipProvider = component.tooltipProvider;
			((RectTransform)((Component)genericPickupIcon).transform).sizeDelta = new Vector2(32f, 32f);
			Object.Destroy((Object)(object)component);
		}

		private void Awake()
		{
			CacheRectTransform();
		}

		public void CacheRectTransform()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if ((Object)(object)rectTransform == (Object)null)
			{
				rectTransform = (RectTransform)((Component)this).transform;
			}
		}

		public void SetPickupIndex(PickupIndex newPickupIndex, int newPickupCount = 1)
		{
			//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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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)
			//IL_00cb: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			if (_pickupIndex == newPickupIndex && _count == newPickupCount)
			{
				return;
			}
			_pickupIndex = newPickupIndex;
			_count = newPickupCount;
			string titleToken = "";
			string bodyToken = "";
			Color val = Color.white;
			Color bodyColor = default(Color);
			((Color)(ref bodyColor))..ctor(0.6f, 0.6f, 0.6f, 1f);
			PickupDef pickupDef = PickupCatalog.GetPickupDef(_pickupIndex);
			if (pickupDef != null)
			{
				_image.texture = pickupDef.iconTexture;
				if (_count > 1)
				{
					((Behaviour)_stackText).enabled = true;
					((TMP_Text)_stackText).text = $"x{_count}";
				}
				else
				{
					((Behaviour)_stackText).enabled = false;
				}
				titleToken = pickupDef.nameToken;
				val = pickupDef.darkColor;
				bodyToken = "???";
				if (pickupDef.IsItem())
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
					if ((Object)(object)itemDef != (Object)null)
					{
						bodyToken = itemDef.pickupToken;
					}
				}
				else if (pickupDef.IsEquipment())
				{
					EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex);
					if ((Object)(object)equipmentDef != (Object)null)
					{
						bodyToken = equipmentDef.pickupToken;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)_glowImage))
			{
				((Graphic)_glowImage).color = new Color(val.r, val.g, val.b, 0.75f);
			}
			if (Object.op_Implicit((Object)(object)_tooltipProvider))
			{
				_tooltipProvider.titleToken = titleToken;
				_tooltipProvider.bodyToken = bodyToken;
				_tooltipProvider.titleColor = val;
				_tooltipProvider.bodyColor = bodyColor;
			}
		}
	}
}
namespace RoR2Randomizer.Utility.Comparers
{
	public sealed class MasterIndexComparer : IComparer<MasterIndex>
	{
		public static readonly MasterIndexComparer Instance = new MasterIndexComparer();

		private MasterIndexComparer()
		{
		}

		public int Compare(MasterIndex x, MasterIndex y)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return ((int)x).CompareTo((int)y);
		}
	}
	public sealed class PickupIndexComparer : IComparer<PickupIndex>
	{
		public static readonly PickupIndexComparer Instance = new PickupIndexComparer();

		private PickupIndexComparer()
		{
		}

		public int Compare(PickupIndex x, PickupIndex y)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return x.value.CompareTo(y.value);
		}
	}
}
namespace RoR2Randomizer.Utility.Catalog
{
	public abstract class GenericCatalog<TObjects, TIdentifier> : IEnumerable<TIdentifier>, IEnumerable where TIdentifier : ICatalogIdentifier<TObjects, TIdentifier>
	{
		public delegate void IdentifierAppendedDelegate(in TIdentifier identifier);

		protected static readonly string LOG_PREFIX_TYPE = "(TObjects=" + typeof(TObjects).Name + ", TIdentifier=" + typeof(TIdentifier).Name + ") ";

		protected int _identifiersCount;

		protected TIdentifier[] _identifiers = new TIdentifier[20];

		protected virtual TIdentifier InvalidIdentifier => default(TIdentifier);

		public event IdentifierAppendedDelegate OnIdentifierAppended;

		public TIdentifier GetIdentifier(int index)
		{
			if (index < 0 || index >= _identifiersCount)
			{
				return InvalidIdentifier;
			}
			return _identifiers[index];
		}

		protected void appendIdentifier(ref TIdentifier identifier, bool checkExisting)
		{
			if (checkExisting)
			{
				for (int i = 0; i < _identifiersCount; i++)
				{
					if (_identifiers[i].Equals(in identifier, compareIndex: false))
					{
						return;
					}
				}
			}
			int identifiersCount = _identifiersCount;
			identifier.Index = identifiersCount;
			ArrayUtils.ArrayAppend<TIdentifier>(ref _identifiers, ref _identifiersCount, ref identifier);
			this.OnIdentifierAppended?.Invoke(in identifier);
		}

		protected bool tryGetAttackIdentifier(TObjects obj, out TIdentifier identifier)
		{
			foreach (TIdentifier item in _identifiers.Take(_identifiersCount))
			{
				if (item.Matches(obj))
				{
					identifier = item;
					return true;
				}
			}
			identifier = default(TIdentifier);
			return false;
		}

		public virtual TIdentifier GetIdentifier(TObjects obj)
		{
			if (!tryGetAttackIdentifier(obj, out var identifier))
			{
				return InvalidIdentifier;
			}
			return identifier;
		}

		public IEnumerator<TIdentifier> GetEnumerator()
		{
			return _identifiers.Take(_identifiersCount).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public abstract class GenericNetworkedCatalog<TObject, TIdentifier> : GenericCatalog<TObject, TIdentifier>, INetMessageProvider where TIdentifier : ICatalogIdentifier<TObject, TIdentifier>
	{
		public virtual bool SendMessages => true;

		protected GenericNetworkedCatalog()
		{
			NetworkingManager.RegisterMessageProvider(this, MessageProviderFlags.Persistent);
		}

		protected abstract bool tryCreateIdentifierForObject(TObject obj, out TIdentifier identifier);

		public override TIdentifier GetIdentifier(TObject obj)
		{
			TIdentifier identifier = base.GetIdentifier(obj);
			if (!identifier.IsValid)
			{
				if (!tryCreateIdentifierForObject(obj, out identifier))
				{
					return InvalidIdentifier;
				}
				if (!NetworkServer.active)
				{
					if (NetworkClient.active)
					{
						NetworkMessageBase syncIdentifierNeededMessage = getSyncIdentifierNeededMessage(in identifier);
						if (syncIdentifierNeededMessage != null)
						{
							syncIdentifierNeededMessage.SendTo((NetworkDestination)2);
						}
						else
						{
							Log.Warning(GenericCatalog<TObject, TIdentifier>.LOG_PREFIX_TYPE + "catalog is networked, but syncIdentifierNeededMessage is null", "C:\\Users\\michi\\source\\repos\\RoR2Randomizer\\RoR2Randomizer\\RoR2Randomizer\\Utility\\Catalog\\GenericNetworkedCatalog.cs", "GetIdentifier", 52);
						}
					}
					return InvalidIdentifier;
				}
				appendIdentifier(ref identifier, checkExisting: false);
				if (!NetworkServer.dontListen)
				{
					this.TrySendAll((NetworkDestination)1);
				}
			}
			return identifier;
		}

		protected abstract NetworkMessageBase getSyncIdentifierNeededMessage(in TIdentifier identifier);

		public abstract IEnumerable<NetworkMessageBase> GetNetMessages();

		protected void SyncCatalog_OnReceive(TIdentifier[] identifiers, int identifiersCount)
		{
			if (!NetworkServer.active && NetworkClient.active)
			{
				_identifiersCount = identifiersCount;
				ArrayUtils.EnsureCapacity<TIdentifier>(ref _identifiers, identifiersCount);
				Array.Copy(identifiers, _identifiers, identifiersCount);
			}
		}

		protected void SyncIndexNeeded_OnReceive(TIdentifier required)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			bool flag = false;
			for (int i = 0; i < _identifiersCount; i++)
			{
				if (_identifiers[i].Equals(in required, compareIndex: false))
				{
					required.Index = _identifiers[i].Index;
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				appendIdentifier(ref required, checkExisting: true);
			}
			foreach (NetworkMessageBase netMessage in GetNetMessages())
			{
				netMessage.SendTo((NetworkDestination)1);
			}
		}
	}
	public interface ICatalogIdentifier<T, TIdentifier>
	{
		int Index { get; set; }

		bool IsValid { get; }

		bool Matches(T value);

		bool Equals(in TIdentifier other, bool compareIndex);

		T CreateInstance();
	}
}
namespace RoR2Randomizer.RandomizerControllers
{
	public abstract class BaseRandomizerController : MonoBehaviour, INetMessageProvider
	{
		public readonly RunSpecific<Xoroshiro128Plus> RNG = new RunSpecific<Xoroshiro128Plus>(delegate(out Xoroshiro128Plus result)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (RNGManager.RandomizerServerRNG.HasValue)
			{
				result = new Xoroshiro128Plus(RNGManager.RandomizerServerRNG.Value.Next());
				return true;
			}
			result = null;
			return false;
		}, 9);

		public abstract bool IsRandomizerEnabled { get; }

		protected abstract bool isNetworked { get; }

		bool INetMessageProvider.SendMessages => IsRandomizerEnabled;

		protected virtual void Awake()
		{
			if (isNetworked)
			{
				NetworkingManager.RegisterMessageProvider(this, MessageProviderFlags.Persistent);
			}
		}

		protected virtual void OnDestroy()
		{
			if (isNetworked)
			{
				NetworkingManager.UnregisterMessageProvider(this);
			}
			RNG.Dispose();
		}

		IEnumerable<NetworkMessageBase> INetMessageProvider.GetNetMessages()
		{
			return getNetMessages();
		}

		protected virtual IEnumerable<NetworkMessageBase> getNetMessages()
		{
			yield break;
		}
	}
	public abstract class CharacterReplacementInfo : MonoBehaviour, INetMessageProvider
	{
		protected enum SetSubtitleMode : byte
		{
			DontOverride,
			OnlyIfExistingIsNull,
			DontOverrideIfBothNotNull,
			AlwaysOverride
		}

		private bool _initializeOnEnable;

		protected CharacterMaster _master;

		protected CharacterBody _body;

		private CharacterMaster _masterPrefab;

		protected virtual CharacterMaster originalMasterPrefab => _masterPrefab;

		protected CharacterBody originalBodyPrefab
		{
			get
			{
				CharacterMaster val = originalMasterPrefab;
				CharacterBody result = default(CharacterBody);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.bodyPrefab) && val.bodyPrefab.TryGetComponent<CharacterBody>(ref result))
				{
					return result;
				}
				return null;
			}
		}

		protected abstract bool isNetworked { get; }

		bool INetMessageProvider.SendMessages => isNetworked;

		protected virtual SetSubtitleMode subtitleOverrideMode => SetSubtitleMode.DontOverride;

		public void SetOriginalMasterIndex(MasterIndex index)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			GameObject masterPrefab = MasterCatalog.GetMasterPrefab(index);
			_masterPrefab = ((masterPrefab != null) ? masterPrefab.GetComponent<CharacterMaster>() : null);
		}

		private void Awake()
		{
			_master = ((Component)this).GetComponent<CharacterMaster>();
			if (isNetworked)
			{
				NetworkingManager.RegisterMessageProvider(this);
			}
		}

		private void OnDestroy()
		{
			if (isNetworked)
			{
				NetworkingManager.UnregisterMessageProvider(this);
			}
		}

		private void Start()
		{
			if (_initializeOnEnable)
			{
				_initializeOnEnable = false;
				Initialize();
			}
		}

		public void Initialize()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				((MonoBehaviour)this).StartCoroutine(waitForBodyInitialized());
				if (NetworkServer.active)
				{
					initializeServer();
				}
				initializeClient();
			}
			else
			{
				_initializeOnEnable = true;
			}
		}

		private IEnumerator waitForBodyInitialized()
		{
			if (!Object.op_Implicit((Object)(object)_body))
			{
				_body = _master.GetBody();
				if (!Object.op_Implicit((Object)(object)_body))
				{
					while (Object.op_Implicit((Object)(object)_master) && !_master.hasBody)
					{
						yield return 0;
					}
					if (!Object.op_Implicit((Object)(object)_master))
					{
						yield break;
					}
					_body = _master.GetBody();
				}
			}
			if (Object.op_Implicit((Object)(object)_body))
			{
				bodyResolved();
			}
		}

		protected virtual void bodyResolved()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			Inventory inventory = _master.inventory;
			if (Object.op_Implicit((Object)(object)inventory))
			{
				giveAdaptiveArmorFromOriginalMaster(inventory);
				GivePickupsOnStart component = ((Component)_master).GetComponent<GivePickupsOnStart>();
				if (_body.bodyIndex == BodyCatalog.FindBodyIndex("EquipmentDroneBody"))
				{
					giveDroneEquipment(inventory, component);
				}
				else if (_body.bodyIndex == BodyCatalog.FindBodyIndex("DroneCommanderBody"))
				{
					DroneWeaponsBehavior.SetNumDroneParts(inventory, 1);
				}
			}
			tryOverrideBodySubtitle();
		}

		private void giveDroneEquipment(Inventory inventory, GivePickupsOnStart droneGivePickupsOnStart)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((!Object.op_Implicit((Object)(object)droneGivePickupsOnStart) || !droneGivePickupsOnStart.HasAnyEquipment()) && (int)inventory.GetEquipmentIndex() == -1)
			{
				EquipmentIndex randomOrDefault = ((IEnumerable<EquipmentIndex>)(object)CharacterReplacements.AvailableDroneEquipments).GetRandomOrDefault(RoR2Application.rng, (EquipmentIndex)(-1));
				inventory.SetEquipmentIndex(randomOrDefault);
			}
		}

		private void giveAdaptiveArmorFromOriginalMaster(Inventory inventory)
		{
			//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_002a: 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)
			CharacterMaster val = originalMasterPrefab;
			if (Object.op_Implicit((Object)(object)val))
			{
				GivePickupsOnStart component = ((Component)val).GetComponent<GivePickupsOnStart>();
				ItemIndex itemIndex = Items.AdaptiveArmor.itemIndex;
				if (Object.op_Implicit((Object)(object)component) && component.HasItems(itemIndex, out var count))
				{
					inventory.GiveItemPermanent(itemIndex, count);
				}
			}
		}

		protected virtual void initializeClient()
		{
			syncDontDestroyOnLoadStatusWithOriginal();
		}

		private void syncDontDestroyOnLoadStatusWithOriginal()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_master) || Object.op_Implicit((Object)(object)((Component)_master).GetComponent<PlayerCharacterMasterController>()))
			{
				return;
			}
			CharacterMaster val = originalMasterPrefab;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			SetDontDestroyOnLoad val2 = default(SetDontDestroyOnLoad);
			if (Object.op_Implicit((Object)(object)((Component)val).GetComponent<SetDontDestroyOnLoad>()))
			{
				((Component)_master).gameObject.GetOrAddComponent<SetDontDestroyOnLoad>();
			}
			else if (((Component)_master).TryGetComponent<SetDontDestroyOnLoad>(ref val2))
			{
				Object.Destroy((Object)(object)val2);
				if (Util.IsDontDestroyOnLoad(((Component)_master).gameObject))
				{
					SceneManager.MoveGameObjectToScene(((Component)_master).gameObject, SceneManager.GetActiveScene());
				}
			}
		}

		protected virtual void initializeServer()
		{
			if (!isNetworked || NetworkServer.dontListen)
			{
				return;
			}
			foreach (NetworkMessageBase netMessage in getNetMessages())
			{
				netMessage.SendTo((NetworkDestination)1);
			}
		}

		protected virtual IEnumerable<NetworkMessageBase> getNetMessages()
		{
			yield break;
		}

		IEnumerable<NetworkMessageBase> INetMessageProvider.GetNetMessages()
		{
			return getNetMessages();
		}

		private void tryOverrideBodySubtitle()
		{
			if (!Object.op_Implicit((Object)(object)_body))
			{
				return;
			}
			CharacterBody val = originalBodyPrefab;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			string subtitleNameToken = val.subtitleNameToken;
			if (string.Equals(_body.subtitleNameToken, subtitleNameToken))
			{
				return;
			}
			switch (subtitleOverrideMode)
			{
			case SetSubtitleMode.DontOverride:
				return;
			case SetSubtitleMode.OnlyIfExistingIsNull:
				if (!string.IsNullOrEmpty(_body.subtitleNameToken))
				{
					return;
				}
				break;
			case SetSubtitleMode.DontOverrideIfBothNotNull:
				if (!string.IsNullOrEmpty(_body.subtitleNameToken) && !string.IsNullOrEmpty(subtitleNameToken))
				{
					return;
				}
				break;
			}
			_body.subtitleNameToken = subtitleNameToken;
			if (Object.op_Implicit((Object)(object)_master) && _master.isBoss)
			{
				forceRefreshBossGroupSubtitle();
			}
		}

		private void forceRefreshBossGroupSubtitle()
		{
			foreach (BossGroup instances in InstanceTracker.GetInstancesList<BossGroup>())
			{
				for (int i = 0; i < instances.bossMemoryCount; i++)
				{
					if ((Object)(object)instances.bossMemories[i].cachedMaster == (Object)(object)_master)
					{
						instances.bestObservedName = string.Empty;
						instances.bestObservedSubtitle = string.Empty;
						return;
					}
				}
			}
		}
	}
	public enum CharacterReplacementMode
	{
		None = -1,
		Random,
		Gup
	}
	public class CharacterReplacements : INetMessageProvider
	{
		public delegate void OnDirectorSpawnReplacedCallback(GameObject result, MasterIndex originalMasterIndex);

		private static CharacterReplacements _instance;

		public static ReadOnlyArray<EquipmentIndex> AvailableDroneEquipments;

		private static int[] _masterIndicesToRandomize;

		private static bool _hasInvokedReplacementsInitialized = false;

		private static ulong _invokeReplacementsInitializedRunCallbackHandle;

		private static readonly RunSpecific<Xoroshiro128Plus> _rng = new RunSpecific<Xoroshiro128Plus>(delegate(out Xoroshiro128Plus result)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (RNGManager.RandomizerServerRNG.HasValue)
			{
				result = new Xoroshiro128Plus(RNGManager.RandomizerServerRNG.Value.Next());
				return true;
			}
			result = null;
			return false;
		}, 9);

		private static readonly RunSpecific<bool> _hasReceivedMasterIndexReplacementsFromServer = new RunSpecific<bool>(1, defaultValue: false);

		private static readonly RunSpecific<IndexReplacementsCollection> _masterIndexReplacements = new RunSpecific<IndexReplacementsCollection>(delegate(out IndexReplacementsCollection result)
		{
			if (NetworkServer.active && _replacementMode.Value == CharacterReplacementMode.Random)
			{
				IEnumerable<int> collection = _masterIndicesToRandomize.Where((int i) => !ConfigManager.ExplicitSpawnRandomizer.IsBlacklisted((MasterIndex)i));
				result = new IndexReplacementsCollection(ReplacementDictionary<int>.CreateFrom(collection, _rng, delegate(int key, int value)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					MasterIndex heretic = Caches.Masters.Heretic;
					CharacterMaster val = default(CharacterMaster);
					CharacterBody val2 = default(CharacterBody);
					return (!((MasterIndex)(ref heretic)).isValid || key != Caches.Masters.Heretic.i || !MasterCatalog.GetMasterPrefab((MasterIndex)value).TryGetComponent<CharacterMaster>(ref val) || !Object.op_Implicit((Object)(object)val.bodyPrefab) || !val.bodyPrefab.TryGetComponent<CharacterBody>(ref val2) || !(val2.baseMoveSpeed <= 0f)) ? true : false;
				}), MasterCatalog.masterPrefabs.Length);
				return true;
			}
			result = default(IndexReplacementsCollection);
			return false;
		}, 1);

		private static readonly RunSpecific<CharacterReplacementMode> _replacementMode = new RunSpecific<CharacterReplacementMode>(delegate(out CharacterReplacementMode result)
		{
			if (NetworkServer.active)
			{
				if (ConfigManager.Fun.GupModeActive)
				{
					result = CharacterReplacementMode.Gup;
				}
				else
				{
					result = CharacterReplacementMode.Random;
				}
				return true;
			}
			result = CharacterReplacementMode.None;
			return false;
		}, 2, CharacterReplacementMode.None);

		public static bool IsEnabled
		{
			get
			{
				if (!NetworkServer.active)
				{
					if (NetworkClient.active)
					{
						if (!_hasReceivedMasterIndexReplacementsFromServer)
						{
							return _replacementMode.HasValue;
						}
						return true;
					}
					return false;
				}
				return true;
			}
		}

		public static bool IsAnyForcedCharacterModeEnabled
		{
			get
			{
				if (_replacementMode.HasValue)
				{
					return _replacementMode.Value >= CharacterReplacementMode.Gup;
				}
				return false;
			}
		}

		public bool SendMessages
		{
			get
			{
				if (!_masterIndexReplacements.HasValue)
				{
					return IsAnyForcedCharacterModeEnabled;
				}
				return true;
			}
		}

		public static event Action OnCharacterReplacementsInitialized;

		public static bool ShouldRandomizeMaster(CharacterMaster masterPrefab)
		{
			if (!Object.op_Implicit((Object)(object)masterPrefab))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)masterPrefab.bodyPrefab))
			{
				return false;
			}
			CharacterBody val = default(CharacterBody);
			if (!masterPrefab.bodyPrefab.TryGetComponent<CharacterBody>(ref val))
			{
				return false;
			}
			ModelLocator val2 = default(ModelLocator);
			Transform modelTransform;
			if (!((Component)val).TryGetComponent<ModelLocator>(ref val2) || !Object.op_Implicit((Object)(object)(modelTransform = val2.modelTransform)))
			{
				return false;
			}
			if (modelTransform.childCount == 0)
			{
				return false;
			}
			switch (((Object)masterPrefab).name)
			{
			case "AncientWispMaster":
			case "SolusVendorMaster":
			case "ArtifactShellMaster":
			case "ClaymanMaster":
			case "EngiBeamTurretMaster":
			case "MinorConstructAttachableMaster":
			case "VoidRaidCrabJointMaster":
			case "SolusHeartMaster":
			case "SolusHeartMaster_Offering":
			case "ExhaustPortWeakpointMaster":
			case "VoidRaidCrabMaster":
				return false;
			default:
				return true;
			}
		}

		[SystemInitializer(new Type[]
		{
			typeof(EquipmentCatalog),
			typeof(MasterCatalog)
		})]
		private static void Init()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			AvailableDroneEquipments = ReadOnlyArray<EquipmentIndex>.op_Implicit((from e in EquipmentCatalog.equipmentDefs
				where Object.op_Implicit((Object)(object)e) && (e.canDrop || Object.op_Implicit((Object)(object)e.passiveBuffDef) || (Object)(object)e == (Object)(object)Equipment.QuestVolatileBattery || (Object)(object)e == (Object)(object)Equipment.BossHunterConsumed || (Object)(object)e == (Object)(object)Equipment.LunarPortalOnUse) && (Object)(object)e != (Object)(object)Equipment.EliteVoidEquipment
				select e.equipmentIndex into ei
				orderby ei
				select ei).ToArray());
			_masterIndicesToRandomize = (from go in MasterCatalog.masterPrefabs.Where(delegate(GameObject master)
				{
					if (!Object.op_Implicit((Object)(object)master))
					{
						return false;
					}
					CharacterMaster masterPrefab = default(CharacterMaster);
					return master.TryGetComponent<CharacterMaster>(ref masterPrefab) && ShouldRandomizeMaster(masterPrefab);
				}).Distinct()
				select (int)MasterCatalog.FindMasterIndex(go)).ToArray();
			_instance = new CharacterReplacements();
			NetworkingManager.RegisterMessageProvider(_instance, MessageProviderFlags.Persistent);
			SyncCharacterMasterReplacements.OnReceive += onMasterReplacementsReceivedFromServer;
			SyncCharacterMasterReplacementMode.OnReceive += onMasterReplacementModeReceivedFromServer;
			_invokeReplacementsInitializedRunCallbackHandle = RunSpecificCallbacksManager.AddEntry((Action<Run>)delegate
			{
				if (IsEnabled)
				{
					tryInvokeCharacterReplacementsInitialized();
	

UnityModdingUtility.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("UnityModdingUtility")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UnityModdingUtility")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("29730596-8e56-4e1f-ab50-97c3413645fe")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UnityModdingUtility
{
	public enum AsyncOperationState : byte
	{
		NotStarted,
		InProgress,
		Complete
	}
	public class HandledList<T> : IEnumerable<T>, IEnumerable
	{
		private struct Slot
		{
			public T Value;

			public bool Occupied;

			public void Set(T value)
			{
				Value = value;
				Occupied = true;
			}

			public void Clear()
			{
				Value = default(T);
				Occupied = false;
			}
		}

		private readonly int _increment;

		private Slot[] _slots;

		public HandledList(int initialSize, int increment)
		{
			_slots = new Slot[initialSize];
			_increment = increment;
		}

		private void expand()
		{
			Array.Resize(ref _slots, _slots.Length + _increment);
		}

		public int Store(T value)
		{
			for (int i = 0; i < _slots.Length; i++)
			{
				ref Slot reference = ref _slots[i];
				if (!reference.Occupied)
				{
					reference.Set(value);
					return i;
				}
			}
			int num = _slots.Length;
			expand();
			_slots[num].Set(value);
			return num;
		}

		public void Clear(int slotID)
		{
			if (slotID < 0 || slotID >= _slots.Length)
			{
				throw new ArgumentOutOfRangeException("slotID");
			}
			_slots[slotID].Clear();
		}

		public IEnumerator<T> GetEnumerator()
		{
			Slot[] slots = _slots;
			for (int i = 0; i < slots.Length; i++)
			{
				Slot slot = slots[i];
				if (slot.Occupied)
				{
					yield return slot.Value;
				}
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public class CoroutineOut<T>
	{
		public T Result;
	}
	public class InitializeAsync<T>
	{
		private readonly IUnityCallbackProvider _callbackProvider;

		private readonly Func<CoroutineOut<T>, IEnumerator> _coroutineFunc;

		private CoroutineOut<T> _taskResult;

		private IEnumerator _coroutine;

		private int _updateCallbackIndex = -1;

		private T _result;

		public AsyncOperationState State { get; private set; }

		public T Get
		{
			get
			{
				if (State != AsyncOperationState.Complete)
				{
					if (State == AsyncOperationState.NotStarted)
					{
						StartAsyncOperation();
					}
					step(forceCompleteThisFrame: true);
				}
				return _result;
			}
		}

		public InitializeAsync(IUnityCallbackProvider callbackProvider, Func<CoroutineOut<T>, IEnumerator> coroutineFunc)
		{
			_callbackProvider = callbackProvider;
			_coroutineFunc = coroutineFunc;
			State = AsyncOperationState.NotStarted;
		}

		public void StartAsyncOperation()
		{
			_taskResult = new CoroutineOut<T>();
			_coroutine = _coroutineFunc(_taskResult);
			_updateCallbackIndex = _callbackProvider.RegisterUpdateCallback(update);
			State = AsyncOperationState.InProgress;
		}

		private void update()
		{
			if (State == AsyncOperationState.InProgress)
			{
				step(forceCompleteThisFrame: false);
			}
		}

		private void step(bool forceCompleteThisFrame)
		{
			if (forceCompleteThisFrame)
			{
				while (_coroutine.MoveNext())
				{
				}
			}
			if (forceCompleteThisFrame || !_coroutine.MoveNext())
			{
				State = AsyncOperationState.Complete;
				if (_updateCallbackIndex != -1)
				{
					_callbackProvider.UnregisterUpdateCallback(_updateCallbackIndex);
				}
				_result = _taskResult.Result;
			}
		}
	}
	public class InitializeOnAccess<T>
	{
		private readonly Func<T> _initializeFunc;

		private T _value;

		public bool IsInitialized { get; private set; }

		public T Get
		{
			get
			{
				if (!IsInitialized)
				{
					_value = _initializeFunc();
					IsInitialized = true;
				}
				return _value;
			}
		}

		public InitializeOnAccess(Func<T> initializeFunc)
		{
			_initializeFunc = initializeFunc;
			IsInitialized = false;
		}

		public void Reset()
		{
			IsInitialized = false;
			_value = default(T);
		}

		public void SetValue(T value)
		{
			_value = value;
			IsInitialized = true;
		}

		public static implicit operator T(InitializeOnAccess<T> initOnAccess)
		{
			return initOnAccess.Get;
		}
	}
	public class InitializeOnAccessDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, ICollection
	{
		public delegate bool ValueSelectorTryGet(TKey key, out TValue value);

		protected Dictionary<TKey, TValue> _internalDict;

		private readonly ValueSelectorTryGet _valueSelector;

		protected object _syncRoot;

		public virtual TValue this[TKey key]
		{
			get
			{
				if (TryGetValue(key, out var value))
				{
					return value;
				}
				throw new KeyNotFoundException($"Key {key} is not in the dictionary and no value was decided");
			}
			set
			{
				_internalDict[key] = value;
			}
		}

		public ICollection<TKey> Keys => _internalDict.Keys;

		public ICollection<TValue> Values => _internalDict.Values;

		public int Count => _internalDict.Count;

		public bool IsReadOnly => false;

		ICollection IDictionary.Keys => _internalDict.Keys;

		ICollection IDictionary.Values => _internalDict.Values;

		public bool IsFixedSize => false;

		public object SyncRoot
		{
			get
			{
				if (_syncRoot == null)
				{
					Interlocked.CompareExchange<object>(ref _syncRoot, new object(), (object)null);
				}
				return _syncRoot;
			}
		}

		public bool IsSynchronized => false;

		public object this[object key]
		{
			get
			{
				return this[(TKey)key];
			}
			set
			{
				this[(TKey)key] = (TValue)value;
			}
		}

		protected InitializeOnAccessDictionary()
		{
			_internalDict = new Dictionary<TKey, TValue>();
		}

		public InitializeOnAccessDictionary(ValueSelectorTryGet selector)
			: this()
		{
			_valueSelector = selector;
		}

		public InitializeOnAccessDictionary(Func<TKey, TValue> selector)
			: this((ValueSelectorTryGet)delegate(TKey key, out TValue value)
			{
				value = selector(key);
				return true;
			})
		{
		}

		public InitializeOnAccessDictionary(Func<TValue> selector)
			: this((ValueSelectorTryGet)delegate(TKey key, out TValue value)
			{
				value = selector();
				return true;
			})
		{
		}

		public void Add(TKey key, TValue value)
		{
			_internalDict.Add(key, value);
		}

		public void Clear()
		{
			_internalDict.Clear();
		}

		public bool ContainsKey(TKey key)
		{
			return _internalDict.ContainsKey(key);
		}

		public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
		{
			return _internalDict.GetEnumerator();
		}

		public bool Remove(TKey key)
		{
			return _internalDict.Remove(key);
		}

		public virtual bool TryGetValue(TKey key, out TValue value)
		{
			if (_internalDict.TryGetValue(key, out value))
			{
				return true;
			}
			if (_valueSelector(key, out value))
			{
				_internalDict.Add(key, value);
				return true;
			}
			return false;
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
		{
			throw new NotImplementedException();
		}

		bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
		{
			throw new NotImplementedException();
		}

		bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
		{
			throw new NotImplementedException();
		}

		void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
		{
			throw new NotImplementedException();
		}

		public bool Contains(object key)
		{
			if (key is TKey key2)
			{
				return ContainsKey(key2);
			}
			return false;
		}

		public void Add(object key, object value)
		{
			Add((TKey)key, (TValue)value);
		}

		IDictionaryEnumerator IDictionary.GetEnumerator()
		{
			return _internalDict.GetEnumerator();
		}

		public void Remove(object key)
		{
			Remove((TKey)key);
		}

		void ICollection.CopyTo(Array array, int index)
		{
			throw new NotImplementedException();
		}

		public void SetTo(IDictionary<TKey, TValue> dict)
		{
			_internalDict = new Dictionary<TKey, TValue>(dict);
		}

		public static implicit operator Dictionary<TKey, TValue>(InitializeOnAccessDictionary<TKey, TValue> initOnAccessDictionary)
		{
			return initOnAccessDictionary._internalDict;
		}
	}
	public class InitializeOnAccessDictionaryArg<TKey, TValue, TArg> : InitializeOnAccessDictionary<TKey, TValue>
	{
		public delegate bool ValueSelectorTryGetArg(TKey key, TArg arg, out TValue value);

		private readonly ValueSelectorTryGetArg _valueSelector;

		public override TValue this[TKey key] => _internalDict[key];

		public TValue this[TKey key, TArg arg]
		{
			get
			{
				if (TryGetValue(key, arg, out var value))
				{
					return value;
				}
				throw new KeyNotFoundException($"Key {key} is not in the dictionary and no value was decided");
			}
			set
			{
				this[key] = value;
			}
		}

		private InitializeOnAccessDictionaryArg(ValueSelectorTryGet selector)
			: base(selector)
		{
			throw new NotImplementedException();
		}

		public InitializeOnAccessDictionaryArg(ValueSelectorTryGetArg selector)
		{
			_valueSelector = selector;
		}

		public InitializeOnAccessDictionaryArg(Func<TKey, TArg, TValue> selector)
			: this((ValueSelectorTryGetArg)delegate(TKey key, TArg arg, out TValue value)
			{
				value = selector(key, arg);
				return true;
			})
		{
		}

		public InitializeOnAccessDictionaryArg(Func<TArg, TValue> selector)
			: this((ValueSelectorTryGetArg)delegate(TKey key, TArg arg, out TValue value)
			{
				value = selector(arg);
				return true;
			})
		{
		}

		public override bool TryGetValue(TKey key, out TValue value)
		{
			return _internalDict.TryGetValue(key, out value);
		}

		public bool TryGetValue(TKey key, TArg arg, out TValue value)
		{
			if (TryGetValue(key, out value))
			{
				return true;
			}
			if (_valueSelector(key, arg, out value))
			{
				_internalDict.Add(key, value);
				return true;
			}
			return false;
		}

		public static implicit operator Dictionary<TKey, TValue>(InitializeOnAccessDictionaryArg<TKey, TValue, TArg> initOnAccessDictionary)
		{
			return initOnAccessDictionary._internalDict;
		}
	}
	public interface IUnityCallbackProvider
	{
		int RegisterUpdateCallback(Action update);

		void UnregisterUpdateCallback(int handle);
	}
}
namespace UnityModdingUtility.Extensions
{
	public static class UnityObjectExtensions
	{
		public static bool Exists(this Object obj)
		{
			if (Object.op_Implicit(obj))
			{
				return obj != (Object)null;
			}
			return false;
		}
	}
}