Decompiled source of HellParty v0.2.0

BepInEx/plugins/HellParty/HellParty.dll

Decompiled 18 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using HellParty.Events;
using HellParty.Native;
using HellParty.Rules;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("artrointel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Host-only stage difficulty and monster abilities for R.E.P.O.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+6502b0fc5a1d46795b931c5af7034de744c04852")]
[assembly: AssemblyProduct("HellParty")]
[assembly: AssemblyTitle("HellParty")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 HellParty
{
	internal sealed class AnimalDivision : MonoBehaviour
	{
		private bool _handled;

		internal void ResetLife()
		{
			_handled = false;
		}

		internal void Died(EnemyHealth health)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!_handled)
			{
				_handled = true;
				health.spawnValuable = false;
				Vector3 origin = NativeEnemy.Position((Component)(object)health);
				StageRuntime current = StageRuntime.Current;
				if ((Object)(object)current == (Object)null)
				{
					Plugin.ModLogger.LogError((object)"Cannot schedule Animal division without an active stage.");
				}
				else
				{
					((MonoBehaviour)current).StartCoroutine(SpawnAfterDelay(current, origin, ((Component)this).transform.right));
				}
			}
		}

		private static IEnumerator SpawnAfterDelay(StageRuntime stage, Vector3 origin, Vector3 right)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(0.5f);
			if ((Object)(object)StageRuntime.Current != (Object)(object)stage || !SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				yield break;
			}
			NavMeshHit val2 = default(NavMeshHit);
			for (int i = 0; i < 2; i++)
			{
				try
				{
					Vector3 val = origin + right * ((i == 0) ? (-0.4f) : 0.4f);
					Vector3 position = (NavMesh.SamplePosition(val, ref val2, 1.5f, -1) ? ((NavMeshHit)(ref val2)).position : origin);
					AnimalSpawnTicket.Create(position, offspring: true);
				}
				catch (Exception arg)
				{
					Plugin.ModLogger.LogError((object)$"Animal division child {i + 1} failed: {arg}");
				}
			}
		}
	}
	internal sealed class AnimalOffspring : MonoBehaviour
	{
		private static readonly FieldRef<EnemyParent, float> ValuableTimer = AccessTools.FieldRefAccess<EnemyParent, float>("valuableSpawnTimer");

		private readonly AnimalOffspringLife _life = new AnimalOffspringLife();

		private EnemyParent _parent;

		private Enemy _enemy;

		private bool _deathHandled;

		internal bool Expired => _life.Expired;

		private void Awake()
		{
			_parent = ((Component)this).GetComponent<EnemyParent>();
			_enemy = ((Component)this).GetComponentInChildren<Enemy>(true);
		}

		internal void Born()
		{
			_deathHandled = false;
			int num = DifficultyRules.AnimalOffspringHealth(_enemy.Health.health);
			_enemy.Health.health = num;
			NativeEnemy.Health.Invoke(_enemy.Health) = num;
			_enemy.Health.spawnValuable = true;
			_enemy.Health.spawnValuableMax = 1;
			_life.Start(Time.time);
		}

		private void Update()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && _life.Started && _life.Expire(Time.time))
			{
				_enemy.Health.spawnValuable = false;
				if (NativeEnemy.Spawned.Invoke(_parent))
				{
					_enemy.CurrentState = (EnemyState)11;
				}
			}
		}

		internal void Died(EnemyHealth health)
		{
			if (!_deathHandled)
			{
				_deathHandled = true;
				if (health.spawnValuable = _life.Die(Time.time))
				{
					ValuableTimer.Invoke(_parent) = 10f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class AnimalDeathPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)__instance).GetComponent<EnemyAnimal>() == (Object)null))
			{
				EnemyParent val = NativeEnemy.Parent((Component)(object)__instance);
				AnimalOffspring component = ((Component)val).GetComponent<AnimalOffspring>();
				if ((Object)(object)component != (Object)null)
				{
					component.Died(__instance);
				}
				else if (DifficultyRules.AnimalDivisionUnlocked(DifficultyService.Current))
				{
					StageRuntime.TryAttach(val);
					((Component)val).GetComponent<AnimalDivision>()?.Died(__instance);
				}
			}
		}
	}
	internal sealed class AnimalPoison : MonoBehaviour
	{
		private static readonly FieldRef<EnemyAnimal, PlayerAvatar> Target = AccessTools.FieldRefAccess<EnemyAnimal, PlayerAvatar>("playerTarget");

		private EnemyParent _parent;

		private EnemyAnimal _animal;

		private EnemyHealth _health;

		private readonly TargetSkillClock _clock = new TargetSkillClock();

		private float _retryAt;

		private bool _loggedError;

		private void Awake()
		{
			_parent = ((Component)this).GetComponent<EnemyParent>();
			_animal = ((Component)this).GetComponentInChildren<EnemyAnimal>(true);
			_health = ((Component)_animal).GetComponent<EnemyHealth>();
		}

		private void Update()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated || !NativeEnemy.Spawned.Invoke(_parent) || NativeEnemy.Dead.Invoke(_health) || NativeEnemy.Health.Invoke(_health) <= 0)
			{
				return;
			}
			int num = DifficultyRules.AnimalGasCooldown(DifficultyService.Current);
			PlayerAvatar val = Target.Invoke(_animal);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			AnimalOffspring component = ((Component)this).GetComponent<AnimalOffspring>();
			if (num == 0 || Time.time < _retryAt || ((Object)(object)component != (Object)null && component.Expired) || !_clock.IsReady(Time.time, hasTarget: true))
			{
				return;
			}
			Vector3 val2 = ((Component)_animal).transform.position - ((Component)val).transform.position;
			if (!DifficultyRules.AnimalGasInRange(((Vector3)(ref val2)).sqrMagnitude))
			{
				return;
			}
			try
			{
				AnimalGas.Emit(((Component)val).transform.position);
				_clock.Used(Time.time, num);
				_loggedError = false;
			}
			catch (Exception arg)
			{
				_retryAt = Time.time + 1f;
				if (!_loggedError)
				{
					Plugin.ModLogger.LogError((object)$"Animal gas failed; retrying: {arg}");
				}
				_loggedError = true;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "Spawn")]
	internal static class CloneAutomaticRespawnPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyParent __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			DuckClone component = ((Component)__instance).GetComponent<DuckClone>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			bool flag = !component.Retired && ((Component)__instance).GetComponent<DuckSpawnTicket>().Pending;
			if (!flag)
			{
				__instance.DespawnedTimerSet(1f, false);
			}
			return flag;
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "EnemySpawn")]
	internal static class AdjacentDuckSpawnPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Enemy enemy, ref bool __result)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			DuckSpawnTicket componentInParent = ((Component)enemy).GetComponentInParent<DuckSpawnTicket>();
			if ((Object)(object)componentInParent == (Object)null || !componentInParent.Pending)
			{
				return true;
			}
			enemy.EnemyTeleported(componentInParent.Position);
			NativeEnemy.FirstPointUsed.Invoke(NativeEnemy.Parent((Component)(object)enemy)) = true;
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
	internal static class DuckSpawnedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyParent __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !NativeEnemy.Spawned.Invoke(__instance))
			{
				return;
			}
			DuckSpawnTicket component = ((Component)__instance).GetComponent<DuckSpawnTicket>();
			EnemyDuck val = NativeEnemy.Duck(__instance);
			if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null)
			{
				if (component.SavedHealth.HasValue)
				{
					NativeEnemy.Health.Invoke(((Component)val).GetComponent<EnemyHealth>()) = component.SavedHealth.Value;
				}
				component.SavedHealth = null;
				component.Pending = false;
				component.HasSpawned = true;
			}
			StageRuntime.TryAttach(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class DuckDeathPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)__instance).GetComponent<EnemyDuck>() == (Object)null))
			{
				EnemyParent val = NativeEnemy.Parent((Component)(object)__instance);
				DuckClone component = ((Component)val).GetComponent<DuckClone>();
				if ((Object)(object)component != (Object)null)
				{
					__instance.spawnValuable = false;
					component.Died();
				}
				else
				{
					((Component)val).GetComponent<DuckFamily>()?.OriginalDied();
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "Despawn")]
	internal static class CloneDropPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyParent __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)((Component)__instance).GetComponent<DuckClone>() != (Object)null)
			{
				EnemyDuck val = NativeEnemy.Duck(__instance);
				if (val != null)
				{
					((Component)val).GetComponent<EnemyHealth>().spawnValuable = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStartedRPC")]
	internal static class PinnedCrownGrabPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabObject __instance)
		{
			CrownCarrier component = ((Component)__instance).GetComponent<CrownCarrier>();
			if (component != null)
			{
				return !component.IsPinned;
			}
			return true;
		}
	}
	internal sealed class BellaAbilities : MonoBehaviour
	{
		private static readonly FieldRef<EnemyTricycle, PlayerAvatar> Target = AccessTools.FieldRefAccess<EnemyTricycle, PlayerAvatar>("playerTarget");

		private static readonly FieldRef<EnemyTricycle, float> AttackTimer = AccessTools.FieldRefAccess<EnemyTricycle, float>("attackTimer");

		private static readonly FieldRef<EnemyTricycle, float> AttackDuration = AccessTools.FieldRefAccess<EnemyTricycle, float>("attackTimerMax");

		private static readonly FieldRef<EnemyTricycle, float> LastSeen = AccessTools.FieldRefAccess<EnemyTricycle, float>("lastSeenPlayerTimer");

		private static readonly MethodInfo SetState = AccessTools.Method(typeof(EnemyTricycle), "SetState", (Type[])null, (Type[])null);

		private EnemyTricycle _bella;

		private EnemyHealth _health;

		private BellaDollCarrier? _doll;

		private BellaBait? _bait;

		private bool _dollCreated;

		private bool _dead;

		private bool Alive
		{
			get
			{
				if (!_dead && NativeEnemy.Health.Invoke(_health) > 0)
				{
					return !NativeEnemy.Dead.Invoke(_health);
				}
				return false;
			}
		}

		private void Awake()
		{
			_bella = ((Component)this).GetComponentInChildren<EnemyTricycle>(true);
			_health = ((Component)_bella).GetComponent<EnemyHealth>();
		}

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (!Alive)
			{
				Died();
				return;
			}
			RemoveDistantBait();
			if (NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_bella)))
			{
				EnsureDoll();
			}
		}

		private void EnsureDoll()
		{
			if (_dollCreated || !Alive)
			{
				return;
			}
			_dollCreated = true;
			try
			{
				_doll = BellaDollCarrier.Create(_bella);
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Bella Clown Doll creation failed: {arg}");
			}
		}

		internal void Spawned()
		{
			if (_dead)
			{
				_dead = false;
				_dollCreated = false;
			}
			EnsureDoll();
		}

		internal void Bell()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if (!Alive || !NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_bella)))
			{
				return;
			}
			EnsureDoll();
			int stage = (((int)_bella.currentState == 5) ? 1 : (((int)_bella.currentState == 6) ? 2 : (((int)_bella.currentState == 7) ? 3 : 0)));
			_doll?.Warning(stage);
			if (!DifficultyRules.BellaBaitUnlocked(DifficultyService.Current))
			{
				return;
			}
			BellaBait bait = _bait;
			_bait = null;
			if ((Object)(object)bait != (Object)null)
			{
				bait.RemoveQuietly();
			}
			try
			{
				Vector3 val = NativeEnemy.Position((Component)(object)_bella);
				Vector3 position;
				Vector3 val2 = (VanillaCatalog.Adjacent(val, Random.Range(0, 3), out position) ? position : val);
				PrefabRef prefab = VanillaCatalog.RandomTinyValuable();
				GameObject val3 = VanillaCatalog.Spawn(prefab, val2 + Vector3.up * 0.25f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
				_bait = val3.AddComponent<BellaBait>();
				_bait.Owner = this;
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Bella bait creation failed: {arg}");
			}
		}

		internal void BaitGrabbed(BellaBait bait, PlayerAvatar player)
		{
			if (!((Object)(object)bait != (Object)(object)_bait) && Alive && NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_bella)) && !((Object)(object)player == (Object)null) && !player.isDisabled && !player.deadSet && !RemoveDistantBait())
			{
				Target.Invoke(_bella) = player;
				AttackTimer.Invoke(_bella) = 0f;
				AttackDuration.Invoke(_bella) = 5f;
				LastSeen.Invoke(_bella) = 10f;
				SetState.Invoke(_bella, new object[1] { (object)(State)11 });
			}
		}

		private bool RemoveDistantBait()
		{
			//IL_0019: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_bait == (Object)null))
			{
				Vector3 val = ((Component)_bait).transform.position - NativeEnemy.Position((Component)(object)_bella);
				if (DifficultyRules.BellaBaitOutOfRange(((Vector3)(ref val)).sqrMagnitude))
				{
					BellaBait bait = _bait;
					_bait = null;
					bait.RemoveQuietly();
					return true;
				}
			}
			return false;
		}

		internal void Died()
		{
			if (!_dead)
			{
				_dead = true;
				if ((Object)(object)_doll != (Object)null)
				{
					_doll.Release();
				}
				_doll = null;
				if (!RemoveDistantBait() && (Object)(object)_bait != (Object)null)
				{
					_bait.Disarm();
				}
				_bait = null;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_bait != (Object)null)
			{
				_bait.Disarm();
			}
		}
	}
	internal sealed class BellaBait : MonoBehaviour
	{
		internal BellaAbilities? Owner;

		internal void Grabbed(PhysGrabber player)
		{
			if ((Object)(object)Owner != (Object)null)
			{
				Owner.BaitGrabbed(this, player.playerAvatar);
			}
		}

		internal void Disarm()
		{
			Owner = null;
			Object.Destroy((Object)(object)this);
		}

		internal void RemoveQuietly()
		{
			Owner = null;
			NetworkLifetime.Remove(((Component)this).gameObject);
		}
	}
	[HarmonyPatch(typeof(EnemyTricycle), "DoBellRing")]
	internal static class BellaBellPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyTricycle __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				StageRuntime.TryAttach(NativeEnemy.Parent((Component)(object)__instance));
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BellaAbilities>()?.Bell();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyTricycle), "OnSpawn")]
	internal static class BellaSpawnPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyTricycle __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				StageRuntime.TryAttach(NativeEnemy.Parent((Component)(object)__instance));
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BellaAbilities>()?.Spawned();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class BellaDeathPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)((Component)__instance).GetComponent<EnemyTricycle>() != (Object)null)
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BellaAbilities>()?.Died();
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerAddRPC")]
	internal static class BellaBaitNetworkGrabPatch
	{
		[HarmonyPrefix]
		private static void Prefix(PhysGrabObject __instance, int photonViewID, out bool __state)
		{
			PhotonView obj = PhotonView.Find(photonViewID);
			PhysGrabber val = ((obj != null) ? ((Component)obj).GetComponent<PhysGrabber>() : null);
			__state = (Object)(object)val != (Object)null && __instance.playerGrabbing.Contains(val);
		}

		[HarmonyPostfix]
		private static void Postfix(PhysGrabObject __instance, int photonViewID, PhotonMessageInfo _info, bool __state)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!__state && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.MasterOnlyRPC(_info))
			{
				PhotonView obj = PhotonView.Find(photonViewID);
				PhysGrabber val = ((obj != null) ? ((Component)obj).GetComponent<PhysGrabber>() : null);
				if ((Object)(object)val != (Object)null && __instance.playerGrabbing.Contains(val))
				{
					((Component)__instance).GetComponent<BellaBait>()?.Grabbed(val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")]
	internal static class BellaBaitSoloGrabPatch
	{
		[HarmonyPrefix]
		private static void Prefix(PhysGrabObject __instance, PhysGrabber player, out bool __state)
		{
			__state = __instance.playerGrabbing.Contains(player);
		}

		[HarmonyPostfix]
		private static void Postfix(PhysGrabObject __instance, PhysGrabber player, bool __state)
		{
			if (!__state && !SemiFunc.IsMultiplayer() && __instance.playerGrabbing.Contains(player))
			{
				((Component)__instance).GetComponent<BellaBait>()?.Grabbed(player);
			}
		}
	}
	internal sealed class BellaDollCarrier : MonoBehaviour
	{
		private EnemyTricycle _bella;

		private Transform _seat;

		private PhysGrabObject _physical;

		private Rigidbody _body;

		private ClownTrap _clown;

		private readonly BellaDollSequence _sequence = new BellaDollSequence();

		private bool _released;

		private float _bottomOffset;

		private Vector3 _lastPosition;

		private Quaternion _lastRotation;

		private Quaternion _seatRotationOffset;

		internal bool IsPinned => !_released;

		internal Enemy? ExplosionOwner
		{
			get
			{
				if (_released || !((Object)(object)_bella != (Object)null))
				{
					return null;
				}
				return ((Component)_bella).GetComponent<Enemy>();
			}
		}

		internal static BellaDollCarrier Create(EnemyTricycle bella)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Transform[] componentsInChildren = ((Component)NativeEnemy.Parent((Component)(object)bella)).GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (((Object)val2).name == "seat")
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Native Bella seat transform not found.");
			}
			PrefabRef prefab = VanillaCatalog.Valuable((GameObject p) => (Object)(object)p.GetComponent<ClownTrap>() != (Object)null);
			GameObject val3 = VanillaCatalog.Spawn(prefab, val.position, val.rotation);
			BellaDollCarrier bellaDollCarrier = val3.AddComponent<BellaDollCarrier>();
			bellaDollCarrier._bella = bella;
			bellaDollCarrier._seat = val;
			bellaDollCarrier._physical = val3.GetComponent<PhysGrabObject>();
			bellaDollCarrier._body = val3.GetComponent<Rigidbody>();
			bellaDollCarrier._clown = val3.GetComponent<ClownTrap>();
			bellaDollCarrier._seatRotationOffset = Quaternion.Inverse(val.rotation) * Quaternion.Euler(0f, bella.followTargetTransform.eulerAngles.y, 0f);
			bellaDollCarrier.MeasureBottom();
			bellaDollCarrier.Pin();
			return bellaDollCarrier;
		}

		private IEnumerator Start()
		{
			yield return null;
			if (_released)
			{
				yield break;
			}
			MeasureBottom();
			Pin();
			_physical.Teleport(((Component)this).transform.position, ((Component)this).transform.rotation);
			while (!_released && !_physical.dead)
			{
				if (NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_bella)) && _sequence.TryAdvance(!((Trap)_clown).trapTriggered))
				{
					_clown.TouchNose();
				}
				yield return null;
			}
		}

		internal void Warning(int stage)
		{
			_sequence.ObserveWarning(stage);
		}

		private void LateUpdate()
		{
			if (!_released && SemiFunc.IsMasterClientOrSingleplayer())
			{
				if ((Object)(object)_bella == (Object)null)
				{
					NetworkLifetime.Remove(((Component)this).gameObject);
				}
				else if (_physical.dead)
				{
					_sequence.Stop();
					Object.Destroy((Object)(object)this);
				}
				else
				{
					Pin();
				}
			}
		}

		private void MeasureBottom()
		{
			//IL_0028: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float num = float.PositiveInfinity;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (val is MeshRenderer || val is SkinnedMeshRenderer)
				{
					float num2 = num;
					Bounds bounds = val.bounds;
					num = Mathf.Min(num2, ((Bounds)(ref bounds)).min.y);
				}
			}
			_bottomOffset = (float.IsPositiveInfinity(num) ? 0f : (num - ((Component)this).transform.position.y));
		}

		private void Pin()
		{
			//IL_0077: 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_008d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_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_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)
			_physical.OverrideKinematic(0.2f);
			_physical.OverrideGrabDisable(0.2f);
			_body.detectCollisions = false;
			_body.interpolation = (RigidbodyInterpolation)0;
			bool flag = NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_bella));
			if (!flag)
			{
				_physical.OverrideDeactivate(0.2f);
			}
			Vector3 val = (flag ? (_seat.position + Vector3.up * (0.03f - _bottomOffset)) : AssetManager.instance.physDisabledPosition);
			Quaternion val2 = _seat.rotation * _seatRotationOffset;
			((Component)this).transform.SetPositionAndRotation(val, val2);
			_body.position = val;
			_body.rotation = val2;
			if (flag)
			{
				_lastPosition = val;
				_lastRotation = val2;
			}
		}

		internal void Release()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!_released)
			{
				_released = true;
				_sequence.Stop();
				_body.detectCollisions = true;
				_body.interpolation = (RigidbodyInterpolation)1;
				_physical.Teleport(_lastPosition, _lastRotation);
				Object.Destroy((Object)(object)this);
			}
		}
	}
	[HarmonyPatch(typeof(ParticleScriptExplosion), "Spawn")]
	internal static class BellaDollExplosionOwnerPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ParticleScriptExplosion __instance, ParticlePrefabExplosion __result)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)__result == (Object)null))
			{
				BellaDollCarrier component = ((Component)__instance).GetComponent<BellaDollCarrier>();
				Enemy val = (((Object)(object)component != (Object)null) ? component.ExplosionOwner : null);
				if (!((Object)(object)val == (Object)null))
				{
					__result.HurtCollider.enemyHost = val;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStartedRPC")]
	internal static class BellaPinnedDollNetworkGrabPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabObject __instance)
		{
			BellaDollCarrier component = ((Component)__instance).GetComponent<BellaDollCarrier>();
			if (component != null)
			{
				return !component.IsPinned;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")]
	internal static class BellaPinnedDollSoloGrabPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabObject __instance)
		{
			BellaDollCarrier component = ((Component)__instance).GetComponent<BellaDollCarrier>();
			if (component != null)
			{
				return !component.IsPinned;
			}
			return true;
		}
	}
	internal sealed class BirthdayBoyAbilities : MonoBehaviour
	{
		private static readonly MethodInfo RemoveBalloon = AccessTools.Method(typeof(EnemyBirthdayBoy), "RemoveBalloon", (Type[])null, (Type[])null);

		private static readonly MethodInfo UpdateTarget = AccessTools.Method(typeof(EnemyBirthdayBoy), "UpdatePlayerTarget", (Type[])null, (Type[])null);

		private EnemyBirthdayBoy _birthday;

		private EnemyHealth _health;

		private readonly BirthdayBalloonRewards<Vector3> _rewards = new BirthdayBalloonRewards<Vector3>();

		private readonly Dictionary<Vector3, BalloonProximityClock> _proximity = new Dictionary<Vector3, BalloonProximityClock>();

		private Vector3? _forcedKey;

		private BalloonPopCause _forcedCause;

		private PlayerAvatar? _forcedTarget;

		private bool _shareAttackTarget;

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			_birthday = ((Component)this).GetComponentInChildren<EnemyBirthdayBoy>(true);
			_health = ((Component)_birthday).GetComponent<EnemyHealth>();
			foreach (KeyValuePair<Vector3, GameObject> balloon in _birthday.balloons)
			{
				Register(balloon.Key);
			}
		}

		internal void Register(Vector3 key)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			_rewards.Register(key);
			_proximity[key] = new BalloonProximityClock();
		}

		internal void NewLife()
		{
			_rewards.NewLife();
		}

		internal void BeginDeath()
		{
			_rewards.BeginDeath();
		}

		private void Update()
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel())
			{
				return;
			}
			if (!NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_birthday)) || NativeEnemy.Health.Invoke(_health) <= 0 || NativeEnemy.Dead.Invoke(_health))
			{
				foreach (BalloonProximityClock value2 in _proximity.Values)
				{
					value2.Observe(Time.time, playerInRange: false);
				}
				return;
			}
			foreach (KeyValuePair<Vector3, GameObject> item in new List<KeyValuePair<Vector3, GameObject>>(_birthday.balloons))
			{
				if ((Object)(object)item.Value == (Object)null || !_proximity.TryGetValue(item.Key, out BalloonProximityClock value))
				{
					continue;
				}
				BirthdayBoyBalloon componentInChildren = item.Value.GetComponentInChildren<BirthdayBoyBalloon>();
				PlayerAvatar val = null;
				float num = 9f;
				if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.popped && componentInChildren.collider1.enabled && componentInChildren.collider2.enabled)
				{
					foreach (PlayerAvatar item2 in SemiFunc.PlayerGetList())
					{
						if (!((Object)(object)item2 == (Object)null) && !item2.isDisabled && !item2.deadSet)
						{
							Vector3 val2 = ((Component)item2).transform.position - componentInChildren.moveTransform.position;
							float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
							if (sqrMagnitude <= num)
							{
								num = sqrMagnitude;
								val = item2;
							}
						}
					}
				}
				if (value.Observe(Time.time, (Object)(object)val != (Object)null))
				{
					Pop(item.Key, BalloonPopCause.Automatic, val);
				}
			}
		}

		private void Pop(Vector3 key, BalloonPopCause cause, PlayerAvatar? target, bool shareAttackTarget = false)
		{
			//IL_0001: 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)
			_forcedKey = key;
			_forcedCause = cause;
			_forcedTarget = target;
			_shareAttackTarget = shareAttackTarget;
			try
			{
				int num = DifficultyRules.BirthdayBalloonTier(DifficultyService.Current);
				if (cause == BalloonPopCause.Automatic && num >= 2 && (Object)(object)target != (Object)null)
				{
					UpdateTarget.Invoke(_birthday, new object[1] { target });
				}
				RemoveBalloon.Invoke(_birthday, new object[2]
				{
					key,
					cause == BalloonPopCause.Damage || num < 2
				});
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Birthday Boy balloon pop failed: {arg}");
			}
			finally
			{
				_forcedKey = null;
				_forcedTarget = null;
				_shareAttackTarget = false;
			}
		}

		private static PlayerAvatar? NearestPlayer(Vector3 position)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			PlayerAvatar result = null;
			float num = 100f;
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!((Object)(object)item == (Object)null) && !item.isDisabled && !item.deadSet)
				{
					Vector3 val = ((Component)item).transform.position - position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (DifficultyRules.BirthdayBalloonInRange(sqrMagnitude) && sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = item;
					}
				}
			}
			return result;
		}

		internal void Damaged()
		{
			//IL_001f: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if (!NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)_birthday)))
			{
				return;
			}
			Vector3 val = NativeEnemy.Position((Component)(object)_birthday);
			PlayerAvatar val2 = _birthday.playerTarget;
			if ((Object)(object)val2 != (Object)null && (val2.isDisabled || val2.deadSet))
			{
				val2 = null;
			}
			BirthdayBoyAbilities[] array = Object.FindObjectsOfType<BirthdayBoyAbilities>();
			foreach (BirthdayBoyAbilities birthdayBoyAbilities in array)
			{
				if (NativeEnemy.Health.Invoke(birthdayBoyAbilities._health) <= 0 || NativeEnemy.Dead.Invoke(birthdayBoyAbilities._health))
				{
					continue;
				}
				foreach (KeyValuePair<Vector3, GameObject> item in new List<KeyValuePair<Vector3, GameObject>>(birthdayBoyAbilities._birthday.balloons))
				{
					if (!((Object)(object)item.Value == (Object)null))
					{
						BirthdayBoyBalloon componentInChildren = item.Value.GetComponentInChildren<BirthdayBoyBalloon>();
						Vector3 val3 = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.moveTransform.position : item.Value.transform.position);
						Vector3 val4 = val3 - val;
						if (DifficultyRules.BirthdayBalloonInRange(((Vector3)(ref val4)).sqrMagnitude))
						{
							birthdayBoyAbilities.Pop(item.Key, BalloonPopCause.Damage, (PlayerAvatar?)(((Object)(object)val2 != (Object)null) ? ((object)val2) : ((object)NearestPlayer(val3))), (Object)(object)val2 != (Object)null);
						}
					}
				}
			}
		}

		internal void Removed(Vector3 key, bool physicalPop)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if (!_birthday.balloons.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			if (NativeEnemy.Health.Invoke(_health) <= 0 || NativeEnemy.Dead.Invoke(_health))
			{
				BeginDeath();
			}
			BirthdayBoyBalloon componentInChildren = value.GetComponentInChildren<BirthdayBoyBalloon>();
			bool flag = _forcedKey.HasValue && _forcedKey.Value == key;
			BalloonPopCause cause = (flag ? _forcedCause : (physicalPop ? (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.popper != (Object)null) ? BalloonPopCause.Player : BalloonPopCause.Physical) : BalloonPopCause.Other));
			Vector3 position = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.moveTransform.position : value.transform.position);
			PlayerAvatar val = NearestPlayer(position);
			int tier = DifficultyRules.BirthdayBalloonTier(DifficultyService.Current);
			BalloonReward balloonReward = _rewards.Remove(key, cause, (Object)(object)val != (Object)null, tier);
			_proximity.Remove(key);
			if (balloonReward == BalloonReward.None)
			{
				return;
			}
			try
			{
				PlayerAvatar target = (PlayerAvatar)(flag ? ((object)_forcedTarget) : ((object)val));
				BirthdayBalloonSpawn.Emit(balloonReward, position, target, flag && _shareAttackTarget);
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Birthday Boy balloon reward failed: {arg}");
			}
		}

		internal void RemovingAll()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			bool flag = NativeEnemy.Health.Invoke(_health) <= 0 || NativeEnemy.Dead.Invoke(_health);
			foreach (Vector3 item in new List<Vector3>(_birthday.balloons.Keys))
			{
				if (flag)
				{
					Removed(item, physicalPop: false);
					continue;
				}
				_rewards.Remove(item, BalloonPopCause.Other, playerNearby: false, 0);
				_proximity.Remove(item);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyBirthdayBoy), "SpawnBalloonRPC")]
	internal static class BirthdayBalloonCreatedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyBirthdayBoy __instance, Vector3 _keyPos, PhotonMessageInfo _info)
		{
			//IL_0007: 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)
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.MasterOnlyRPC(_info))
			{
				StageRuntime.TryAttach(NativeEnemy.Parent((Component)(object)__instance));
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.Register(_keyPos);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyBirthdayBoy), "RemoveBalloonRPC")]
	internal static class BirthdayBalloonRemovedPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyBirthdayBoy __instance, Vector3 _position, bool _global, PhotonMessageInfo _info)
		{
			//IL_0007: 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)
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.MasterOnlyRPC(_info))
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.Removed(_position, _global);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyBirthdayBoy), "PopAllBalloonsRPC")]
	internal static class BirthdayBalloonsDeathCleanupPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyBirthdayBoy __instance, PhotonMessageInfo _info)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.MasterOnlyRPC(_info))
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.RemovingAll();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Hurt")]
	internal static class BirthdayDamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance, out int __state)
		{
			__state = -1;
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)((Component)__instance).GetComponent<EnemyBirthdayBoy>() != (Object)null)
			{
				__state = NativeEnemy.Health.Invoke(__instance);
			}
		}

		[HarmonyPostfix]
		private static void Postfix(EnemyHealth __instance, int __state)
		{
			if (__state >= 0 && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel() && DifficultyRules.BirthdayDamageTriggers(__state, NativeEnemy.Health.Invoke(__instance), DifficultyRules.BirthdayBalloonTier(DifficultyService.Current)))
			{
				StageRuntime.TryAttach(NativeEnemy.Parent((Component)(object)__instance));
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.Damaged();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class BirthdayDeathStartPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)__instance).GetComponent<EnemyBirthdayBoy>() == (Object)null))
			{
				StageRuntime.TryAttach(NativeEnemy.Parent((Component)(object)__instance));
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.BeginDeath();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyBirthdayBoy), "OnSpawn")]
	internal static class BirthdayNewLifePatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyBirthdayBoy __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BirthdayBoyAbilities>()?.NewLife();
			}
		}
	}
	internal sealed class BlindAbility : MonoBehaviour
	{
		private static readonly FieldRef<EnemyThinMan, PlayerAvatar> ChildTarget = AccessTools.FieldRefAccess<EnemyThinMan, PlayerAvatar>("playerTarget");

		private readonly BlindTargetClock _clock = new BlindTargetClock();

		private EnemyParent _parent;

		private EnemyHealth _health;

		private EnemyThinMan? _child;

		private bool _loggedError;

		private void Awake()
		{
			_parent = ((Component)this).GetComponent<EnemyParent>();
			_health = ((Component)this).GetComponentInChildren<EnemyHealth>(true);
			_child = ((Component)this).GetComponentInChildren<EnemyThinMan>(true);
		}

		internal void NewLife()
		{
			_clock.Reset();
			_loggedError = false;
		}

		private void OnDisable()
		{
			NewLife();
		}

		private void Update()
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || !BlindTargetClock.Unlocked(DifficultyService.Current) || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated || !NativeEnemy.Spawned.Invoke(_parent) || (Object)(object)_health == (Object)null || NativeEnemy.Dead.Invoke(_health) || NativeEnemy.Health.Invoke(_health) <= 0)
			{
				_clock.Reset();
				return;
			}
			PlayerAvatar val = (((Object)(object)_child != (Object)null) ? ChildTarget.Invoke(_child) : null);
			if ((Object)(object)val == (Object)null || val.isDisabled || val.deadSet || (Object)(object)val.PlayerVisionTarget == (Object)null || (Object)(object)val.PlayerVisionTarget.VisionTransform == (Object)null)
			{
				_clock.Reset();
			}
			else
			{
				if (!_clock.TryCast(Time.time, val))
				{
					return;
				}
				try
				{
					AnimalGas.Emit(val.PlayerVisionTarget.VisionTransform.position);
					_loggedError = false;
				}
				catch (Exception arg)
				{
					if (!_loggedError)
					{
						Plugin.ModLogger.LogError((object)$"Blind gas failed; retrying next interval: {arg}");
					}
					_loggedError = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyThinMan), "OnSpawn")]
	internal static class BlindNewLifePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Component __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				((Component)NativeEnemy.Parent(__instance)).GetComponent<BlindAbility>()?.NewLife();
			}
		}
	}
	internal sealed class BowtieBrothers : MonoBehaviour
	{
		private static readonly FieldRef<EnemyBowtie, PlayerAvatar> Target = AccessTools.FieldRefAccess<EnemyBowtie, PlayerAvatar>("playerTarget");

		private readonly BowtieWindCycle _cycle = new BowtieWindCycle();

		private readonly BowtieRevengeTrigger _revenge = new BowtieRevengeTrigger();

		private EnemyBowtie _bowtie;

		private BowtieBrother? _brother;

		private void Awake()
		{
			_bowtie = ((Component)this).GetComponentInChildren<EnemyBowtie>(true);
			HurtCollider[] componentsInChildren = ((Component)this).GetComponentsInChildren<HurtCollider>(true);
			foreach (HurtCollider val in componentsInChildren)
			{
				if (!((Component)val).transform.IsChildOf(_bowtie.hurtColliderLeave))
				{
					BowtieWindSource bowtieWindSource = ((Component)val).gameObject.GetComponent<BowtieWindSource>();
					if ((Object)(object)bowtieWindSource == (Object)null)
					{
						bowtieWindSource = ((Component)val).gameObject.AddComponent<BowtieWindSource>();
					}
					bowtieWindSource.Summoner = ((Component)this).GetComponent<EnemyParent>();
				}
			}
		}

		private void Update()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			_cycle.Observe((int)_bowtie.currentState == 5);
		}

		internal void NewLife()
		{
			_revenge.NewLife();
		}

		internal void WindStarted()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)_bowtie.currentState != 5 || !NativeEnemy.Spawned.Invoke(((Component)this).GetComponent<EnemyParent>()))
			{
				return;
			}
			EnemyHealth component = ((Component)_bowtie).GetComponent<EnemyHealth>();
			PlayerAvatar val = Target.Invoke(_bowtie);
			if (NativeEnemy.Health.Invoke(component) <= 0 || NativeEnemy.Dead.Invoke(component) || (Object)(object)val == (Object)null || val.isDisabled || val.deadSet || !_cycle.TrySummon(hasTarget: true))
			{
				return;
			}
			try
			{
				Summon(((Component)val).transform.position, val);
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Bowtie Brothers summon failed: {arg}");
			}
		}

		private void Summon(Vector3 origin, PlayerAvatar? target, bool revenge = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			NavMeshHit val = default(NavMeshHit);
			if (!NavMesh.SamplePosition(origin, ref val, 3f, -1))
			{
				throw new InvalidOperationException($"No walkable Elsa spawn near {origin}.");
			}
			if ((Object)(object)_brother != (Object)null)
			{
				_brother.Retire();
			}
			_brother = BowtieBrother.Create(((Component)this).GetComponent<EnemyParent>(), ((NavMeshHit)(ref val)).position, target, revenge);
		}

		internal void Died(PlayerAvatar? killer)
		{
			//IL_0038: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (_revenge.TryQueue(DifficultyService.Current))
			{
				StageRuntime current = StageRuntime.Current;
				if ((Object)(object)current == (Object)null)
				{
					Plugin.ModLogger.LogError((object)"Cannot schedule Bowtie revenge without an active stage.");
					return;
				}
				Vector3 position = NativeEnemy.Position((Component)(object)_bowtie);
				((MonoBehaviour)current).StartCoroutine(RevengeAfterDelay(current, position, killer));
			}
		}

		private IEnumerator RevengeAfterDelay(StageRuntime stage, Vector3 position, PlayerAvatar? killer)
		{
			//IL_0015: 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)
			yield return (object)new WaitForSeconds(0.5f);
			if ((Object)(object)this == (Object)null || (Object)(object)StageRuntime.Current != (Object)(object)stage || !SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				yield break;
			}
			PlayerAvatar target = (ValidTarget(killer) ? killer : NearestPlayer(position));
			try
			{
				Summon(position, target, revenge: true);
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Bowtie revenge summon failed: {arg}");
			}
		}

		private static bool ValidTarget(PlayerAvatar? player)
		{
			if ((Object)(object)player != (Object)null && !player.isDisabled)
			{
				return !player.deadSet;
			}
			return false;
		}

		internal static PlayerAvatar? NearestPlayer(Vector3 position)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			PlayerAvatar result = null;
			float num = float.PositiveInfinity;
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (ValidTarget(item))
				{
					Vector3 val = ((Component)item).transform.position - position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = item;
					}
				}
			}
			return result;
		}
	}
	internal sealed class BowtieBrother : MonoBehaviour
	{
		private static readonly FieldRef<EnemyElsa, PlayerAvatar> ElsaTarget = AccessTools.FieldRefAccess<EnemyElsa, PlayerAvatar>("playerTarget");

		private static readonly MethodInfo UpdateState = AccessTools.Method(typeof(EnemyElsa), "UpdateState", (Type[])null, (Type[])null);

		private static readonly MethodInfo ShrinkState = AccessTools.Method(typeof(EnemyElsa), "StateTransformBigToSmall", (Type[])null, (Type[])null);

		private static readonly MethodInfo DespawnState = AccessTools.Method(typeof(EnemyElsa), "StateDespawnSmall", (Type[])null, (Type[])null);

		private readonly BowtieBrotherLife _life = new BowtieBrotherLife();

		private EnemyParent _parent;

		private EnemyElsa _elsa;

		private EnemyHealth _health;

		private PlayerAvatar? _target;

		private bool _chooseFallbackOnSpawn;

		private int _despawnFrame = -1;

		internal EnemyParent Summoner;

		internal bool Retired => _life.Retired;

		private void Awake()
		{
			_parent = ((Component)this).GetComponent<EnemyParent>();
			_elsa = ((Component)this).GetComponentInChildren<EnemyElsa>(true);
			_health = ((Component)_elsa).GetComponent<EnemyHealth>();
		}

		internal static BowtieBrother Create(EnemyParent summoner, Vector3 position, PlayerAvatar? target, bool chooseFallbackOnSpawn = false)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			EnemyParent val = SummonedEnemySpawnTicket.Create(((PrefabRef<GameObject>)(object)VanillaCatalog.ElsaPrefab()).ResourcePath, position);
			BowtieBrother bowtieBrother = ((Component)val).gameObject.AddComponent<BowtieBrother>();
			bowtieBrother.Summoner = summoner;
			bowtieBrother._target = target;
			bowtieBrother._chooseFallbackOnSpawn = chooseFallbackOnSpawn;
			bowtieBrother._health.spawnValuable = false;
			return bowtieBrother;
		}

		internal void Born()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (_life.Retired)
			{
				return;
			}
			_life.Start(Time.time);
			_health.spawnValuable = false;
			if (_chooseFallbackOnSpawn && ((Object)(object)_target == (Object)null || _target.isDisabled || _target.deadSet))
			{
				_target = BowtieBrothers.NearestPlayer(NativeEnemy.Position((Component)(object)_elsa));
			}
			if ((Object)(object)_target == (Object)null || _target.isDisabled || _target.deadSet)
			{
				Retire();
				return;
			}
			ElsaTarget.Invoke(_elsa) = _target;
			if (SemiFunc.IsMultiplayer())
			{
				((Component)_elsa).GetComponent<PhotonView>().RPC("UpdatePlayerTargetRPC", (RpcTarget)0, new object[1] { _target.photonView.ViewID });
			}
			SetState((State)24);
		}

		private void Update()
		{
			TickLife();
		}

		internal void TickLife()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && _life.Started && !_life.Retired)
			{
				if (NativeEnemy.Health.Invoke(_health) <= 0 || NativeEnemy.Dead.Invoke(_health))
				{
					_health.spawnValuable = false;
					_life.Retire();
				}
				else if (_life.Expire(Time.time))
				{
					BeginDespawn();
				}
				else if ((Object)(object)_target == (Object)null || _target.isDisabled || _target.deadSet)
				{
					Retire();
				}
			}
		}

		internal void Retire()
		{
			if (!_life.Retired)
			{
				_life.Retire();
				BeginDespawn();
			}
		}

		private void BeginDespawn()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			_health.spawnValuable = false;
			if (_life.Started && NativeEnemy.Spawned.Invoke(_parent) && NativeEnemy.Health.Invoke(_health) > 0)
			{
				_elsa.enemy.CurrentState = (EnemyState)11;
				_elsa.enemy.NavMeshAgent.ResetPath();
				DriveDespawn();
			}
		}

		internal void DriveDespawn()
		{
			if (_despawnFrame != Time.frameCount)
			{
				_despawnFrame = Time.frameCount;
				if (_elsa.IsBig())
				{
					SetState((State)25);
					ShrinkState.Invoke(_elsa, null);
				}
				else
				{
					SetState((State)17);
					DespawnState.Invoke(_elsa, null);
				}
			}
		}

		private void SetState(State state)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			UpdateState.Invoke(_elsa, new object[1] { state });
		}
	}
	internal sealed class BowtieWindSource : MonoBehaviour
	{
		internal EnemyParent Summoner;
	}
	[HarmonyPatch(typeof(HurtCollider), "EnemyHurt")]
	internal static class BowtieBrotherWindImmunityPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(HurtCollider __instance, Enemy _enemy, ref bool __result)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)_enemy == (Object)null)
			{
				return true;
			}
			BowtieWindSource component = ((Component)__instance).GetComponent<BowtieWindSource>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			BowtieBrother componentInParent = ((Component)_enemy).GetComponentInParent<BowtieBrother>();
			if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.Summoner == (Object)null || (Object)(object)componentInParent.Summoner != (Object)(object)component.Summoner)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyBowtieAnim), "YellStart")]
	internal static class BowtieWindStartedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyBowtieAnim __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				EnemyParent val = NativeEnemy.Parent((Component)(object)__instance.controller);
				StageRuntime.TryAttach(val);
				((Component)val).GetComponent<BowtieBrothers>()?.WindStarted();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class BowtieRevengeDeathPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && DifficultyRules.BowtieRevengeUnlocked(DifficultyService.Current) && !((Object)(object)((Component)__instance).GetComponent<EnemyBowtie>() == (Object)null))
			{
				EnemyParent val = NativeEnemy.Parent((Component)(object)__instance);
				StageRuntime.TryAttach(val);
				((Component)val).GetComponent<BowtieBrothers>()?.Died(EnemyDamageSource.Current);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyBowtie), "OnSpawn")]
	internal static class BowtieRevengeNewLifePatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyBowtie __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BowtieBrothers>()?.NewLife();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyElsa), "Update")]
	internal static class BowtieBrotherDespawnPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyElsa __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			BowtieBrother component = ((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<BowtieBrother>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.TickLife();
			if (!component.Retired || NativeEnemy.Health.Invoke(((Component)__instance).GetComponent<EnemyHealth>()) <= 0)
			{
				return true;
			}
			if (NativeEnemy.Spawned.Invoke(NativeEnemy.Parent((Component)(object)__instance)))
			{
				component.DriveDespawn();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class BowtieBrotherNoOrbPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)((Component)__instance).GetComponentInParent<BowtieBrother>() != (Object)null)
			{
				__instance.spawnValuable = false;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "Spawn")]
	internal static class BowtieBrotherNoRespawnPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyParent __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			BowtieBrother component = ((Component)__instance).GetComponent<BowtieBrother>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			SummonedEnemySpawnTicket component2 = ((Component)__instance).GetComponent<SummonedEnemySpawnTicket>();
			if (!component.Retired && (Object)(object)component2 != (Object)null && component2.Pending)
			{
				return true;
			}
			__instance.DespawnedTimerSet(1f, false);
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyGnomeDirector), "StateAttackSet")]
	internal static class ChefFrogGnomeTarget
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				yield return instruction;
				if (instruction.operand is MethodInfo { Name: "GetComponentInParent", IsGenericMethod: not false } methodInfo && methodInfo.GetGenericArguments()[0] == typeof(ValuableObject))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ChefFrogGnomeTarget), "Eligible", (Type[])null, (Type[])null));
				}
			}
		}

		private static ValuableObject? Eligible(ValuableObject? candidate)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !ChefMimicFrog.BlocksTarget((Component?)(object)candidate))
			{
				return candidate;
			}
			return null;
		}
	}
	internal sealed class ChefMimic : MonoBehaviour
	{
		private static readonly MethodInfo UpdateState = AccessTools.Method(typeof(EnemyTumbler), "UpdateState", (Type[])null, (Type[])null);

		private static readonly MethodInfo Death = AccessTools.Method(typeof(EnemyHealth), "Death", (Type[])null, (Type[])null);

		private static readonly FieldRef<EnemyParent, float> ValuableSpawnTimer = AccessTools.FieldRefAccess<EnemyParent, float>("valuableSpawnTimer");

		private readonly ChefMimicState _state = new ChefMimicState();

		private readonly ChefVitality _vitality = new ChefVitality();

		private EnemyParent _parent;

		private EnemyTumbler _chef;

		private EnemyUpscream? _upscream;

		private Enemy _enemy;

		private EnemyHealth _health;

		private ChefMimicFrog? _frog;

		private PlayerAvatar? _target;

		private Vector3 _revealPosition;

		private int _savedHealth;

		private bool _pursuingBeforeUpdate;

		internal bool Disguised => _state.Mode == ChefMimicMode.Disguised;

		internal bool Revealing => _state.Mode == ChefMimicMode.Revealing;

		internal bool Restoring
		{
			get
			{
				bool revealing = Revealing;
				bool flag = revealing;
				if (!flag)
				{
					ChefMimicMode mode = _state.Mode;
					bool flag2 = (uint)(mode - 4) <= 1u;
					flag = flag2;
				}
				return flag;
			}
		}

		private bool NativePassive
		{
			get
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				if ((Object)(object)_upscream != (Object)null)
				{
					State currentState = _upscream.currentState;
					return (currentState - 1 <= 2 || currentState - 7 <= 1) ? true : false;
				}
				return Passive(_chef.currentState);
			}
		}

		private bool NativeRoaming
		{
			get
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Invalid comparison between Unknown and I4
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				if ((Object)(object)_upscream != (Object)null)
				{
					State currentState = _upscream.currentState;
					return currentState - 1 <= 1;
				}
				State currentState2 = _chef.currentState;
				return currentState2 - 1 <= 1;
			}
		}

		private bool NativePursuing
		{
			get
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Invalid comparison between Unknown and I4
				if (!((Object)(object)_upscream != (Object)null))
				{
					return (int)_chef.currentState == 5;
				}
				return (int)_upscream.currentState == 5;
			}
		}

		private bool UpscreamPursuitEnded
		{
			get
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Invalid comparison between Unknown and I4
				if ((Object)(object)_upscream != (Object)null)
				{
					return (int)_upscream.currentState == 7;
				}
				return false;
			}
		}

		internal bool Attacking => _state.Mode == ChefMimicMode.Attacking;

		private void Awake()
		{
			_parent = ((Component)this).GetComponent<EnemyParent>();
			_chef = ((Component)this).GetComponentInChildren<EnemyTumbler>(true);
			_upscream = ((Component)this).GetComponentInChildren<EnemyUpscream>(true);
			_enemy = ((Component)this).GetComponentInChildren<Enemy>(true);
			_health = ((Component)_enemy).GetComponent<EnemyHealth>();
		}

		private void Update()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel() && !((Object)(object)_frog == (Object)null) && _state.TryDisguiseScan(Time.time))
			{
				Vector3 position = ((Component)_frog).transform.position;
				if (_state.ReturnIfUnseen(Time.time, HasVisiblePlayer(position + Vector3.up * 0.25f, position)))
				{
					SaveRevealPosition(position);
					ChefMimicFrog frog = _frog;
					_frog = null;
					_target = null;
					frog.RemoveQuietly();
					Restore();
				}
			}
		}

		internal void Tick()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			_pursuingBeforeUpdate = false;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel())
			{
				return;
			}
			if (NativeEnemy.Health.Invoke(_health) <= 0 || NativeEnemy.Dead.Invoke(_health))
			{
				Cleanup();
			}
			else
			{
				if (!NativeEnemy.Spawned.Invoke(_parent))
				{
					return;
				}
				if (_state.Mode == ChefMimicMode.Attacking)
				{
					if (_state.ShouldReleaseTarget(Valid(_target), UpscreamPursuitEnded))
					{
						ReturnToRoam();
						return;
					}
					if (NativePassive)
					{
						ResumePursuit();
					}
					_pursuingBeforeUpdate = NativePursuing;
				}
				else if (_state.TryScan(Time.time, NativeRoaming))
				{
					Vector3 position = _enemy.Vision.VisionTransform.position;
					if (HasVisiblePlayer(position, NativeEnemy.Position((Component)(object)_enemy)))
					{
						Disguise();
					}
				}
			}
		}

		internal void AfterNativeTick()
		{
			if (_state.ShouldReleaseTarget(Valid(_target), UpscreamPursuitEnded || (_pursuingBeforeUpdate && NativePassive)))
			{
				ReturnToRoam();
			}
		}

		internal float FrogValue(float original)
		{
			return (float)_vitality.FrogValue(original);
		}

		internal bool CaptureFrog(float change, float original)
		{
			_vitality.ApplyFrogChange(change, original);
			_savedHealth = _vitality.BodyHealth(_health.health);
			NativeEnemy.Health.Invoke(_health) = _savedHealth;
			return _savedHealth <= 0;
		}

		private bool HasVisiblePlayer(Vector3 origin, Vector3 rangeOrigin)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!Valid(item))
				{
					continue;
				}
				Vector3 val = ((Component)item).transform.position - rangeOrigin;
				if (ChefMimicState.InRange(((Vector3)(ref val)).sqrMagnitude))
				{
					Vector3 position = item.PlayerVisionTarget.VisionTransform.position;
					if (Unobstructed(origin, position, item))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool Valid(PlayerAvatar? player)
		{
			if ((Object)(object)player != (Object)null && !player.isDisabled)
			{
				return !player.deadSet;
			}
			return false;
		}

		private bool Unobstructed(Vector3 origin, Vector3 destination, PlayerAvatar player)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = destination - origin;
			RaycastHit[] array = Physics.RaycastAll(origin, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if (((RaycastHit)(ref val2)).transform.IsChildOf(((Component)_parent).transform) || ((Object)(object)_frog != (Object)null && ((RaycastHit)(ref val2)).transform.IsChildOf(((Component)_frog).transform)) || (Object)(object)((Component)((RaycastHit)(ref val2)).transform).GetComponentInParent<PlayerAvatar>() == (Object)(object)player)
				{
					continue;
				}
				PlayerTumble componentInParent = ((Component)((RaycastHit)(ref val2)).transform).GetComponentInParent<PlayerTumble>();
				if (componentInParent == null || !((Object)(object)componentInParent.playerAvatar == (Object)(object)player))
				{
					PlayerController componentInParent2 = ((Component)((RaycastHit)(ref val2)).transform).GetComponentInParent<PlayerController>();
					if (componentInParent2 == null || !((Object)(object)componentInParent2.playerAvatarScript == (Object)(object)player))
					{
						return false;
					}
				}
			}
			return true;
		}

		private static bool Passive(State state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if (state - 1 <= 1 || (int)state == 4 || (int)state == 10)
			{
				return true;
			}
			return false;
		}

		private void ResumePursuit()
		{
			if ((Object)(object)_upscream != (Object)null)
			{
				_upscream.UpdateState((State)5);
			}
			else
			{
				SetState((State)5);
			}
		}

		private void Disguise()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (_state.Mode != ChefMimicMode.Roaming)
			{
				return;
			}
			try
			{
				Vector3 val = NativeEnemy.Position((Component)(object)_enemy);
				NavMeshHit val2 = default(NavMeshHit);
				if (NavMesh.SamplePosition(val, ref val2, 2f, -1))
				{
					val = ((NavMeshHit)(ref val2)).position;
				}
				string prefabPath = (((Object)(object)_upscream != (Object)null) ? VanillaCatalog.RandomUpscreamDisguisePath() : ((PrefabRef<GameObject>)(object)VanillaCatalog.Valuable((GameObject p) => (Object)(object)p.GetComponent<FrogTrap>() != (Object)null)).ResourcePath);
				_savedHealth = NativeEnemy.Health.Invoke(_health);
				_vitality.CaptureBody(_savedHealth, _health.health);
				_revealPosition = val;
				_frog = ChefMimicFrog.Create(prefabPath, val, ((Component)this).transform.rotation, this);
				_state.Disguise();
				_parent.Despawn();
			}
			catch (Exception arg)
			{
				Cleanup();
				Plugin.ModLogger.LogError((object)$"{((Object)_enemy).name} disguise failed: {arg}");
			}
		}

		internal void Grabbed(ChefMimicFrog frog, PhysGrabber grabber)
		{
			if (!((Object)(object)frog != (Object)(object)_frog) && Valid(grabber.playerAvatar) && _state.Reveal())
			{
				_target = grabber.playerAvatar;
				((MonoBehaviour)this).StartCoroutine(RevealAfterGrab(frog));
			}
		}

		private IEnumerator RevealAfterGrab(ChefMimicFrog frog)
		{
			yield return null;
			if (Revealing && !((Object)(object)_frog != (Object)(object)frog) && !((Object)(object)frog == (Object)null))
			{
				SaveRevealPosition(((Component)frog).transform.position);
				_frog = null;
				frog.RemoveQuietly();
				Restore();
			}
		}

		internal void Destroyed(ChefMimicFrog frog)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)frog != (Object)(object)_frog) && _state.Defeat())
			{
				SaveRevealPosition(((Component)frog).transform.position);
				_frog = null;
				_target = null;
				((MonoBehaviour)this).StartCoroutine(DefeatAfterBreak());
			}
		}

		private IEnumerator DefeatAfterBreak()
		{
			yield return null;
			if (_state.Mode == ChefMimicMode.Defeating)
			{
				Restore();
			}
		}

		private void SaveRevealPosition(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, 3f, -1))
			{
				_revealPosition = ((NavMeshHit)(ref val)).position;
			}
		}

		private void Restore()
		{
			try
			{
				NativeEnemy.Spawn(_parent);
			}
			catch (Exception arg)
			{
				_state.Roam(Time.time);
				_parent.DespawnedTimerSet(0f, false);
				Plugin.ModLogger.LogError((object)$"{((Object)_enemy).name} reveal failed: {arg}");
			}
		}

		internal void PlaceForReveal(Enemy enemy)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			enemy.EnemyTeleported(_revealPosition);
			NativeEnemy.FirstPointUsed.Invoke(_parent) = true;
		}

		internal void Spawned()
		{
			//IL_008a: 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)
			if (!Restoring)
			{
				_vitality.NewLife(NativeEnemy.Health.Invoke(_health), _health.health);
				_state.Roam(Time.time);
				return;
			}
			NativeEnemy.Health.Invoke(_health) = Math.Max(1, Math.Min(_health.health, _savedHealth));
			_enemy.NavMeshAgent.Enable();
			_enemy.NavMeshAgent.Warp(_revealPosition, true);
			_enemy.Rigidbody.GrabRelease(true, 0.1f);
			((Component)_enemy.Rigidbody).GetComponent<PhysGrabObject>().OverrideGrabDisable(0.5f);
			if (_state.Mode == ChefMimicMode.Defeating)
			{
				ValuableSpawnTimer.Invoke(_parent) = 10f;
				NativeEnemy.Health.Invoke(_health) = 0;
				Death.Invoke(_health, new object[1] { Vector3.zero });
				return;
			}
			if (_state.Mode == ChefMimicMode.ReturningToRoam)
			{
				ReturnToRoam();
				return;
			}
			_state.Attack();
			if (!Valid(_target))
			{
				ReturnToRoam();
				return;
			}
			if ((Object)(object)_upscream != (Object)null)
			{
				_enemy.Vision.onVisionTriggeredPlayer = _target;
				_enemy.Vision.onVisionTriggeredID = _target.photonView.ViewID;
				_upscream.UpdateState((State)1);
				_upscream.OnVision();
				return;
			}
			_chef.targetPlayer = _target;
			if (SemiFunc.IsMultiplayer())
			{
				((Component)_chef).GetComponent<PhotonView>().RPC("TargetPlayerRPC", (RpcTarget)0, new object[1] { _target.photonView.ViewID });
			}
			SetState((State)3);
		}

		internal bool AllowVision(EnemyTumbler chef)
		{
			if (_state.Mode == ChefMimicMode.Attacking && Valid(_target))
			{
				return (Object)(object)chef.enemy.Vision.onVisionTriggeredPlayer == (Object)(object)_target;
			}
			return false;
		}

		internal bool AllowUpscreamVision()
		{
			if (_state.Mode == ChefMimicMode.Attacking && Valid(_target))
			{
				return (Object)(object)_enemy.Vision.onVisionTriggeredPlayer == (Object)(object)_target;
			}
			return false;
		}

		private void ReturnToRoam()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			_target = null;
			if ((Object)(object)_upscream != (Object)null)
			{
				_upscream.targetPlayer = null;
				_state.Roam(Time.time);
				_upscream.UpdateState((State)2);
			}
			else
			{
				_chef.targetPlayer = null;
				_state.Roam(Time.time);
				State currentState = _chef.currentState;
				bool flag = currentState - 7 <= 2;
				SetState((State)(flag ? 9 : 2));
			}
		}

		private void SetState(State state)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			UpdateState.Invoke(_chef, new object[1] { state });
		}

		internal void Cleanup()
		{
			if ((Object)(object)_frog != (Object)null)
			{
				_frog.RemoveQuietly();
			}
			_frog = null;
			_target = null;
			_state.Roam(Time.time);
		}

		private void OnDestroy()
		{
			Cleanup();
		}
	}
	[HarmonyPatch(typeof(EnemyTumbler), "Update")]
	internal static class ChefMimicUpdatePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyTumbler __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			ChefMimic component = ((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<ChefMimic>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.Tick();
			if (!component.Disguised)
			{
				return !component.Restoring;
			}
			return false;
		}

		[HarmonyPostfix]
		private static void Postfix(EnemyTumbler __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<ChefMimic>()?.AfterNativeTick();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyTumbler), "OnVision")]
	internal static class ChefMimicVisionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyTumbler __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ChefMimic component = ((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<ChefMimic>();
				if (component != null)
				{
					return component.AllowVision(__instance);
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnemyTumbler), "OnGrabbed")]
	internal static class ChefMimicBodyGrabPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyTumbler __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ChefMimic component = ((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<ChefMimic>();
				if (component != null)
				{
					return component.Attacking;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "Spawn")]
	internal static class ChefMimicHiddenSpawnPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(EnemyParent __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ChefMimic component = ((Component)__instance).GetComponent<ChefMimic>();
				if (component != null && component.Disguised)
				{
					__instance.DespawnedTimerSet(1f, false);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "EnemySpawn")]
	internal static class ChefMimicRevealPositionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Enemy enemy, ref bool __result)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ChefMimic componentInParent = ((Component)enemy).GetComponentInParent<ChefMimic>();
				if (componentInParent != null && componentInParent.Restoring)
				{
					componentInParent.PlaceForReveal(enemy);
					__result = true;
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
	internal static class ChefMimicRevealedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyParent __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && NativeEnemy.Spawned.Invoke(__instance))
			{
				((Component)__instance).GetComponent<ChefMimic>()?.Spawned();
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth), "Death")]
	internal static class ChefMimicDeathPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyHealth __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && ((Object)(object)((Component)__instance).GetComponent<EnemyTumbler>() != (Object)null || (Object)(object)((Component)__instance).GetComponent<EnemyUpscream>() != (Object)null))
			{
				((Component)NativeEnemy.Parent((Component)(object)__instance)).GetComponent<ChefMimic>()?.Cleanup();
			}
		}
	}
	internal sealed class ChefMimicFrog : MonoBehaviour
	{
		private ChefMimic? _owner;

		private PhysGrabObject _physical;

		private ValuableObject _valuable;

		private bool _initialized;

		private float _lastFrogValue;

		private static readonly MethodInfo Heal = AccessTools.Method(typeof(PhysGrabObjectImpactDetector), "HealRPC", (Type[])null, (Type[])null);

		internal bool Active
		{
			get
			{
				if ((Object)(object)_owner != (Object)null)
				{
					if (!_owner.Disguised)
					{
						return _owner.Revealing;
					}
					return true;
				}
				return false;
			}
		}

		internal static bool BlocksTarget(Component? candidate)
		{
			if ((Object)(object)candidate != (Object)null)
			{
				ChefMimicFrog componentInParent = candidate.GetComponentInParent<ChefMimicFrog>();
				if (componentInParent != null)
				{
					return componentInParent.Active;
				}
			}
			return false;
		}

		internal static ChefMimicFrog Create(string prefabPath, Vector3 ground, Quaternion rotation, ChefMimic owner)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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)
			GameObject val = VanillaCatalog.Spawn(prefabPath, ground + Vector3.up * 0.15f, rotation);
			ChefMimicFrog chefMimicFrog = val.AddComponent<ChefMimicFrog>();
			chefMimicFrog._owner = owner;
			chefMimicFrog._physical = val.GetComponent<PhysGrabObject>();
			chefMimicFrog._valuable = val.GetComponent<ValuableObject>();
			return chefMimicFrog;
		}

		internal void InitializeVitality()
		{
			//IL_00c4: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized && Active && NetworkLifetime.Live((Component)(object)this))
			{
				float num = Mathf.Max(Mathf.Floor(_owner.FrogValue(_valuable.dollarValueOriginal)), Mathf.Floor(_valuable.dollarValueOriginal * 0.15f) + 1f);
				float num2 = num - _valuable.dollarValueCurrent;
				PhysGrabObjectImpactDetector component = ((Component)this).GetComponent<PhysGrabObjectImpactDetector>();
				if (SemiFunc.IsMultiplayer())
				{
					((Component)this).GetComponent<PhotonView>().RPC("HealRPC", (RpcTarget)0, new object[2]
					{
						num2,
						((Component)this).transform.position
					});
				}
				else
				{
					Heal.Invoke(component, new object[3]
					{
						num2,
						((Component)this).transform.position,
						(object)default(PhotonMessageInfo)
					});
				}
				_lastFrogValue = _valuable.dollarValueCurrent;
				_initialized = true;
				SynchronizeVitality();
			}
		}

		private void Update()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				SynchronizeVitality();
			}
		}

		internal void SynchronizeVitality()
		{
			if (_initialized && Active)
			{
				float change = _valuable.dollarValueCurrent - _lastFrogValue;
				_lastFrogValue = _valuable.dollarValueCurrent;
				if (_owner.CaptureFrog(change, _valuable.dollarValueOriginal))
				{
					((Component)this).GetComponent<PhysGrabObjectImpactDetector>().DestroyObject(true);
				}
			}
		}

		internal void Grabbed(PhysGrabber player)
		{
			if (Active)
			{
				_owner.Grabbed(this, player);
			}
		}

		internal void RemoveQuietly()
		{
			SynchronizeVitality();
			_owner = null;
			NetworkLifetime.Remove(((Component)this).gameObject);
		}

		internal void Destroyed()
		{
			_owner?.Destroyed(this);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerAddRPC")]
	internal static class ChefFrogNetworkGrabPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysGrabObject __instance, int photonViewID, PhotonMessageInfo _info)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.MasterOnlyRPC(_info))
			{
				return;
			}
			ChefMimicFrog component = ((Component)__instance).GetComponent<ChefMimicFrog>();
			if (component != null && component.Active)
			{
				PhotonView obj = PhotonView.Find(photonViewID);
				PhysGrabber val = ((obj != null) ? ((Component)obj).GetComponent<PhysGrabber>() : null);
				if ((Object)(object)val != (Object)null && __instance.playerGrabbing.Contains(val))
				{
					component.Grabbed(val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")]
	internal static class ChefFrogSoloGrabPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysGrabObject __instance, PhysGrabber player)
		{
			if (!SemiFunc.IsMultiplayer() && __instance.playerGrabbing.Contains(player))
			{
				((Component)__instance).GetComponent<ChefMimicFrog>()?.Grabbed(player);
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "DestroyObject")]
	internal static class ChefFrogDestructionPatch
	{
		[HarmonyPrefix]
		private static void Prefix(PhysGrabObjectImpactDetector __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !__instance.destroyDisable && !((Component)__instance).GetComponent<PhysGrabObject>().dead)
			{
				ChefMimicFrog component = ((Component)__instance).GetComponent<ChefMimicFrog>();
				if (component != null && component.Active)
				{
					component.Destroyed();
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "DestroyPhysGrabObject")]
	internal static class ChefFrogDirectDestructionPatch
	{
		[HarmonyPrefix]
		private static void Prefix(PhysGrabObject __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ChefMimicFrog component = ((Component)__instance).GetComponent<ChefMimicFrog>();
				if (component != null && component.Active)
				{
					component.Destroyed();
				}
			}
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "DollarValueSet")]
	internal static class ChefFrogPossibleHaulPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ValuableObject __instance, ref IEnumerator __result)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)((Component)__instance).GetComponent<ChefMimicFrog>() != (Object)null)
			{
				__result = ExcludeHaul(__result, __instance);
			}
		}

		private static IEnumerator ExcludeHaul(IEnumerator native, ValuableObject valuable)
		{
			while (native.MoveNext())
			{
				yield return native.Current;
			}
			if ((Object)(object)valuable != (Object)null && (Object)(object)RoundDirector.instance != (Object)null)
			{
				RoundDirector instance = RoundDirector.instance;
				instance.haulGoalMax -= (int)valuable.dollarValueCurrent;
			}
			if ((Object)(object)valuable != (Object)null)
			{
				((Component)valuable).GetComponent<ChefMimicFrog>()?.InitializeVitality();
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "BreakRPC")]
	internal static class ChefFrogDamageSyncPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysGrabObjectImpactDetector __instance, PhotonMessageInfo _info)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.MasterOnlyRPC(_info))
			{
				((Component)__instance).GetComponent<ChefMimicFrog>()?.SynchronizeVitality();
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "GetHighestParentWithRigidbody")]
	internal static class ChefFrogDroneTargetPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Transform _child, ref Transform? __result)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !ChefMimicFrog.BlocksTarget((Component?)(object)_child))
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "NewRayHitPoint")]
	internal static class ChefFrogDroneAttachmentPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance, int photonViewId, Transform newMagnetTarget)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			object obj2;
			if (!((Object)(object)newMagnetTarget != (Object)null))
			{
				PhotonView obj = PhotonView.Find(photonViewId);
				obj2 = ((obj != null) ? ((Component)obj).transform : null);
			}
			else
			{
				obj2 = newMagnetTarget;
			}
			Transform candidate = (Transform)obj2;
			if (!ChefMimicFrog.BlocksTarget((Component?)(object)candidate))
			{
				return true;
			}
			__instance.DeactivateMagnet();
			return false;
		}
	}
	internal sealed class CleanupHeadPursuit : MonoBehaviour
	{
		internal readonly CleanupHeadCycle Cycle = new CleanupHeadCycle();

		internal static bool Valid(PlayerAvatar? target)
		{
			if ((Object)(object)target != (Object)null && !target.deadSet && !target.isDisabled)
			{
				return NetworkLifetime.Live((Component)(object)target);
			}
			return false;
		}

		internal static CleanupHeadPursuit Marker(EnemyBombThrowerHead head)
		{
			return ((Component)head).GetComponent<CleanupHeadPursuit>() ?? ((Component)head).gameObject.AddComponent<CleanupHeadPursuit>();
		}

		internal static void Exploded(StageRuntime stage, Vector3 position, PlayerAvatar target, bool upscream)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)stage).StartCoroutine(SummonAfterDelay(stage, position, target, upscream));
		}

		private static IEnumerator SummonAfterDelay(StageRuntime stage, Vector3 position, PlayerAvatar target, bool upscream)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(2f);
			if ((Object)(object)stage == (Object)null || (Object)(object)StageRuntime.Current != (Object)(object)stage || !SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || !Valid(target))
			{
				yield break;
			}
			try
			{
				PrefabRef val = (upscream ? VanillaCatalog.UpscreamPrefab() : VanillaCatalog.SpewerPrefab());
				if (!FindPosition(val, position, target, out var result))
				{
					Plugin.ModLogger.LogWarning((object)$"Cleanup Crew pursuit skipped: no connected clear spawn near {position}.");
					yield break;
				}
				EnemyParent val2 = SummonedEnemySpawnTicket.Create(((PrefabRef<GameObject>)(object)val).ResourcePath, result, null, shareAttackTarget: false, prepareOnMesh: true, vanillaOnly: false, SummonPool.Cleanup);
				CleanupPursuer cleanupPursuer = ((Component)val2).GetComponent<CleanupPursuer>() ?? ((Component)val2).gameObject.AddComponent<CleanupPursuer>();
				cleanupPursuer.Prepare(stage, target);
				((Component)val2).GetComponentInChildren<EnemyHealth>(true).spawnValuable = false;
			}
			catch (RoomViewCapacityException)
			{
				RoomViewBudget.Warn();
			}
			catch (Exception arg)
			{
				Plugin.ModLogger.LogError((object)$"Cleanup Crew pursuit summon failed: {arg}");
			}
		}

		private static bool FindPosition(PrefabRef prefab, Vector3 origin, PlayerAvatar target, out Vector3 result)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0033: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent componentInChildren = ((PrefabRef<GameObject>)(object)prefab).Prefab.GetComponentInChildren<NavMeshAgent>(true);
			NavMeshQueryFilter val = default(NavMeshQueryFilter);
			((NavMeshQueryFilter)(ref val)).agentTypeID = componentInChildren.agentTypeID;
			((NavMeshQueryFilter)(ref val)).areaMask = componentInChildren.areaMask;
			NavMeshQueryFilter val2 = val;
			result = default(Vector3);
			NavMeshHit val3 = default(NavMeshHit);
			if (!NavMesh.SamplePosition(((Component)target).transform.position, ref val3, 3f, val2))
			{
				return false;
			}
			float num = Mathf.Max(0.3f, componentInChildren.height);
			float num2 = Mathf.Clamp(componentInChildren.radius, 0.12f, num / 2f);
			NavMeshPath val4 = new NavMeshPath();
			NavMeshHit val6 = default(NavMeshHit);
			for (int i = 0; i < 25; i++)