Decompiled source of PlayableBishops v0.7.52

plugins/PlayableBishops.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.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMOD.Studio;
using HarmonyLib;
using Lamb.UI;
using MMBiomeGeneration;
using MMRoomGeneration;
using Microsoft.CodeAnalysis;
using Rewired;
using Spine;
using Spine.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
using src.UINavigator;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PlayableBishops")]
[assembly: AssemblyDescription("Playable bishop aspects for Cult of the Lamb")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PlayableBishops")]
[assembly: ComVisible(false)]
[assembly: Guid("c641d23c-12f9-497d-b527-468e741a0d5a")]
[assembly: AssemblyFileVersion("0.7.52.0")]
[assembly: AssemblyVersion("0.7.52.0")]
[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 PlayableBishops
{
	[BepInPlugin("com.cotl.playablebishops", "PlayableBishops", "0.7.52")]
	public sealed class PlayableBishopsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.cotl.playablebishops";

		public const string PluginName = "PlayableBishops";

		public const string PluginVersion = "0.7.52";

		internal static ManualLogSource Log;

		internal static BishopAspectController Controller;

		internal static readonly BishopAspectController[] Controllers = new BishopAspectController[2];

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			PlayableBishopsConfig.Bind(((BaseUnityPlugin)this).Config);
			for (int i = 0; i < Controllers.Length; i++)
			{
				BishopAspectController bishopAspectController = ((Component)this).gameObject.AddComponent<BishopAspectController>();
				bishopAspectController.Initialize(i);
				Controllers[i] = bishopAspectController;
			}
			Controller = Controllers[0];
			_harmony = new Harmony("com.cotl.playablebishops");
			Patch(AccessTools.Method(typeof(EnemyWormBoss), "Start", (Type[])null, (Type[])null), typeof(EnemyWormBossStartPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyWormBoss), "Update", (Type[])null, (Type[])null), typeof(EnemyWormBossUpdatePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyWormBoss), "OnDie", (Type[])null, (Type[])null), typeof(EnemyWormBossOnDiePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyWormBoss), "OnDamageTriggerEnter", (Type[])null, (Type[])null), typeof(PlayableLeshyDamagePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyFrogBoss), "Start", (Type[])null, (Type[])null), typeof(EnemyFrogBossStartPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyFrogBoss), "Update", (Type[])null, (Type[])null), typeof(EnemyFrogBossUpdatePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyFrogBoss), "OnDie", (Type[])null, (Type[])null), typeof(EnemyFrogBossOnDiePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyFrogBoss), "OnDestroy", (Type[])null, (Type[])null), typeof(EnemyFrogBossOnDestroyPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyTentacleMonster), "Start", (Type[])null, (Type[])null), typeof(EnemyTentacleMonsterStartPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyTentacleMonster), "OnEnable", (Type[])null, (Type[])null), typeof(EnemyTentacleMonsterOnEnablePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyTentacleMonster), "Update", (Type[])null, (Type[])null), typeof(EnemyTentacleMonsterUpdatePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyTentacleMonster), "OnDie", (Type[])null, (Type[])null), typeof(EnemyTentacleMonsterOnDiePatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemyTentacleMonster), "OnDestroy", (Type[])null, (Type[])null), typeof(EnemyTentacleMonsterOnDestroyPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemySpiderMonster), "Awake", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterAwakePatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(EnemySpiderMonster), "Awake", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterAwakePostPatch), "Postfix");
			Patch(AccessTools.Method(typeof(EnemySpiderMonster), "Start", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterStartPatch), "Prefix");
			Patch(AccessTools.Method(typeof(EnemySpiderMonster), "OnEnable", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterOnEnablePatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(EnemySpiderMonster), "OnEnable", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterOnEnablePatch), "Postfix");
			Patch(AccessTools.Method(typeof(EnemySpiderMonster), "OnDie", (Type[])null, (Type[])null), typeof(EnemySpiderMonsterOnDiePatch), "Prefix");
			Patch(AccessTools.Method(typeof(SkeletonRenderer), "GenerateMesh", (Type[])null, (Type[])null), typeof(PlayableShamuraMeshGuardPatch), "Prefix");
			Patch(AccessTools.Method(typeof(HealthPlayer), "DealDamage", new Type[7]
			{
				typeof(float),
				typeof(GameObject),
				typeof(Vector3),
				typeof(bool),
				typeof(AttackTypes),
				typeof(bool),
				typeof(AttackFlags)
			}, (Type[])null), typeof(PlayableLeshyTunnelDamageImmunityPatch), "Prefix");
			Patch(AccessTools.Method(typeof(GrenadeBullet), "Play", new Type[8]
			{
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(Team),
				typeof(bool),
				typeof(string),
				typeof(SkeletonAnimation)
			}, (Type[])null), typeof(GrenadeBulletPlayPatch), "Prefix");
			Patch(AccessTools.Method(typeof(GrenadeBullet), "OnDamageTriggerEnter", (Type[])null, (Type[])null), typeof(GrenadeBulletDamagePatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(GrenadeBullet), "DoCollision", (Type[])null, (Type[])null), typeof(GrenadeBulletDoCollisionPatch), "Postfix");
			Patch(AccessTools.Method(typeof(FrogBossTongue), "OnTriggerEnterEvent", (Type[])null, (Type[])null), typeof(PlayableHeketTongueDamagePatch), "Prefix");
			Patch(AccessTools.Method(typeof(Explosion), "CreateExplosion", (Type[])null, (Type[])null), typeof(PlayableHeketExplosionDamagePatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetAttackButtonDown", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopBasicAttackDownPatch), "Postfix");
			Patch(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetAttackButtonHeld", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopBasicAttackHeldPatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetCurseButtonDown", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopSecondaryAttackDownPatch), "Postfix");
			Patch(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetCurseButtonHeld", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopCombatInputHeldPatch), "Prefix");
			Patch(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetCurseButtonUp", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopCombatInputUpPatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetHeavyAttackButtonDown", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopSignatureAttackDownPatch), "Postfix");
			Patch(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetHeavyAttackButtonHeld", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopCombatInputHeldPatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetDodgeButtonDown", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopDodgeDownPatch), "Postfix");
			Patch(AccessTools.Method(typeof(RewiredGameplayInputSource), "GetDodgeButtonHeld", new Type[1] { typeof(PlayerFarming) }, (Type[])null), typeof(PlayableBishopDodgeHeldPatch), "Prefix");
			PatchPostfix(AccessTools.Method(typeof(UIPlayerUpgradesMenuController), "Start", (Type[])null, (Type[])null), typeof(UIPlayerUpgradesMenuStartPatch), "Postfix");
			Log.LogInfo((object)"PlayableBishops 0.7.52 loaded with global per-instance Shamura straight-alpha rendering and restored Kallamar dodge-teleport travel.");
		}

		internal static int GetPlayerSlot(PlayerFarming player)
		{
			if ((Object)(object)player != (Object)null)
			{
				for (int i = 0; i < PlayerFarming.players.Count && i < Controllers.Length; i++)
				{
					if ((Object)(object)PlayerFarming.players[i] == (Object)(object)player)
					{
						return i;
					}
				}
				if (player.playerID >= 0 && player.playerID < Controllers.Length)
				{
					return player.playerID;
				}
			}
			return 0;
		}

		internal static BishopAspectController GetController(PlayerFarming player)
		{
			int playerSlot = GetPlayerSlot(player);
			if (playerSlot < 0 || playerSlot >= Controllers.Length)
			{
				return null;
			}
			return Controllers[playerSlot];
		}

		internal static BishopAspectController GetController(int playerSlot)
		{
			if (playerSlot < 0 || playerSlot >= Controllers.Length)
			{
				return null;
			}
			return Controllers[playerSlot];
		}

		private void Patch(MethodBase original, Type patchType, string patchName)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			if (original == null)
			{
				Log.LogError((object)("Could not find required game method for " + patchType.Name + "."));
			}
			else
			{
				_harmony.Patch(original, new HarmonyMethod(patchType, patchName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private void PatchPostfix(MethodBase original, Type patchType, string patchName)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			if (original == null)
			{
				Log.LogError((object)("Could not find required game method for " + patchType.Name + "."));
			}
			else
			{
				_harmony.Patch(original, (HarmonyMethod)null, new HarmonyMethod(patchType, patchName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private void OnDestroy()
		{
			for (int i = 0; i < Controllers.Length; i++)
			{
				if ((Object)(object)Controllers[i] != (Object)null)
				{
					Controllers[i].Shutdown();
					Controllers[i] = null;
				}
			}
			Controller = null;
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}
	}
	internal static class PlayableBishopsLog
	{
		internal static void Debug(string message)
		{
			if (PlayableBishopsConfig.DebugLogging != null && PlayableBishopsConfig.DebugLogging.Value && PlayableBishopsPlugin.Log != null)
			{
				PlayableBishopsPlugin.Log.LogInfo((object)message);
			}
		}
	}
	internal enum ControllerToggleStick
	{
		LeftStick,
		RightStick
	}
	internal static class PlayableBishopsConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AllowOutsideDungeons;

		internal static ConfigEntry<bool> AutoActivateInDungeons;

		internal static ConfigEntry<bool> CultLeaderFormsOutsideDungeons;

		internal static ConfigEntry<float> CultLeaderTransitionDuration;

		internal static ConfigEntry<float> CultLeaderLeshyScale;

		internal static ConfigEntry<float> CultLeaderHeketScale;

		internal static ConfigEntry<float> CultLeaderKallamarScale;

		internal static ConfigEntry<float> CultLeaderShamuraScale;

		internal static ConfigEntry<float> BossDamageMultiplier;

		internal static ConfigEntry<string> SelectedAspect;

		internal static ConfigEntry<string> SelectedAspectP2;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<KeyCode> SpikeKey;

		internal static ConfigEntry<KeyCode> VolleyKey;

		internal static ConfigEntry<KeyCode> RoarKey;

		internal static ConfigEntry<KeyCode> SignatureMouseButton;

		internal static ConfigEntry<KeyCode> ResetKey;

		internal static ConfigEntry<bool> ControllerToggleChord;

		internal static ConfigEntry<ControllerToggleStick> ControllerToggleStickChoice;

		internal static ConfigEntry<bool> ProjectileAimAssist;

		internal static ConfigEntry<float> ProjectileAimAssistMouseRadius;

		internal static ConfigEntry<float> ProjectileAimAssistControllerCone;

		internal static ConfigEntry<float> VisualScale;

		internal static ConfigEntry<float> SpikeCooldown;

		internal static ConfigEntry<float> SpikeBaseDamage;

		internal static ConfigEntry<float> SpikeLineReach;

		internal static ConfigEntry<float> SpikeLineHalfWidth;

		internal static ConfigEntry<float> VolleyCooldown;

		internal static ConfigEntry<float> VolleyProjectileBaseDamage;

		internal static ConfigEntry<int> VolleyShotCount;

		internal static ConfigEntry<int> VolleyFocusedShots;

		internal static ConfigEntry<float> VolleySpreadRadius;

		internal static ConfigEntry<float> RoarCooldown;

		internal static ConfigEntry<float> RoarRadius;

		internal static ConfigEntry<float> RoarDamage;

		internal static ConfigEntry<float> TunnelDamage;

		internal static ConfigEntry<float> TunnelHitCooldown;

		internal static ConfigEntry<float> HeketVisualScale;

		internal static ConfigEntry<float> HeketTongueCooldown;

		internal static ConfigEntry<float> HeketMortarCooldown;

		internal static ConfigEntry<int> HeketMortarCount;

		internal static ConfigEntry<float> HeketSlamCooldown;

		internal static ConfigEntry<float> HeketSlamRadius;

		internal static ConfigEntry<float> HeketSlamDamage;

		internal static ConfigEntry<float> HeketLocomotionHopRadius;

		internal static ConfigEntry<float> HeketLocomotionHopDamage;

		internal static ConfigEntry<float> HeketBurpCooldown;

		internal static ConfigEntry<float> HeketTongueBaseDamage;

		internal static ConfigEntry<float> HeketTongueImpactRadius;

		internal static ConfigEntry<float> HeketMortarBaseDamage;

		internal static ConfigEntry<float> HeketBurpProjectileBaseDamage;

		internal static ConfigEntry<float> KallamarVisualScale;

		internal static ConfigEntry<float> KallamarDaggerCooldown;

		internal static ConfigEntry<float> KallamarDaggerRadius;

		internal static ConfigEntry<float> KallamarDaggerDamage;

		internal static ConfigEntry<float> KallamarDaggerReach;

		internal static ConfigEntry<float> KallamarProjectileCooldown;

		internal static ConfigEntry<float> KallamarProjectileBaseDamage;

		internal static ConfigEntry<float> KallamarSwordCooldown;

		internal static ConfigEntry<float> KallamarSwordRadius;

		internal static ConfigEntry<float> KallamarSwordDamage;

		internal static ConfigEntry<float> KallamarMovementDestructionRadius;

		internal static ConfigEntry<float> KallamarTeleportCooldown;

		internal static ConfigEntry<float> KallamarTeleportDistance;

		internal static ConfigEntry<float> KallamarChargedTeleportDistance;

		internal static ConfigEntry<float> ShamuraVisualScale;

		internal static ConfigEntry<float> ShamuraSlashCooldown;

		internal static ConfigEntry<float> ShamuraSlashRadius;

		internal static ConfigEntry<float> ShamuraSlashBaseDamage;

		internal static ConfigEntry<float> ShamuraBombCooldown;

		internal static ConfigEntry<int> ShamuraBombCount;

		internal static ConfigEntry<int> ShamuraBombFocusedCount;

		internal static ConfigEntry<float> ShamuraBombSpreadRadius;

		internal static ConfigEntry<float> ShamuraBombBaseDamage;

		internal static ConfigEntry<float> ShamuraJumpCooldown;

		internal static ConfigEntry<float> ShamuraJumpRadius;

		internal static ConfigEntry<float> ShamuraJumpBaseDamage;

		internal static ConfigEntry<bool> DebugLogging;

		internal static void Bind(ConfigFile config)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Expected O, but got Unknown
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Invalid comparison between Unknown and I4
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Invalid comparison between Unknown and I4
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Invalid comparison between Unknown and I4
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Invalid comparison between Unknown and I4
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Expected O, but got Unknown
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Expected O, but got Unknown
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Expected O, but got Unknown
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Expected O, but got Unknown
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Expected O, but got Unknown
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Expected O, but got Unknown
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0637: Expected O, but got Unknown
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Expected O, but got Unknown
			//IL_068a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Expected O, but got Unknown
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Expected O, but got Unknown
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Expected O, but got Unknown
			//IL_077f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0789: Expected O, but got Unknown
			//IL_07b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c1: Expected O, but got Unknown
			//IL_07ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f9: Expected O, but got Unknown
			//IL_0827: Unknown result type (might be due to invalid IL or missing references)
			//IL_0831: Expected O, but got Unknown
			//IL_08a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b3: Expected O, but got Unknown
			//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08eb: Expected O, but got Unknown
			//IL_0919: Unknown result type (might be due to invalid IL or missing references)
			//IL_0923: Expected O, but got Unknown
			//IL_0945: Unknown result type (might be due to invalid IL or missing references)
			//IL_094f: Expected O, but got Unknown
			//IL_097d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0987: Expected O, but got Unknown
			//IL_09b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09bf: Expected O, but got Unknown
			//IL_09ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f7: Expected O, but got Unknown
			//IL_0a25: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a2f: Expected O, but got Unknown
			//IL_0a5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a67: Expected O, but got Unknown
			//IL_0a95: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a9f: Expected O, but got Unknown
			//IL_0acd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad7: Expected O, but got Unknown
			//IL_0b05: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b0f: Expected O, but got Unknown
			//IL_0b3d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b47: Expected O, but got Unknown
			//IL_0b75: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b7f: Expected O, but got Unknown
			//IL_0c1c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c26: Expected O, but got Unknown
			//IL_0c54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c5e: Expected O, but got Unknown
			//IL_0c8c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c96: Expected O, but got Unknown
			//IL_0cc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cce: Expected O, but got Unknown
			//IL_0cfc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d06: Expected O, but got Unknown
			//IL_0d34: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d3e: Expected O, but got Unknown
			//IL_0d6c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d76: Expected O, but got Unknown
			//IL_0da4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dae: Expected O, but got Unknown
			//IL_0ddc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0de6: Expected O, but got Unknown
			//IL_0e14: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e1e: Expected O, but got Unknown
			//IL_0e4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e56: Expected O, but got Unknown
			//IL_0e84: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e8e: Expected O, but got Unknown
			//IL_0ebc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ec6: Expected O, but got Unknown
			//IL_0ef4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0efe: Expected O, but got Unknown
			//IL_102f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1039: Expected O, but got Unknown
			//IL_1067: Unknown result type (might be due to invalid IL or missing references)
			//IL_1071: Expected O, but got Unknown
			//IL_109f: Unknown result type (might be due to invalid IL or missing references)
			//IL_10a9: Expected O, but got Unknown
			//IL_10d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_10e1: Expected O, but got Unknown
			//IL_110f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1119: Expected O, but got Unknown
			//IL_113d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1147: Expected O, but got Unknown
			//IL_116a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1174: Expected O, but got Unknown
			//IL_11a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_11ac: Expected O, but got Unknown
			//IL_11da: Unknown result type (might be due to invalid IL or missing references)
			//IL_11e4: Expected O, but got Unknown
			//IL_1212: Unknown result type (might be due to invalid IL or missing references)
			//IL_121c: Expected O, but got Unknown
			//IL_124a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1254: Expected O, but got Unknown
			//IL_1282: Unknown result type (might be due to invalid IL or missing references)
			//IL_128c: Expected O, but got Unknown
			Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Playable Bishops.");
			AllowOutsideDungeons = config.Bind<bool>("General", "AllowOutsideDungeons", false, "Allow the prototype aspect at the cult and other non-combat locations.");
			AutoActivateInDungeons = config.Bind<bool>("General", "AutoActivateInDungeons", true, "Automatically activate the altar-selected bishop when a dungeon player becomes available.");
			CultLeaderFormsOutsideDungeons = config.Bind<bool>("General", "CultLeaderFormsOutsideDungeons", true, "Use the selected bishop's pre-boss cult-leader rig when toggled outside a dungeon.");
			CultLeaderTransitionDuration = config.Bind<float>("General", "CultLeaderTransitionDuration", 0.35f, new ConfigDescription("Seconds used for the local warp and cult-leader crossfade.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1.5f), Array.Empty<object>()));
			SelectedAspect = config.Bind<string>("Selection", "SelectedAspect", "Leshy", "Saved bishop aspect selection from the altar row.");
			SelectedAspectP2 = config.Bind<string>("Selection", "SelectedAspectP2", "None", "Saved Player 2 bishop aspect selection from the altar row.");
			BossDamageMultiplier = config.Bind<float>("Balance", "BossDamageMultiplier", 1.35f, new ConfigDescription("Final multiplier applied after playable-bishop attacks use the game's player weapon-level, run, fleece, relic, trinket, and difficulty scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>()));
			CultLeaderLeshyScale = config.Bind<float>("Cult Leaders", "LeshyScale", 0.8f, new ConfigDescription("Scale applied to Leshy's non-dungeon cult-leader form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2.5f), Array.Empty<object>()));
			CultLeaderHeketScale = config.Bind<float>("Cult Leaders", "HeketScale", 0.8f, new ConfigDescription("Scale applied to Heket's non-dungeon cult-leader form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2.5f), Array.Empty<object>()));
			CultLeaderKallamarScale = config.Bind<float>("Cult Leaders", "KallamarScale", 0.8f, new ConfigDescription("Scale applied to Kallamar's non-dungeon cult-leader form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2.5f), Array.Empty<object>()));
			CultLeaderShamuraScale = config.Bind<float>("Cult Leaders", "ShamuraScale", 0.8f, new ConfigDescription("Scale applied to Shamura's non-dungeon cult-leader form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2.5f), Array.Empty<object>()));
			if (Mathf.Approximately(CultLeaderLeshyScale.Value, 1f))
			{
				CultLeaderLeshyScale.Value = 0.8f;
			}
			if (Mathf.Approximately(CultLeaderHeketScale.Value, 1f))
			{
				CultLeaderHeketScale.Value = 0.8f;
			}
			if (Mathf.Approximately(CultLeaderKallamarScale.Value, 1f))
			{
				CultLeaderKallamarScale.Value = 0.8f;
			}
			if (Mathf.Approximately(CultLeaderShamuraScale.Value, 1f))
			{
				CultLeaderShamuraScale.Value = 0.8f;
			}
			ToggleKey = config.Bind<KeyCode>("Controls", "ToggleAspect", (KeyCode)282, "Toggle the selected bishop aspect.");
			SpikeKey = config.Bind<KeyCode>("Controls", "PrimaryAbility", (KeyCode)283, "Use the selected bishop's primary ability.");
			VolleyKey = config.Bind<KeyCode>("Controls", "SecondaryAbility", (KeyCode)284, "Use the selected bishop's secondary ability.");
			RoarKey = config.Bind<KeyCode>("Controls", "SignatureAbility", (KeyCode)285, "Use the selected bishop's signature ability.");
			SignatureMouseButton = config.Bind<KeyCode>("Controls", "SignatureMouseButton", (KeyCode)325, "Mouse fallback for the selected bishop's signature ability. Mouse2 is the middle mouse button.");
			ResetKey = config.Bind<KeyCode>("Controls", "ResetAspect", (KeyCode)286, "Reset the playable avatar to its idle render state.");
			ControllerToggleChord = config.Bind<bool>("Controls", "ControllerToggleChord", true, "Allow each controller player to toggle their selected bishop with the configured stick-click and D-pad Up chord.");
			ControllerToggleStickChoice = config.Bind<ControllerToggleStick>("Controls", "ControllerToggleStick", ControllerToggleStick.LeftStick, "Stick click used with D-pad Up to toggle bishop form. LeftStick avoids conflicts with controller mod menus that use Right Stick Click.");
			ProjectileAimAssist = config.Bind<bool>("Controls", "ProjectileAimAssist", true, "Aim projectile attacks toward nearby active enemies.");
			ProjectileAimAssistMouseRadius = config.Bind<float>("Controls", "ProjectileAimAssistMouseRadius", 3f, new ConfigDescription("Maximum world-space distance from the mouse target at which a projectile attack snaps to an enemy.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 8f), Array.Empty<object>()));
			ProjectileAimAssistControllerCone = config.Bind<float>("Controls", "ProjectileAimAssistControllerCone", 55f, new ConfigDescription("Half-angle of the preferred controller aim-assist cone in degrees. If no enemy is inside it, controller attacks fall back to the nearest enemy in range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 90f), Array.Empty<object>()));
			if ((int)ToggleKey.Value == 289)
			{
				ToggleKey.Value = (KeyCode)282;
			}
			if ((int)SpikeKey.Value == 287)
			{
				SpikeKey.Value = (KeyCode)283;
			}
			if ((int)VolleyKey.Value == 288)
			{
				VolleyKey.Value = (KeyCode)284;
			}
			if ((int)RoarKey.Value == 290)
			{
				RoarKey.Value = (KeyCode)285;
			}
			if (Mathf.Approximately(ProjectileAimAssistControllerCone.Value, 38f))
			{
				ProjectileAimAssistControllerCone.Value = 55f;
			}
			config.Save();
			VisualScale = config.Bind<float>("Leshy", "VisualScale", 0.72f, new ConfigDescription("Scale applied to Leshy's boss form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>()));
			SpikeCooldown = config.Bind<float>("Leshy", "SpikeCooldown", 2f, new ConfigDescription("Seconds between spike attacks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
			SpikeBaseDamage = config.Bind<float>("Leshy", "SpikeBaseDamage", 1.5f, new ConfigDescription("Base damage of each Leshy spike hit before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			SpikeLineReach = config.Bind<float>("Leshy", "SpikeLineReach", 11.5f, new ConfigDescription("Reliable damage and destruction reach behind Leshy's visual spike line.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>()));
			SpikeLineHalfWidth = config.Bind<float>("Leshy", "SpikeLineHalfWidth", 1.65f, new ConfigDescription("Half-width of Leshy's spike-line damage corridor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f), Array.Empty<object>()));
			VolleyCooldown = config.Bind<float>("Leshy", "VolleyCooldown", 3f, new ConfigDescription("Seconds between projectile volleys.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 15f), Array.Empty<object>()));
			VolleyProjectileBaseDamage = config.Bind<float>("Leshy", "VolleyProjectileBaseDamage", 1.25f, new ConfigDescription("Base damage of each Leshy volley grenade before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			VolleyShotCount = config.Bind<int>("Leshy", "VolleyShotCount", 42, new ConfigDescription("Total grenades in Leshy's native fan-shaped volley.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 60), Array.Empty<object>()));
			VolleyFocusedShots = config.Bind<int>("Leshy", "VolleyFocusedShots", 28, new ConfigDescription("Randomly distributed volley shots that directly target active enemies inside the aimed sector.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 42), Array.Empty<object>()));
			VolleySpreadRadius = config.Bind<float>("Leshy", "VolleySpreadRadius", 2.25f, new ConfigDescription("Radius used by the non-focused portion of Leshy's volley.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>()));
			if (VolleyShotCount.Value == 14)
			{
				VolleyShotCount.Value = 42;
			}
			if (VolleyFocusedShots.Value == 8)
			{
				VolleyFocusedShots.Value = 10;
			}
			if (VolleyFocusedShots.Value == 10)
			{
				VolleyFocusedShots.Value = 28;
			}
			RoarCooldown = config.Bind<float>("Leshy", "RoarCooldown", 5f, new ConfigDescription("Seconds between roar bursts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			RoarRadius = config.Bind<float>("Leshy", "RoarRadius", 8f, new ConfigDescription("Damage and destruction radius of Leshy's middle-mouse roar shockwave.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 16f), Array.Empty<object>()));
			RoarDamage = config.Bind<float>("Leshy", "RoarDamage", 4f, new ConfigDescription("Base damage dealt by Leshy's middle-mouse roar shockwave before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			TunnelDamage = config.Bind<float>("Leshy", "TunnelDamage", 0.5f, new ConfigDescription("Damage dealt when Leshy's tunnel trail contacts an enemy.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			TunnelHitCooldown = config.Bind<float>("Leshy", "TunnelHitCooldown", 0.35f, new ConfigDescription("Minimum seconds before tunneling can damage the same enemy again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			if (Mathf.Approximately(RoarRadius.Value, 4.5f))
			{
				RoarRadius.Value = 8f;
			}
			if (Mathf.Approximately(RoarDamage.Value, 2f))
			{
				RoarDamage.Value = 4f;
			}
			HeketVisualScale = config.Bind<float>("Heket", "VisualScale", 0.68f, new ConfigDescription("Scale applied to Heket's boss form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>()));
			HeketTongueCooldown = config.Bind<float>("Heket", "TongueCooldown", 2f, new ConfigDescription("Seconds between cursor-targeted tongue strikes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
			HeketMortarCooldown = config.Bind<float>("Heket", "MortarCooldown", 3.5f, new ConfigDescription("Seconds between cursor-targeted mortar bursts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
			HeketMortarCount = config.Bind<int>("Heket", "MortarCount", 3, new ConfigDescription("Mortars spawned by each burst.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 7), Array.Empty<object>()));
			HeketSlamCooldown = config.Bind<float>("Heket", "SlamCooldown", 5f, new ConfigDescription("Seconds between hop shockwaves.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			HeketSlamRadius = config.Bind<float>("Heket", "SlamRadius", 15f, new ConfigDescription("Damage and destruction radius of Heket's manual dodge-hop landing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			HeketSlamDamage = config.Bind<float>("Heket", "SlamDamage", 4f, new ConfigDescription("Base damage of Heket's large Dodge-hop landing before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			HeketLocomotionHopRadius = config.Bind<float>("Heket", "LocomotionHopRadius", 2.25f, new ConfigDescription("Damage radius of Heket's normal traversal-hop landing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>()));
			HeketLocomotionHopDamage = config.Bind<float>("Heket", "LocomotionHopDamage", 0.5f, new ConfigDescription("Base damage of Heket's normal traversal-hop landing before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			HeketBurpCooldown = config.Bind<float>("Heket", "BurpCooldown", 4f, new ConfigDescription("Seconds between Heket's projectile-burp barrages.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
			HeketTongueBaseDamage = config.Bind<float>("Heket", "TongueBaseDamage", 4.25f, new ConfigDescription("Base damage of Heket's tongue impact shockwave before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			HeketTongueImpactRadius = config.Bind<float>("Heket", "TongueImpactRadius", 3.75f, new ConfigDescription("Damage and destruction radius at Heket's tongue endpoint.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 8f), Array.Empty<object>()));
			HeketMortarBaseDamage = config.Bind<float>("Heket", "MortarBaseDamage", 3f, new ConfigDescription("Base damage of each Heket mortar before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			HeketBurpProjectileBaseDamage = config.Bind<float>("Heket", "BurpProjectileBaseDamage", 1.5f, new ConfigDescription("Base damage of each Heket burp projectile before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			if (Mathf.Approximately(HeketSlamRadius.Value, 4f))
			{
				HeketSlamRadius.Value = 15f;
			}
			if (Mathf.Approximately(HeketSlamDamage.Value, 2f))
			{
				HeketSlamDamage.Value = 4f;
			}
			if (Mathf.Approximately(HeketTongueBaseDamage.Value, 3.5f))
			{
				HeketTongueBaseDamage.Value = 4.25f;
			}
			KallamarVisualScale = config.Bind<float>("Kallamar", "VisualScale", 0.68f, new ConfigDescription("Scale applied to Kallamar's boss form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>()));
			KallamarDaggerCooldown = config.Bind<float>("Kallamar", "DaggerCooldown", 0.45f, new ConfigDescription("Minimum seconds between dagger strikes. The native clip length, clamped to a short playable recovery, remains the practical repeat limit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			KallamarDaggerRadius = config.Bind<float>("Kallamar", "DaggerRadius", 2.3f, new ConfigDescription("Half-width of Kallamar's forgiving mirrored dagger-hit corridor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			KallamarDaggerDamage = config.Bind<float>("Kallamar", "DaggerDamage", 2f, new ConfigDescription("Base damage of Kallamar's dagger strike before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			KallamarDaggerReach = config.Bind<float>("Kallamar", "DaggerReach", 5.5f, new ConfigDescription("Reach on each side of Kallamar's mirrored dagger hit area.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			KallamarProjectileCooldown = config.Bind<float>("Kallamar", "ProjectileCooldown", 3.5f, new ConfigDescription("Seconds between aimed projectile circles.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
			KallamarProjectileBaseDamage = config.Bind<float>("Kallamar", "ProjectileBaseDamage", 1.25f, new ConfigDescription("Base damage of each Kallamar circle projectile before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			KallamarSwordCooldown = config.Bind<float>("Kallamar", "SwordCooldown", 5f, new ConfigDescription("Seconds between charged sword cleaves.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			KallamarSwordRadius = config.Bind<float>("Kallamar", "SwordRadius", 4f, new ConfigDescription("360-degree damage and destruction radius of Kallamar's middle-mouse sword swipe.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>()));
			KallamarSwordDamage = config.Bind<float>("Kallamar", "SwordDamage", 2.5f, new ConfigDescription("Damage dealt by Kallamar's sword cleave.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			KallamarMovementDestructionRadius = config.Bind<float>("Kallamar", "MovementDestructionRadius", 1.65f, new ConfigDescription("Radius in which moving Kallamar crushes rubble and destructible props.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f), Array.Empty<object>()));
			KallamarTeleportCooldown = config.Bind<float>("Kallamar", "TeleportCooldown", 0.3f, new ConfigDescription("Recovery between Kallamar dodge-teleports; 0.3 seconds matches the vanilla Lamb dodge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f), Array.Empty<object>()));
			KallamarTeleportDistance = config.Bind<float>("Kallamar", "TeleportDistance", 6f, new ConfigDescription("Directional travel distance of a tapped Kallamar dodge-teleport.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 12f), Array.Empty<object>()));
			KallamarChargedTeleportDistance = config.Bind<float>("Kallamar", "ChargedTeleportDistance", 7.5f, new ConfigDescription("Maximum room-safe travel distance reached by holding Kallamar's dodge through the vanish animation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>()));
			if (Mathf.Approximately(KallamarTeleportCooldown.Value, 2.5f))
			{
				KallamarTeleportCooldown.Value = 0.3f;
			}
			if (Mathf.Approximately(KallamarDaggerCooldown.Value, 1.4f))
			{
				KallamarDaggerCooldown.Value = 0.2f;
			}
			if (Mathf.Approximately(KallamarDaggerCooldown.Value, 0.2f))
			{
				KallamarDaggerCooldown.Value = 0.45f;
			}
			if (Mathf.Approximately(KallamarDaggerDamage.Value, 1.25f))
			{
				KallamarDaggerDamage.Value = 2f;
			}
			if (Mathf.Approximately(KallamarDaggerRadius.Value, 1.7f))
			{
				KallamarDaggerRadius.Value = 2.3f;
			}
			if (Mathf.Approximately(KallamarDaggerReach.Value, 4.5f))
			{
				KallamarDaggerReach.Value = 5.5f;
			}
			if (Mathf.Approximately(KallamarSwordRadius.Value, 3f))
			{
				KallamarSwordRadius.Value = 4f;
			}
			ShamuraVisualScale = config.Bind<float>("Shamura", "VisualScale", 0.68f, new ConfigDescription("Scale applied to Shamura's boss form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>()));
			ShamuraSlashCooldown = config.Bind<float>("Shamura", "SlashCooldown", 1.25f, new ConfigDescription("Seconds between Shamura's local melee slashes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 10f), Array.Empty<object>()));
			ShamuraSlashRadius = config.Bind<float>("Shamura", "SlashRadius", 3.8f, new ConfigDescription("Damage and destruction radius around Shamura during the melee slash.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 7f), Array.Empty<object>()));
			ShamuraSlashBaseDamage = config.Bind<float>("Shamura", "SlashBaseDamage", 2.25f, new ConfigDescription("Base damage of Shamura's melee slash before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			ShamuraBombCooldown = config.Bind<float>("Shamura", "BombCooldown", 3.8f, new ConfigDescription("Seconds between Shamura's aimed grenade spreads.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
			ShamuraBombCount = config.Bind<int>("Shamura", "BombCount", 28, new ConfigDescription("Grenades launched by Shamura's aimed spread.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 40), Array.Empty<object>()));
			ShamuraBombFocusedCount = config.Bind<int>("Shamura", "BombFocusedCount", 8, new ConfigDescription("Grenades in each Shamura spread that directly target active enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 24), Array.Empty<object>()));
			ShamuraBombSpreadRadius = config.Bind<float>("Shamura", "BombSpreadRadius", 3.2f, new ConfigDescription("Radius used by Shamura's collateral grenade landings around the aimed point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 7f), Array.Empty<object>()));
			ShamuraBombBaseDamage = config.Bind<float>("Shamura", "BombBaseDamage", 1.1f, new ConfigDescription("Base damage of each Shamura grenade before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			ShamuraJumpCooldown = config.Bind<float>("Shamura", "JumpCooldown", 5.5f, new ConfigDescription("Seconds between Shamura's three-impact jump barrage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			ShamuraJumpRadius = config.Bind<float>("Shamura", "JumpRadius", 3.4f, new ConfigDescription("Local damage and destruction radius of each Shamura jump landing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 8f), Array.Empty<object>()));
			ShamuraJumpBaseDamage = config.Bind<float>("Shamura", "JumpBaseDamage", 2f, new ConfigDescription("Base damage of each Shamura jump landing before game combat scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			if (Mathf.Approximately(ShamuraSlashRadius.Value, 1.8f))
			{
				ShamuraSlashRadius.Value = 3.8f;
			}
			if (Mathf.Approximately(ShamuraJumpRadius.Value, 2.35f))
			{
				ShamuraJumpRadius.Value = 3.4f;
			}
			if (ShamuraBombCount.Value == 7)
			{
				ShamuraBombCount.Value = 28;
			}
			if (ShamuraBombFocusedCount.Value == 3)
			{
				ShamuraBombFocusedCount.Value = 8;
			}
			DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, "Write verbose aspect lifecycle messages to the BepInEx log.");
			config.Save();
		}

		internal static string GetSelectedAspect(int playerSlot)
		{
			if (playerSlot != 1 || SelectedAspectP2 == null)
			{
				return SelectedAspect.Value;
			}
			return SelectedAspectP2.Value;
		}

		internal static void SetSelectedAspect(int playerSlot, string aspectId)
		{
			if (playerSlot == 1 && SelectedAspectP2 != null)
			{
				SelectedAspectP2.Value = aspectId;
			}
			else
			{
				SelectedAspect.Value = aspectId;
			}
		}
	}
	internal static class BishopAspectIds
	{
		internal const int LeshyFleece = 20001;

		internal const int HeketFleece = 20002;

		internal const int KallamarFleece = 20003;

		internal const int ShamuraFleece = 20004;

		internal const int NarinderFleece = 20005;
	}
	internal sealed class BishopAspectController : MonoBehaviour
	{
		private sealed class PlayerRendererState
		{
			internal Renderer Renderer;

			internal bool ForceRenderingOff;
		}

		private const int AttackActionId = 2;

		private const int CurseActionId = 13;

		private const int DodgeActionId = 16;

		private const int HeavyAttackActionId = 94;

		private readonly LeshyAspect _leshy = new LeshyAspect();

		private readonly HeketAspect _heket = new HeketAspect();

		private readonly KallamarAspect _kallamar = new KallamarAspect();

		private readonly ShamuraAspect _shamura = new ShamuraAspect();

		private readonly CultLeaderPuppet _cultLeader = new CultLeaderPuppet();

		private readonly List<PlayerRendererState> _playerRendererStates = new List<PlayerRendererState>();

		private BishopAspect _activeAspect;

		private PlayerFarming _player;

		private bool _activationPending;

		private int _lastCapturedAttackFrame = -1;

		private int _lastCapturedSecondaryFrame = -1;

		private int _lastCapturedSignatureFrame = -1;

		private int _lastCapturedDodgeFrame = -1;

		private bool _autoActivationBlockedUntilDungeonExit;

		private float _nextAutoActivationTime;

		private bool _deathPresentationInProgress;

		private bool _lifecycleTransitionInProgress;

		private bool _deactivationPending;

		private bool _leaderActivationPending;

		private bool _leaderDeactivationPending;

		private bool _leaderDesiredOutside;

		private bool _leaderRestorePending;

		private bool _leaderToBossPending;

		private bool _formTransitionInProgress;

		private bool _locationModeInitialized;

		private bool _wasInDungeon;

		private bool _transformedThisDungeon;

		private int _playerSlot;

		internal bool IsActive
		{
			get
			{
				if (_activeAspect != null)
				{
					return _activeAspect.IsActive;
				}
				return false;
			}
		}

		internal bool IsCultLeaderActive => _cultLeader.IsActive;

		internal PlayerFarming CurrentPlayer => _player;

		internal int PlayerSlot => _playerSlot;

		private string PlayerLabel => "P" + (_playerSlot + 1);

		internal bool ProtectsWithLeshyTunnel(Health health)
		{
			if ((Object)(object)health != (Object)null && (Object)(object)_player != (Object)null && (Object)(object)_player.health == (Object)(object)health && _activeAspect == _leshy)
			{
				return _leshy.IsTunneling;
			}
			return false;
		}

		internal void Initialize(int playerSlot)
		{
			_playerSlot = Mathf.Clamp(playerSlot, 0, 1);
		}

		private void Update()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			if (!PlayableBishopsConfig.Enabled.Value)
			{
				if (IsActive)
				{
					Deactivate();
				}
				if (IsCultLeaderActive || _leaderActivationPending || _leaderDeactivationPending || _formTransitionInProgress)
				{
					_leaderDesiredOutside = false;
					DeactivateCultLeaderImmediate(restorePlayer: true);
				}
				return;
			}
			UpdateLocationMode();
			UpdateAutomaticActivation();
			PlayerFarming player = (((Object)(object)_player != (Object)null) ? _player : GetSlotPlayer());
			if ((_playerSlot == 0 && Input.GetKeyDown(PlayableBishopsConfig.ToggleKey.Value)) || IsControllerTogglePressed(player))
			{
				Toggle();
			}
			if (!IsActive)
			{
				if (IsCultLeaderActive && !IsPlayerUsable(_player))
				{
					PlayableBishopsPlugin.Log.LogWarning((object)("Automatically hiding the cult-leader form because its player became unavailable: " + DescribePlayer(_player)));
					DeactivateCultLeaderImmediate(restorePlayer: true);
					_leaderRestorePending = _leaderDesiredOutside && !GameManager.IsDungeon(PlayerFarming.Location);
				}
			}
			else if (!IsPlayerUsable(_player))
			{
				if ((Object)(object)_player != (Object)null && (Object)(object)_player.health != (Object)null && ((Health)_player.health).HP <= 0f)
				{
					BeginDeathPresentation();
					return;
				}
				PlayableBishopsPlugin.Log.LogWarning((object)("Automatically disabling " + _activeAspect.DisplayName + " because the player became unusable: " + DescribePlayer(_player)));
				Deactivate();
			}
			else if (!_activeAspect.IsValid)
			{
				PlayableBishopsPlugin.Log.LogWarning((object)("Automatically disabling " + _activeAspect.DisplayName + " because the retained boss puppet became invalid."));
				DeactivateImmediate();
			}
			else if (!_activationPending && !_lifecycleTransitionInProgress && !_deathPresentationInProgress)
			{
				if (_playerSlot == 0 && Input.GetKeyDown(PlayableBishopsConfig.SpikeKey.Value))
				{
					_activeAspect.TryPrimary(_player);
				}
				if (_playerSlot == 0 && Input.GetKeyDown(PlayableBishopsConfig.VolleyKey.Value))
				{
					_activeAspect.TrySecondary(_player);
				}
				if (_playerSlot == 0 && (Input.GetKeyDown(PlayableBishopsConfig.RoarKey.Value) || Input.GetKeyDown(PlayableBishopsConfig.SignatureMouseButton.Value)))
				{
					_activeAspect.TrySignature((MonoBehaviour)(object)this, _player);
				}
				if (_playerSlot == 0 && Input.GetKeyDown(PlayableBishopsConfig.ResetKey.Value))
				{
					_activeAspect.ResetVisualState();
				}
				PollControllerCombatInput(_player);
			}
		}

		private bool IsControllerTogglePressed(PlayerFarming player)
		{
			if (PlayableBishopsConfig.ControllerToggleChord == null || !PlayableBishopsConfig.ControllerToggleChord.Value || (Object)(object)player == (Object)null || player.rewiredPlayer == null || Time.timeScale <= 0.01f)
			{
				return false;
			}
			foreach (Joystick joystick in player.rewiredPlayer.controllers.Joysticks)
			{
				if (joystick == null || !((Controller)joystick).isConnected || !((Controller)joystick).enabled)
				{
					continue;
				}
				IGamepadTemplate template = ((Controller)joystick).GetTemplate<IGamepadTemplate>();
				if (template == null || template.dPad == null || template.dPad.up == null)
				{
					continue;
				}
				IControllerTemplateButton val = ((PlayableBishopsConfig.ControllerToggleStickChoice.Value != ControllerToggleStick.RightStick) ? ((template.leftStick != null) ? template.leftStick.press : null) : ((template.rightStick != null) ? template.rightStick.press : null));
				if (val != null)
				{
					bool value = val.value;
					bool value2 = template.dPad.up.value;
					if ((value && template.dPad.up.justPressed) || (value2 && val.justPressed))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void PollControllerCombatInput(PlayerFarming player)
		{
			if (!((Object)(object)player == (Object)null) && player.rewiredPlayer != null && player.rewiredPlayer.controllers.Joysticks.Count != 0)
			{
				Player rewiredPlayer = player.rewiredPlayer;
				if (rewiredPlayer.GetButtonDown(2))
				{
					CaptureBasicAttack(player);
				}
				if (rewiredPlayer.GetButtonDown(13))
				{
					CaptureSecondaryAttack(player);
				}
				if (rewiredPlayer.GetButtonDown(94))
				{
					CaptureSignatureAttack(player);
				}
				if (rewiredPlayer.GetButtonDown(16))
				{
					CaptureDodge(player);
				}
			}
		}

		private void LateUpdate()
		{
			if (IsActive && IsPlayerUsable(_player))
			{
				_activeAspect.Follow(_player);
				KeepPlayerHidden();
			}
			else if (IsCultLeaderActive && IsPlayerUsable(_player))
			{
				_cultLeader.Follow(_player);
				KeepPlayerHidden();
			}
		}

		private void Toggle()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (_activationPending || _leaderActivationPending || _leaderDeactivationPending || _lifecycleTransitionInProgress || _deathPresentationInProgress || _formTransitionInProgress)
			{
				PlayableBishopsLog.Debug("Aspect toggle ignored while a lifecycle presentation is running.");
				return;
			}
			if (!GameManager.IsDungeon(PlayerFarming.Location) && PlayableBishopsConfig.CultLeaderFormsOutsideDungeons.Value)
			{
				ToggleCultLeader();
				return;
			}
			BishopAspectDefinition bishopAspectDefinition = BishopAspectRegistry.Get(PlayableBishopsConfig.GetSelectedAspect(_playerSlot));
			PlayableBishopsPlugin.Log.LogInfo((object)(PlayerLabel + " " + bishopAspectDefinition.DisplayName + " toggle requested; current state is " + (IsActive ? "active" : "inactive") + "."));
			if (IsActive)
			{
				_autoActivationBlockedUntilDungeonExit = GameManager.IsDungeon(PlayerFarming.Location);
				Deactivate();
				return;
			}
			if (_activationPending)
			{
				PlayableBishopsLog.Debug("Aspect activation is already pending.");
				return;
			}
			PlayerFarming slotPlayer = GetSlotPlayer();
			if (!IsPlayerUsable(slotPlayer))
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(bishopAspectDefinition.DisplayName + " aspect needs an active player."));
				return;
			}
			if (!PlayableBishopsConfig.AllowOutsideDungeons.Value && !GameManager.IsDungeon(PlayerFarming.Location))
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(bishopAspectDefinition.DisplayName + " aspect is currently limited to dungeon locations. Set AllowOutsideDungeons=true to override."));
				return;
			}
			if (string.Equals(bishopAspectDefinition.Id, "None", StringComparison.OrdinalIgnoreCase))
			{
				PlayableBishopsPlugin.Log.LogInfo((object)"No Bishop Aspect is selected. Choose one from the altar row.");
				return;
			}
			BishopAspect bishopAspect = ResolveAspect(bishopAspectDefinition.Id);
			if (!bishopAspectDefinition.Implemented || bishopAspect == null)
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(bishopAspectDefinition.DisplayName + " is registered but does not have a playable controller yet."));
				return;
			}
			_autoActivationBlockedUntilDungeonExit = false;
			BeginActivation(slotPlayer, bishopAspect, automatic: false, playSpawnPresentation: true);
		}

		private void ToggleCultLeader()
		{
			BishopAspectDefinition bishopAspectDefinition = BishopAspectRegistry.Get(PlayableBishopsConfig.GetSelectedAspect(_playerSlot));
			PlayableBishopsPlugin.Log.LogInfo((object)(PlayerLabel + " " + bishopAspectDefinition.DisplayName + " cult-leader toggle requested; current state is " + (IsCultLeaderActive ? "active" : "inactive") + "."));
			if (IsCultLeaderActive)
			{
				_leaderDesiredOutside = false;
				BeginCultLeaderDeactivation();
				return;
			}
			if (string.Equals(bishopAspectDefinition.Id, "None", StringComparison.OrdinalIgnoreCase))
			{
				PlayableBishopsPlugin.Log.LogInfo((object)"No Bishop Aspect is selected. Choose one from the altar row.");
				return;
			}
			PlayerFarming slotPlayer = GetSlotPlayer();
			if (!IsPlayerUsable(slotPlayer))
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(bishopAspectDefinition.DisplayName + " cult-leader form needs an active player."));
				return;
			}
			CultLeaderDefinition cultLeaderDefinition = CultLeaderRegistry.Get(bishopAspectDefinition.Id);
			if (!bishopAspectDefinition.Implemented || cultLeaderDefinition == null)
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(bishopAspectDefinition.DisplayName + " does not have a cult-leader presentation configured."));
				return;
			}
			_leaderDesiredOutside = true;
			_leaderRestorePending = false;
			BeginCultLeaderActivation(slotPlayer, cultLeaderDefinition, playPlayerWarp: true);
		}

		private void BeginCultLeaderActivation(PlayerFarming player, CultLeaderDefinition definition, bool playPlayerWarp)
		{
			if (!_leaderActivationPending && !_formTransitionInProgress)
			{
				_leaderActivationPending = true;
				((MonoBehaviour)this).StartCoroutine(CultLeaderActivationRoutine(player, definition, playPlayerWarp));
			}
		}

		private IEnumerator CultLeaderActivationRoutine(PlayerFarming player, CultLeaderDefinition definition, bool playPlayerWarp)
		{
			bool created = false;
			string error = null;
			_player = player;
			yield return _cultLeader.Activate((MonoBehaviour)(object)this, player, definition, delegate(bool success, string reason)
			{
				created = success;
				error = reason;
			});
			if (!created || !IsPlayerUsable(player) || GameManager.IsDungeon(PlayerFarming.Location))
			{
				_leaderActivationPending = false;
				_cultLeader.Deactivate();
				RestorePlayer();
				if (!created)
				{
					_leaderDesiredOutside = false;
					PlayableBishopsPlugin.Log.LogError((object)("Could not activate " + definition.DisplayName + " cult-leader form: " + (error ?? "unknown asset error")));
				}
				yield break;
			}
			_cultLeader.Follow(player);
			_cultLeader.SetAlpha(0f);
			float transitionDuration = Mathf.Max(0.1f, PlayableBishopsConfig.CultLeaderTransitionDuration.Value);
			if (playPlayerWarp)
			{
				PlayPlayerWarp(player, warpOut: true);
				yield return WaitForCultLeader(player, transitionDuration);
			}
			if (!IsPlayerUsable(player) || GameManager.IsDungeon(PlayerFarming.Location))
			{
				_leaderActivationPending = false;
				_cultLeader.Deactivate();
				RestorePlayer();
				yield break;
			}
			HidePlayer(player);
			_cultLeader.Follow(player);
			_cultLeader.BeginReveal();
			yield return BishopPresentation.Fade(_cultLeader.Spine, 0f, 1f, transitionDuration);
			_leaderActivationPending = false;
			PlayableBishopsPlugin.Log.LogInfo((object)(PlayerLabel + " " + definition.DisplayName + " cult-leader form active outside the dungeon."));
		}

		private void BeginCultLeaderDeactivation()
		{
			if (!_leaderDeactivationPending)
			{
				_leaderDeactivationPending = true;
				((MonoBehaviour)this).StartCoroutine(CultLeaderDeactivationRoutine());
			}
		}

		private IEnumerator CultLeaderDeactivationRoutine()
		{
			PlayerFarming player = _player;
			float duration = Mathf.Max(0.1f, PlayableBishopsConfig.CultLeaderTransitionDuration.Value);
			if (_cultLeader.IsValid)
			{
				yield return BishopPresentation.Fade(_cultLeader.Spine, 1f, 0f, duration);
			}
			_cultLeader.Deactivate();
			RestorePlayer();
			if (IsPlayerUsable(player))
			{
				PlayPlayerWarp(player, warpOut: false);
			}
			_leaderDeactivationPending = false;
			PlayableBishopsLog.Debug("Cult-leader form inactive.");
		}

		private IEnumerator WaitForCultLeader(PlayerFarming player, float duration)
		{
			float elapsed = 0f;
			while (IsPlayerUsable(player))
			{
				float num;
				elapsed = (num = elapsed + Time.unscaledDeltaTime);
				if (num < duration)
				{
					_cultLeader.Follow(player);
					yield return null;
					continue;
				}
				break;
			}
		}

		private static void PlayPlayerWarp(PlayerFarming player, bool warpOut)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPlayerUsable(player))
			{
				return;
			}
			try
			{
				string text = (warpOut ? "warp-out-down" : "warp-in-up");
				if ((Object)(object)player.Spine != (Object)null && ((SkeletonRenderer)player.Spine).Skeleton != null && ((SkeletonRenderer)player.Spine).Skeleton.Data.FindAnimation(text) != null)
				{
					player.Spine.AnimationState.SetAnimation(0, text, false);
					player.Spine.AnimationState.AddAnimation(0, "idle", true, 0f);
				}
				if ((Object)(object)AudioManager.Instance != (Object)null)
				{
					AudioManager.Instance.PlayOneShot(warpOut ? "event:/enemy/teleport_away" : "event:/enemy/teleport_appear", ((Component)player).transform.position);
				}
			}
			catch (Exception ex)
			{
				PlayableBishopsLog.Debug("Player cult-leader warp presentation failed: " + ex.GetBaseException().Message);
			}
		}

		private void UpdateLocationMode()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			bool flag = GameManager.IsDungeon(PlayerFarming.Location);
			if (!_locationModeInitialized)
			{
				_locationModeInitialized = true;
				_wasInDungeon = flag;
			}
			else
			{
				if (_wasInDungeon == flag)
				{
					return;
				}
				_wasInDungeon = flag;
				if (flag)
				{
					_transformedThisDungeon = false;
					_leaderToBossPending = _leaderDesiredOutside;
					_leaderRestorePending = false;
					_autoActivationBlockedUntilDungeonExit = false;
					if (IsCultLeaderActive || _leaderActivationPending || _leaderDeactivationPending)
					{
						DeactivateCultLeaderImmediate(restorePlayer: true);
					}
					PlayableBishopsLog.Debug("Entered a dungeon; controller switched to boss-form toggling.");
					return;
				}
				_leaderToBossPending = false;
				_transformedThisDungeon = false;
				_autoActivationBlockedUntilDungeonExit = false;
				_nextAutoActivationTime = 0f;
				if (_formTransitionInProgress)
				{
					DeactivateCultLeaderImmediate(restorePlayer: true);
				}
				if (IsActive || _activationPending || _deactivationPending)
				{
					DeactivateImmediate();
				}
				_leaderRestorePending = _leaderDesiredOutside;
				PlayableBishopsLog.Debug("Left the dungeon; controller switched to cult-leader toggling.");
			}
		}

		private void BeginLeaderToBossHandoff(PlayerFarming player, BishopAspect aspect, CultLeaderDefinition definition)
		{
			if (!_formTransitionInProgress)
			{
				_formTransitionInProgress = true;
				((MonoBehaviour)this).StartCoroutine(LeaderToBossHandoffRoutine(player, aspect, definition));
			}
		}

		private IEnumerator LeaderToBossHandoffRoutine(PlayerFarming player, BishopAspect aspect, CultLeaderDefinition definition)
		{
			bool created = false;
			string error = null;
			yield return _cultLeader.Activate((MonoBehaviour)(object)this, player, definition, delegate(bool success, string reason)
			{
				created = success;
				error = reason;
			});
			if (created && IsPlayerUsable(player) && GameManager.IsDungeon(PlayerFarming.Location))
			{
				_player = player;
				HidePlayer(player);
				_cultLeader.Follow(player);
				_cultLeader.SetAlpha(1f);
				float num = _cultLeader.BeginTransformation();
				if (num <= 0f)
				{
					num = Mathf.Max(0.1f, PlayableBishopsConfig.CultLeaderTransitionDuration.Value);
					yield return BishopPresentation.Fade(_cultLeader.Spine, 1f, 0f, num);
				}
				else
				{
					yield return WaitForCultLeader(player, num);
				}
				_cultLeader.Deactivate();
			}
			else if (!created)
			{
				PlayableBishopsPlugin.Log.LogWarning((object)(definition.DisplayName + " cult-leader transformation could not be shown: " + (error ?? "asset unavailable") + ". Activating the boss directly."));
			}
			else
			{
				_cultLeader.Deactivate();
			}
			_leaderToBossPending = false;
			_transformedThisDungeon = true;
			_formTransitionInProgress = false;
			if (!IsPlayerUsable(player) || !GameManager.IsDungeon(PlayerFarming.Location))
			{
				RestorePlayer();
			}
			else
			{
				BeginActivation(player, aspect, automatic: true, playSpawnPresentation: false);
			}
		}

		private void DeactivateCultLeaderImmediate(bool restorePlayer)
		{
			((MonoBehaviour)this).StopAllCoroutines();
			_leaderActivationPending = false;
			_leaderDeactivationPending = false;
			_formTransitionInProgress = false;
			_cultLeader.Deactivate();
			if (restorePlayer)
			{
				RestorePlayer();
			}
		}

		private void BeginActivation(PlayerFarming player, BishopAspect aspect, bool automatic, bool playSpawnPresentation)
		{
			_activationPending = true;
			((MonoBehaviour)this).StartCoroutine(ActivateRoutine(player, aspect, automatic, playSpawnPresentation));
		}

		private IEnumerator ActivateRoutine(PlayerFarming player, BishopAspect aspect, bool automatic, bool playSpawnPresentation)
		{
			bool created = false;
			string error = null;
			_player = player;
			_activeAspect = aspect;
			yield return aspect.Activate(this, player, delegate(bool success, string reason)
			{
				created = success;
				error = reason;
			});
			_activationPending = false;
			if (!created || !IsPlayerUsable(player))
			{
				aspect.Deactivate();
				if (_activeAspect == aspect)
				{
					_activeAspect = null;
				}
				RestorePlayer();
				PlayableBishopsPlugin.Log.LogError((object)("Could not activate " + aspect.DisplayName + " aspect: " + (error ?? "player became unavailable")));
				if (automatic)
				{
					_autoActivationBlockedUntilDungeonExit = true;
				}
				yield break;
			}
			HidePlayer(player);
			aspect.Follow(player);
			_lifecycleTransitionInProgress = true;
			float num = 0f;
			try
			{
				if (playSpawnPresentation)
				{
					num = aspect.BeginSpawnPresentation();
				}
			}
			catch (Exception ex)
			{
				PlayableBishopsPlugin.Log.LogError((object)(aspect.DisplayName + " spawn presentation failed: " + ex.GetBaseException().Message));
			}
			yield return WaitForPresentation(aspect, Mathf.Max(0f, num));
			if (_activeAspect == aspect)
			{
				try
				{
					aspect.CompleteSpawnPresentation();
				}
				catch (Exception ex2)
				{
					PlayableBishopsPlugin.Log.LogError((object)(aspect.DisplayName + " spawn completion failed: " + ex2.GetBaseException().Message));
				}
				_lifecycleTransitionInProgress = false;
				PlayableBishopsPlugin.Log.LogInfo((object)(aspect.DisplayName + " aspect active."));
			}
		}

		private void UpdateAutomaticActivation()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!GameManager.IsDungeon(PlayerFarming.Location))
			{
				_autoActivationBlockedUntilDungeonExit = false;
				_nextAutoActivationTime = 0f;
				if (_leaderRestorePending && _leaderDesiredOutside && PlayableBishopsConfig.CultLeaderFormsOutsideDungeons.Value && !IsCultLeaderActive && !_leaderActivationPending && !_leaderDeactivationPending && !_formTransitionInProgress)
				{
					PlayerFarming slotPlayer = GetSlotPlayer();
					CultLeaderDefinition cultLeaderDefinition = CultLeaderRegistry.Get(BishopAspectRegistry.Get(PlayableBishopsConfig.GetSelectedAspect(_playerSlot)).Id);
					if (IsPlayerUsable(slotPlayer) && cultLeaderDefinition != null)
					{
						_leaderRestorePending = false;
						BeginCultLeaderActivation(slotPlayer, cultLeaderDefinition, playPlayerWarp: false);
					}
				}
			}
			else
			{
				if (IsActive || _activationPending || _lifecycleTransitionInProgress || _formTransitionInProgress || _autoActivationBlockedUntilDungeonExit || Time.time < _nextAutoActivationTime)
				{
					return;
				}
				PlayerFarming slotPlayer2 = GetSlotPlayer();
				if (!IsPlayerUsable(slotPlayer2))
				{
					return;
				}
				BishopAspectDefinition bishopAspectDefinition = BishopAspectRegistry.Get(PlayableBishopsConfig.GetSelectedAspect(_playerSlot));
				if (string.Equals(bishopAspectDefinition.Id, "None", StringComparison.OrdinalIgnoreCase))
				{
					_leaderToBossPending = false;
					return;
				}
				BishopAspect bishopAspect = ResolveAspect(bishopAspectDefinition.Id);
				if (!bishopAspectDefinition.Implemented || bishopAspect == null)
				{
					_leaderToBossPending = false;
					return;
				}
				if (_leaderToBossPending && !_transformedThisDungeon)
				{
					CultLeaderDefinition cultLeaderDefinition2 = CultLeaderRegistry.Get(bishopAspectDefinition.Id);
					if (cultLeaderDefinition2 != null)
					{
						_nextAutoActivationTime = Time.time + 2f;
						PlayableBishopsPlugin.Log.LogInfo((object)("Transforming " + PlayerLabel + " " + bishopAspectDefinition.DisplayName + " from cult-leader form into the dungeon boss form."));
						BeginLeaderToBossHandoff(slotPlayer2, bishopAspect, cultLeaderDefinition2);
						return;
					}
					_leaderToBossPending = false;
				}
				if (PlayableBishopsConfig.AutoActivateInDungeons.Value)
				{
					_nextAutoActivationTime = Time.time + 2f;
					PlayableBishopsPlugin.Log.LogInfo((object)("Automatically activating " + PlayerLabel + " Bishop Aspect: " + bishopAspectDefinition.DisplayName + "."));
					BeginActivation(slotPlayer2, bishopAspect, automatic: true, playSpawnPresentation: true);
				}
			}
		}

		private void HidePlayer(PlayerFarming player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.Spine == (Object)null))
			{
				RecoverPlayerAttackState(player);
				RestorePlayerRenderers();
				((Component)player.Spine).gameObject.SetActive(true);
				Renderer[] componentsInChildren = ((Component)player.Spine).gameObject.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					_playerRendererStates.Add(new PlayerRendererState
					{
						Renderer = val,
						ForceRenderingOff = val.forceRenderingOff
					});
					val.forceRenderingOff = true;
				}
			}
		}

		private void KeepPlayerHidden()
		{
			for (int i = 0; i < _playerRendererStates.Count; i++)
			{
				Renderer renderer = _playerRendererStates[i].Renderer;
				if ((Object)(object)renderer != (Object)null)
				{
					renderer.forceRenderingOff = true;
				}
			}
		}

		private void RestorePlayer()
		{
			RestorePlayerRenderers();
			RecoverPlayerAttackState(_player);
			_player = null;
		}

		private void RestorePlayerRenderers()
		{
			for (int i = 0; i < _playerRendererStates.Count; i++)
			{
				PlayerRendererState playerRendererState = _playerRendererStates[i];
				if ((Object)(object)playerRendererState.Renderer != (Object)null)
				{
					playerRendererState.Renderer.forceRenderingOff = playerRendererState.ForceRenderingOff;
				}
			}
			_playerRendererStates.Clear();
		}

		private static void RecoverPlayerAttackState(PlayerFarming player)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0047: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if ((Object)(object)player.playerWeapon != (Object)null)
			{
				player.playerWeapon.StopAttackRoutine();
			}
			player.HoldingAttack = false;
			if ((Object)(object)player.state == (Object)null)
			{
				return;
			}
			State cURRENT_STATE = player.state.CURRENT_STATE;
			if ((int)cURRENT_STATE == 2 || (int)cURRENT_STATE == 4 || (int)cURRENT_STATE == 5 || (int)cURRENT_STATE == 46 || (int)cURRENT_STATE == 54)
			{
				player.state.CURRENT_STATE = (State)0;
				if ((Object)(object)player.playerController != (Object)null)
				{
					player.playerController.speed = player.playerController.GetPlayerMaxSpeed();
				}
				PlayableBishopsPlugin.Log.LogInfo((object)"Recovered the underlying player from a weapon attack state.");
			}
		}

		internal bool BlocksBasicAttack(PlayerFarming player)
		{
			if (IsActive && (Object)(object)_player != (Object)null)
			{
				return (Object)(object)player == (Object)(object)_player;
			}
			return false;
		}

		internal bool BlocksCombatInput(PlayerFarming player)
		{
			return BlocksBasicAttack(player);
		}

		internal bool BlocksDodgeInput(PlayerFarming player)
		{
			if (BlocksBasicAttack(player) && _activeAspect != null)
			{
				return _activeAspect.UsesDodgeAbility;
			}
			return false;
		}

		internal void CaptureBasicAttack(PlayerFarming player)
		{
			if (CanCaptureCombatInput(player) && _lastCapturedAttackFrame != Time.frameCount)
			{
				_lastCapturedAttackFrame = Time.frameCount;
				_activeAspect.TryPrimary(_player);
			}
		}

		internal void CaptureSecondaryAttack(PlayerFarming player)
		{
			if (CanCaptureCombatInput(player) && _lastCapturedSecondaryFrame != Time.frameCount)
			{
				_lastCapturedSecondaryFrame = Time.frameCount;
				_activeAspect.TrySecondary(_player);
			}
		}

		internal void CaptureSignatureAttack(PlayerFarming player)
		{
			if (CanCaptureCombatInput(player) && _lastCapturedSignatureFrame != Time.frameCount)
			{
				_lastCapturedSignatureFrame = Time.frameCount;
				_activeAspect.TrySignature((MonoBehaviour)(object)this, _player);
			}
		}

		internal void CaptureDodge(PlayerFarming player)
		{
			if (CanCaptureCombatInput(player) && BlocksDodgeInput(player) && _lastCapturedDodgeFrame != Time.frameCount)
			{
				_lastCapturedDodgeFrame = Time.frameCount;
				_activeAspect.TryDodge((MonoBehaviour)(object)this, _player);
			}
		}

		internal void SelectAspect(string aspectId)
		{
			BishopAspectDefinition bishopAspectDefinition = BishopAspectRegistry.Get(aspectId);
			_leaderDesiredOutside = false;
			_leaderRestorePending = false;
			_leaderToBossPending = false;
			if (IsCultLeaderActive || _leaderActivationPending || _leaderDeactivationPending)
			{
				DeactivateCultLeaderImmediate(restorePlayer: true);
			}
			if (IsActive)
			{
				Deactivate();
			}
			PlayableBishopsConfig.SetSelectedAspect(_playerSlot, bishopAspectDefinition.Id);
			PlayableBishopsPlugin.Log.LogInfo((object)("Selected " + PlayerLabel + " Bishop Aspect: " + bishopAspectDefinition.DisplayName + "."));
		}

		internal void Deactivate()
		{
			if (!_deactivationPending && !_deathPresentationInProgress)
			{
				BishopAspect activeAspect = _activeAspect;
				if (activeAspect == null)
				{
					DeactivateImmediate();
					return;
				}
				((MonoBehaviour)this).StopAllCoroutines();
				_activationPending = false;
				_lifecycleTransitionInProgress = true;
				_deactivationPending = true;
				((MonoBehaviour)this).StartCoroutine(DeactivateRoutine(activeAspect));
			}
		}

		private IEnumerator DeactivateRoutine(BishopAspect aspect)
		{
			float num = 0f;
			try
			{
				num = aspect.BeginDespawnPresentation();
			}
			catch (Exception ex)
			{
				PlayableBishopsPlugin.Log.LogError((object)(aspect.DisplayName + " despawn presentation failed: " + ex.GetBaseException().Message));
			}
			yield return WaitForPresentation(aspect, Mathf.Max(0f, num));
			CompleteDeactivation(aspect);
		}

		private IEnumerator WaitForPresentation(BishopAspect aspect, float duration)
		{
			float elapsed = 0f;
			while (_activeAspect == aspect)
			{
				float num;
				elapsed = (num = elapsed + Time.unscaledDeltaTime);
				if (num < duration)
				{
					if (IsPlayerUsable(_player))
					{
						KeepPlayerHidden();
					}
					yield return null;
					continue;
				}
				break;
			}
		}

		private bool CanCaptureCombatInput(PlayerFarming player)
		{
			if (BlocksBasicAttack(player) && (Object)(object)_player != (Object)null && !_activationPending && !_lifecycleTransitionInProgress)
			{
				return !_deathPresentationInProgress;
			}
			return false;
		}

		private void DeactivateImmediate()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			CompleteDeactivation(_activeAspect);
		}

		private void CompleteDeactivation(BishopAspect aspect)
		{
			_deathPresentationInProgress = false;
			_lifecycleTransitionInProgress = false;
			_deactivationPending = false;
			_activationPending = false;
			if (_activeAspect == aspect)
			{
				_activeAspect = null;
			}
			if (aspect != null)
			{
				try
				{
					aspect.Deactivate();
				}
				catch (Exception ex)
				{
					PlayableBishopsPlugin.Log.LogError((object)(aspect.DisplayName + " cleanup failed: " + ex.GetBaseException().Message));
				}
			}
			RestorePlayer();
			PlayableBishopsLog.Debug("Bishop aspect inactive.");
		}

		internal void Shutdown()
		{
			DeactivateImmediate();
			_cultLeader.Dispose();
			_leshy.Dispose();
			_heket.Dispose();
			_kallamar.Dispose();
			_shamura.Dispose();
		}

		private BishopAspect ResolveAspect(string aspectId)
		{
			if (string.Equals(aspectId, "Leshy", StringComparison.OrdinalIgnoreCase))
			{
				return _leshy;
			}
			if (string.Equals(aspectId, "Heket", StringComparison.OrdinalIgnoreCase))
			{
				return _heket;
			}
			if (string.Equals(aspectId, "Kallamar", StringComparison.OrdinalIgnoreCase))
			{
				return _kallamar;
			}
			if (string.Equals(aspectId, "Shamura", StringComparison.OrdinalIgnoreCase))
			{
				return _shamura;
			}
			return null;
		}

		private void BeginDeathPresentation()
		{
			if (!_deathPresentationInProgress && _activeAspect != null)
			{
				_deathPresentationInProgress = true;
				_lifecycleTransitionInProgress = true;
				_deactivationPending = false;
				_activationPending = false;
				((MonoBehaviour)this).StopAllCoroutines();
				float num = 0f;
				try
				{
					num = _activeAspect.BeginDeathPresentation();
				}
				catch (Exception ex)
				{
					PlayableBishopsPlugin.Log.LogError((object)(_activeAspect.DisplayName + " death presentation failed: " + ex.GetBaseException().Message));
				}
				PlayableBishopsPlugin.Log.LogInfo((object)("Playing " + _activeAspect.DisplayName + " death presentation."));
				((MonoBehaviour)this).StartCoroutine(DeathPresentationRoutine(Mathf.Max(0.1f, num)));
			}
		}

		private IEnumerator DeathPresentationRoutine(float duration)
		{
			float elapsed = 0f;
			while (_activeAspect != null)
			{
				float num;
				elapsed = (num = elapsed + Time.unscaledDeltaTime);
				if (!(num < duration))
				{
					break;
				}
				KeepPlayerHidden();
				yield return null;
			}
			CompleteDeactivation(_activeAspect);
		}

		private static bool IsPlayerUsable(PlayerFarming player)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)((Component)player).gameObject != (Object)null && ((Component)player).gameObject.activeInHierarchy && (Object)(object)player.health != (Object)null)
			{
				return ((Health)player.health).HP > 0f;
			}
			return false;
		}

		private PlayerFarming GetSlotPlayer()
		{
			if (PlayerFarming.players == null || _playerSlot < 0 || _playerSlot >= PlayerFarming.players.Count)
			{
				return null;
			}
			return PlayerFarming.players[_playerSlot];
		}

		private static string DescribePlayer(PlayerFarming player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return "PlayerFarming reference is null";
			}
			if ((Object)(object)((Component)player).gameObject == (Object)null)
			{
				return "player GameObject is missing";
			}
			if (!((Component)player).gameObject.activeInHierarchy)
			{
				return "player GameObject is inactive";
			}
			if ((Object)(object)player.health == (Object)null)
			{
				return "player Health is missing";
			}
			return "player HP is " + ((Health)player.health).HP.ToString("F2");
		}
	}
	internal abstract class BishopAspect
	{
		internal abstract string Id { get; }

		internal abstract string DisplayName { get; }

		internal abstract bool IsActive { get; }

		internal abstract bool IsValid { get; }

		internal virtual bool UsesDodgeAbility => false;

		internal abstract IEnumerator Activate(BishopAspectController controller, PlayerFarming player, Action<bool, string> completed);

		internal abstract void Follow(PlayerFarming player);

		internal abstract void TryPrimary(PlayerFarming player);

		internal abstract void TrySecondary(PlayerFarming player);

		internal abstract void TrySignature(MonoBehaviour host, PlayerFarming player);

		internal virtual void TryDodge(MonoBehaviour host, PlayerFarming player)
		{
		}

		internal virtual float BeginSpawnPresentation()
		{
			return 0f;
		}

		internal virtual void CompleteSpawnPresentation()
		{
		}

		internal virtual float BeginDespawnPresentation()
		{
			return 0f;
		}

		internal virtual float BeginDeathPresentation()
		{
			return 0f;
		}

		internal abstract void ResetVisualState();

		internal abstract void Deactivate();

		internal abstract void Dispose();
	}
	internal static class BishopPresentation
	{
		internal static float GetAnimationDuration(SkeletonAnimation spine, string animationName, float fallback, float minimum, float maximum)
		{
			if ((Object)(object)spine == (Object)null || ((SkeletonRenderer)spine).Skeleton == null || ((SkeletonRenderer)spine).Skeleton.Data == null || string.IsNullOrEmpty(animationName))
			{
				return fallback;
			}
			Animation val = ((SkeletonRenderer)spine).Skeleton.Data.FindAnimation(animationName);
			if (val == null)
			{
				return fallback;
			}
			return Mathf.Clamp(val.Duration, minimum, maximum);
		}

		internal static void SetAlpha(SkeletonAnimation spine, float alpha)
		{
			if ((Object)(object)spine != (Object)null && ((SkeletonRenderer)spine).Skeleton != null)
			{
				((SkeletonRenderer)spine).Skeleton.A = Mathf.Clamp01(alpha);
			}
		}

		internal static IEnumerator Fade(SkeletonAnimation spine, float from, float to, float duration)
		{
			if ((Object)(object)spine == (Object)null || ((SkeletonRenderer)spine).Skeleton == null)
			{
				yield break;
			}
			duration = Mathf.Max(0.01f, duration);
			float elapsed = 0f;
			SetAlpha(spine, from);
			while ((Object)(object)spine != (Object)null && ((SkeletonRenderer)spine).Skeleton != null)
			{
				float num;
				elapsed = (num = elapsed + Time.unscaledDeltaTime);
				if (!(num < duration))
				{
					break;
				}
				SetAlpha(spine, Mathf.Lerp(from, to, elapsed / duration));
				yield return null;
			}
			SetAlpha(spine, to);
		}
	}
	internal static class BishopAim
	{
		private const float TeleportPathSampleSpacing = 0.2f;

		private static readonly Vector2[] TeleportEndpointProbeDirections = (Vector2[])(object)new Vector2[8]
		{
			Vector2.up,
			Vector2.down,
			Vector2.left,
			Vector2.right,
			new Vector2(0.7071068f, 0.7071068f),
			new Vector2(-0.7071068f, 0.7071068f),
			new Vector2(0.7071068f, -0.7071068f),
			new Vector2(-0.7071068f, -0.7071068f)
		};

		internal static Vector3 GetDirection(PlayerFarming player)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			float num = (((Object)(object)player != (Object)null && (Object)(object)player.state != (Object)null) ? player.state.facingAngle : 0f);
			if (TryGetMouseCamera(player, out var camera, out var mouseScreen))
			{
				num = Utils.GetAngle(camera.WorldToScreenPoint(((Component)player).transform.position), mouseScreen);
			}
			float num2 = num * ((float)Math.PI / 180f);
			Vector3 val = new Vector3(Mathf.Cos(num2), Mathf.Sin(num2), 0f);
			return ((Vector3)(ref val)).normalized;
		}

		internal static Vector3 GetPoint(PlayerFarming player, float fallbackDistance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetMouseCamera(player, out var camera, out var mouseScreen))
			{
				Ray val = camera.ScreenPointToRay(mouseScreen);
				Plane val2 = default(Plane);
				((Plane)(ref val2))..ctor(Vector3.forward, Vector3.zero);
				float num = default(float);
				if (((Plane)(ref val2)).Raycast(val, ref num))
				{
					return ((Ray)(ref val)).GetPoint(num);
				}
			}
			return (((Object)(object)player != (Object)null) ? ((Component)player).transform.position : Vector3.zero) + GetDirection(player) * fallbackDistance;
		}

		internal static Vector3 GetAssistedPoint(PlayerFarming player, float fallbackDistance, float maxRange)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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_0144: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 point = GetPoint(player, fallbackDistance);
			if ((Object)(object)player == (Object)null || PlayableBishopsConfig.ProjectileAimAssist == null || !PlayableBishopsConfig.ProjectileAimAssist.Value)
			{
				return point;
			}
			Vector3 position = ((Component)player).transform.position;
			Camera camera;
			Vector3 mouseScreen;
			bool flag = TryGetMouseCamera(player, out camera, out mouseScreen);
			Vector3 direction = GetDirection(player);
			float value = PlayableBishopsConfig.ProjectileAimAssistMouseRadius.Value;
			float num = Mathf.Cos(PlayableBishopsConfig.ProjectileAimAssistControllerCone.Value * ((float)Math.PI / 180f));
			Health val = null;
			float num2 = float.MaxValue;
			Health val2 = null;
			float num3 = float.MaxValue;
			for (int num4 = Health.team2.Count - 1; num4 >= 0; num4--)
			{
				Health val3 = Health.team2[num4];
				if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).gameObject == (Object)null || !((Component)val3).gameObject.activeInHierarchy || !((Behaviour)val3).enabled || val3.HP <= 0f || val3.InanimateObject)
				{
					continue;
				}
				Vector3 val4 = ((Component)val3).transform.position - position;
				val4.z = 0f;
				float magnitude = ((Vector3)(ref val4)).magnitude;
				if (magnitude < 0.05f || magnitude > maxRange)
				{
					continue;
				}
				float num5;
				if (flag)
				{
					Vector3 val5 = ((Component)val3).transform.position - point;
					val5.z = 0f;
					float magnitude2 = ((Vector3)(ref val5)).magnitude;
					if (magnitude2 > value)
					{
						continue;
					}
					num5 = magnitude2 + magnitude * 0.01f;
				}
				else
				{
					float num6 = Vector3.Dot(val4 / magnitude, direction);
					float num7 = magnitude + (1f - num6) * maxRange * 0.35f;
					if (num7 < num3)
					{
						num3 = num7;
						val2 = val3;
					}
					if (num6 < num)
					{
						continue;
					}
					num5 = (1f - num6) * maxRange * 3f + magnitude * 0.08f;
				}
				if (num5 < num2)
				{
					num2 = num5;
					val = val3;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).transform.position;
			}
			if (flag || !((Object)(object)val2 != (Object)null))
			{
				return point;
			}
			return ((Component)val2).transform.position;
		}

		internal static List<Health> GetTargetsInSector(Vector3 origin, Vector3 direction, float maxRange, float halfAngle)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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)
			List<Health> list = new List<Health>();
			direction.z = 0f;
			direction = ((((Vector3)(ref direction)).sqrMagnitude > 0.01f) ? ((Vector3)(ref direction)).normalized : Vector3.right);
			float num = Mathf.Cos(Mathf.Clamp(halfAngle, 1f, 180f) * ((float)Math.PI / 180f));
			float num2 = maxRange * maxRange;
			for (int num3 = Health.team2.Count - 1; num3 >= 0; num3--)
			{
				Health val = Health.team2[num3];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy && ((Behaviour)val).enabled && !(val.HP <= 0f) && !val.InanimateObject)
				{
					Vector3 val2 = ((Component)val).transform.position - origin;
					val2.z = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude > 0.01f && ((Vector3)(ref val2)).sqrMagnitude <= num2 && Vector3.Dot(direction, ((Vector3)(ref val2)).normalized) >= num)
					{
						list.Add(val);
					}
				}
			}
			list.Sort(delegate(Health left, Health right)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val3 = ((Component)left).transform.position - origin;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				val3 = ((Component)right).transform.position - origin;
				return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude);
			});
			return list;
		}

		internal static Vector3 ClampToCurrentRoomFloor(Vector3 origin, Vector3 desired, float inwardMargin)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			desired.z = origin.z;
			BiomeGenerator instance = BiomeGenerator.Instance;
			if ((Object)(object)instance == (Object)null || instance.CurrentRoom == null || (Object)(object)instance.CurrentRoom.generateRoom == (Object)null || instance.CurrentRoom.generateRoom.Pieces == null)
			{
				return desired;
			}
			PolygonCollider2D val = null;
			List<IslandPiece> pieces = instance.CurrentRoom.generateRoom.Pieces;
			for (int i = 0; i < pieces.Count; i++)
			{
				PolygonCollider2D val2 = (((Object)(object)pieces[i] != (Object)null) ? pieces[i].Collider : null);
				if ((Object)(object)val2 != (Object)null && ((Collider2D)val2).OverlapPoint(Vector2.op_Implicit(origin)))
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null || ((Collider2D)val).OverlapPoint(Vector2.op_Implicit(desired)))
			{
				return desired;
			}
			Vector2 val3 = ((Collider2D)val).ClosestPoint(Vector2.op_Implicit(desired));
			Vector2 val4 = Vector2.op_Implicit(origin) - val3;
			if (((Vector2)(ref val4)).sqrMagnitude > 0.0001f)
			{
				val3 += ((Vector2)(ref val4)).normalized * Mathf.Max(0f, inwardMargin);
			}
			return new Vector3(val3.x, val3.y, origin.z);
		}

		internal static Vector3 ClampTeleportRouteToCurrentRoomFloor(Vector3 origin, Vector3 desired, float inwardMargin)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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_0127: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to inval