Decompiled source of IAmEnemy v0.7.1

IAmEnemy.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using OpJosModREPO.Controllers.IAmEnemy;
using OpJosModREPO.IAmEnemy;
using OpJosModREPO.IAmEnemy.Networking;
using OpJosModREPO.IAmEnemy.Patches;
using OpJosModREPO.IAmEnemy.Util;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("REPOMods")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("REPOMods")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ae067094-69b3-4aaf-9688-38ff78ee3b28")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OpJosModREPO.Controllers.IAmEnemy
{
	public class ReaperPlayerController : EnemyControllerBase
	{
		public EnemyRunner thisRunner = null;

		public void Setup(int actorNumber, EnemyRunner runner)
		{
			thisRunner = runner;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(runner, "enemy");
			OnSetup(actorNumber, ((Component)runner).gameObject, fieldValue, ((Component)runner).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (PublicVars.EnemyInBlendMode || isInBlendMode)
			{
				return;
			}
			FixedUpdateLogic();
			if ((int)thisRunner.currentState == 1)
			{
				ReflectionUtils.InvokeMethod(thisRunner, "UpdateState", new object[1] { (object)(State)2 });
			}
			if (isYourEnemy)
			{
				if (attackCooldown > 0f)
				{
					attackCooldown -= Time.fixedDeltaTime;
				}
				if (attackCooldown <= 0f)
				{
					attackNearbyEnemies();
					attackCooldown = 0.75f;
				}
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					if ((int)thisRunner.currentState == 7)
					{
						EnemyControllerBase.mls.LogInfo((object)"Stopping reaper attack mode");
						ReflectionUtils.InvokeMethod(thisRunner, "UpdateState", new object[1] { (object)(State)1 });
					}
					else if (ConfigVariables.allowAttackToggle)
					{
						EnemyControllerBase.mls.LogInfo((object)"Starting reaper attack mode");
						ReflectionUtils.InvokeMethod(thisRunner, "UpdateState", new object[1] { (object)(State)7 });
					}
				}
			}
			catch
			{
			}
		}

		private void attackNearbyEnemies()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0022: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			if ((int)thisRunner.currentState != 7)
			{
				return;
			}
			List<Enemy> list = GeneralUtil.FindCloseEnemies(((Component)thisRunner).transform.position, 3.5f);
			foreach (Enemy item in list)
			{
				if (!((Object)(object)item != (Object)null) || ((Object)item).GetInstanceID() == ((Object)thisRunner.enemy).GetInstanceID())
				{
					continue;
				}
				Vector3 val = ((Component)item).transform.position - ((Component)thisRunner).transform.position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				float num = Vector3.Angle(((Component)thisRunner).transform.forward, normalized);
				if (num < 50f)
				{
					EnemyHealth fieldValue = ReflectionUtils.GetFieldValue<EnemyHealth>(item, "Health");
					if ((Object)(object)fieldValue != (Object)null)
					{
						val = ((Component)item).transform.position - ((Component)thisRunner).transform.position;
						Vector3 normalized2 = ((Vector3)(ref val)).normalized;
						fieldValue.Hurt(40, normalized2);
					}
					else
					{
						EnemyControllerBase.mls.LogError((object)("Health component not found for enemy: " + ((Object)item).name));
					}
				}
			}
		}
	}
	public class ClownPlayerController : EnemyControllerBase
	{
		public EnemyBeamer thisBeamer = null;

		private Vector3 laserLocation;

		private Vector3 laserAngle;

		private float syncTimer = 0f;

		private float syncInterval = 0.375f;

		public void Setup(int actorNumber, EnemyBeamer beamer)
		{
			thisBeamer = beamer;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(beamer, "enemy");
			OnSetup(actorNumber, ((Component)beamer).gameObject, fieldValue, ((Component)beamer).transform);
			ReflectionUtils.InvokeMethod(thisBeamer, "UpdateState", new object[1] { (object)(State)2 });
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_007e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b3: 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)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (PublicVars.EnemyInBlendMode || isInBlendMode)
			{
				return;
			}
			FixedUpdateLogic();
			if ((int)thisBeamer.currentState == 1)
			{
				ReflectionUtils.InvokeMethod(thisBeamer, "UpdateState", new object[1] { (object)(State)2 });
			}
			if ((int)thisBeamer.currentState != 5)
			{
				return;
			}
			if (isYourEnemy)
			{
				laserAngle = cameraTransform.eulerAngles;
				laserLocation = thisBeamer.laserStartTransform.position + cameraTransform.forward * 20f;
				if (!PhotonNetwork.IsMasterClient)
				{
					syncTimer += Time.deltaTime;
					if (syncTimer >= syncInterval)
					{
						EnemySpawnerNetwork.Instance.TriggerSpecialAttack(laserLocation, laserAngle, controlActorNumber);
						syncTimer = 0f;
					}
				}
			}
			if (PhotonNetwork.IsMasterClient)
			{
				ShootLaser();
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					if ((int)thisBeamer.currentState == 5)
					{
						EnemyControllerBase.mls.LogInfo((object)"Stopping clown attack mode");
						ReflectionUtils.InvokeMethod(thisBeamer, "UpdateState", new object[1] { (object)(State)2 });
					}
					else if (ConfigVariables.allowAttackToggle)
					{
						EnemyControllerBase.mls.LogInfo((object)"Starting clown attack mode");
						ReflectionUtils.InvokeMethod(thisBeamer, "UpdateState", new object[1] { (object)(State)5 });
					}
				}
			}
			catch
			{
			}
		}

		public override void SpecialAttack(Vector3 pos, Vector3 angle)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			laserAngle = angle;
			laserLocation = pos;
		}

		private void ShootLaser()
		{
			//IL_0021: 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)
			ReflectionUtils.SetFieldValue(thisBeamer, "aimHorizontalTarget", Quaternion.Euler(0f, laserAngle.y, 0f));
			ReflectionUtils.SetFieldValue(thisBeamer, "hitPosition", laserLocation);
			ReflectionUtils.InvokeMethod(thisBeamer, "RotationLogic", new object[0]);
			ReflectionUtils.InvokeMethod(thisBeamer, "VerticalAimLogic", new object[0]);
			ReflectionUtils.InvokeMethod(thisBeamer, "LaserLogic", new object[0]);
		}
	}
	public class PeeperPlayerController : EnemyControllerBase
	{
		public EnemyCeilingEye thisEye = null;

		public void Setup(int actorNumber, EnemyCeilingEye eye)
		{
			thisEye = eye;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(eye, "enemy");
			OnSetup(actorNumber, ((Component)eye).gameObject, fieldValue, ((Component)eye).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class GnomePlayerController : EnemyControllerBase
	{
		public EnemyGnome thisGnome = null;

		public void Setup(int actorNumber, EnemyGnome gnome)
		{
			thisGnome = gnome;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(gnome, "enemy");
			OnSetup(actorNumber, ((Component)gnome).gameObject, fieldValue, ((Component)gnome).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					if ((int)thisGnome.currentState == 9)
					{
						EnemyControllerBase.mls.LogInfo((object)"Stopping gnome attack mode");
						ReflectionUtils.InvokeMethod(thisGnome, "UpdateState", new object[1] { (object)(State)1 });
					}
					else if (ConfigVariables.allowAttackToggle)
					{
						EnemyControllerBase.mls.LogInfo((object)"Starting gnome attack mode");
						ReflectionUtils.InvokeMethod(thisGnome, "UpdateState", new object[1] { (object)(State)9 });
					}
				}
			}
			catch
			{
			}
		}
	}
	public class ShadowChildPlayerController : EnemyControllerBase
	{
		public EnemyThinMan thisThinMan = null;

		public void Setup(int actorNumber, EnemyThinMan thinMan)
		{
			thisThinMan = thinMan;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(thinMan, "enemy");
			OnSetup(actorNumber, ((Component)thinMan).gameObject, fieldValue, ((Component)thinMan).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class HeadManPlayerController : EnemyControllerBase
	{
		public EnemyHeadController thisHead = null;

		public void Setup(int actorNumber, EnemyHeadController head)
		{
			thisHead = head;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(head, "enemy");
			OnSetup(actorNumber, ((Component)head).gameObject, fieldValue, ((Component)head).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class HuntsmanPlayerController : EnemyControllerBase
	{
		public EnemyHunter thisHunter = null;

		public void Setup(int actorNumber, EnemyHunter hunter)
		{
			thisHunter = hunter;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(hunter, "enemy");
			OnSetup(actorNumber, ((Component)hunter).gameObject, fieldValue, ((Component)hunter).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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)
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (!((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame || !ConfigVariables.allowAttackToggle)
				{
					return;
				}
				Vector3 val = ((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward * 10f;
				ReflectionUtils.SetFieldValue(thisHunter, "investigatePoint", val);
				ReflectionUtils.InvokeMethod(thisHunter, "UpdateState", new object[1] { (object)(State)1 });
				ReflectionUtils.InvokeMethod(thisHunter, "UpdateState", new object[1] { (object)(State)5 });
				ManualLogSource obj = EnemyControllerBase.mls;
				Vector3 val2 = val;
				obj.LogInfo((object)("Set hunter to Aim at: " + ((object)(Vector3)(ref val2)).ToString()));
				DelayUtility.RunAfterDelay(0.5f, delegate
				{
					ReflectionUtils.InvokeMethod(thisHunter, "StateShoot", null);
					DelayUtility.RunAfterDelay(0.25f, delegate
					{
						ReflectionUtils.InvokeMethod(thisHunter, "UpdateState", new object[1] { (object)(State)7 });
					});
					DelayUtility.RunAfterDelay(0.5f, delegate
					{
						ReflectionUtils.InvokeMethod(thisHunter, "UpdateState", new object[1] { (object)(State)1 });
						EnemyControllerBase.mls.LogInfo((object)"Returned hunter to Idle.");
					});
				});
			}
			catch (Exception ex)
			{
				EnemyControllerBase.mls.LogError((object)ex);
			}
		}
	}
	public class BabyPlayerController : EnemyControllerBase
	{
		public EnemyValuableThrower thisBaby = null;

		public void Setup(int actorNumber, EnemyValuableThrower baby)
		{
			thisBaby = baby;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(baby, "enemy");
			OnSetup(actorNumber, ((Component)baby).gameObject, fieldValue, ((Component)baby).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				HandleInput();
			}
		}

		private void FixedUpdate()
		{
			FixedUpdateLogic();
			PhysGrabObject fieldValue = ReflectionUtils.GetFieldValue<PhysGrabObject>(thisBaby, "valuableTarget");
			if ((Object)(object)fieldValue != (Object)null && PhotonNetwork.IsMasterClient)
			{
				ReflectionUtils.InvokeMethod(thisBaby, "ValuableTargetFollow", new object[0]);
			}
		}

		private void HandleInput()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame && ConfigVariables.allowAttackToggle)
				{
					if (PhotonNetwork.IsMasterClient)
					{
						TriggerPickupOrThrow();
					}
					else
					{
						EnemySpawnerNetwork.Instance.TriggerSpecialAttack(Vector3.zero, Vector3.zero, controlActorNumber);
					}
				}
			}
			catch
			{
			}
		}

		public override void SpecialAttack(Vector3 pos, Vector3 angle)
		{
			TriggerPickupOrThrow();
		}

		public void TriggerPickupOrThrow()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			PhysGrabObject fieldValue = ReflectionUtils.GetFieldValue<PhysGrabObject>(thisBaby, "valuableTarget");
			if ((Object)(object)fieldValue == (Object)null)
			{
				Collider[] array = Physics.OverlapSphere(thisEnemyGameObject.transform.position, 2f, LayerMask.GetMask(new string[1] { "PhysGrabObject" }));
				Collider[] array2 = array;
				foreach (Collider val in array2)
				{
					ValuableObject componentInParent = ((Component)val).GetComponentInParent<ValuableObject>();
					if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.volumeType <= 3)
					{
						fieldValue = ReflectionUtils.GetFieldValue<PhysGrabObject>(componentInParent, "physGrabObject");
						ReflectionUtils.SetFieldValue(thisBaby, "valuableTarget", fieldValue);
						fieldValue.OverrideZeroGravity(0.1f);
						fieldValue.OverrideMass(0.5f, 0.1f);
						fieldValue.OverrideIndestructible(0.1f);
						fieldValue.OverrideBreakEffects(0.1f);
						((Component)fieldValue).transform.position = thisBaby.pickupTarget.position;
						((Component)fieldValue).transform.rotation = thisBaby.pickupTarget.rotation;
						fieldValue.rb.velocity = Vector3.zero;
						fieldValue.rb.angularVelocity = Vector3.zero;
						ReflectionUtils.InvokeMethod(thisBaby, "UpdateState", new object[1] { (object)(State)7 });
						break;
					}
				}
			}
			else
			{
				ReflectionUtils.InvokeMethod(thisBaby, "UpdateState", new object[1] { (object)(State)9 });
				DelayUtility.RunAfterDelay(0.5f, delegate
				{
					//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_001d: 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_0023: 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_002a: 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_0034: 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 forward = ((Component)thisBaby).transform.forward;
					Vector3 position = thisBaby.pickupTarget.position;
					Vector3 targetSpot = position + forward * 10f;
					CustomThrowAtLocation(targetSpot);
				});
				DelayUtility.RunAfterDelay(0.75f, delegate
				{
					ReflectionUtils.InvokeMethod(thisBaby, "UpdateState", new object[1] { (object)(State)1 });
				});
			}
		}

		private void CustomThrowAtLocation(Vector3 targetSpot)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			PhysGrabObject fieldValue = ReflectionUtils.GetFieldValue<PhysGrabObject>(thisBaby, "valuableTarget");
			if (!Object.op_Implicit((Object)(object)fieldValue))
			{
				return;
			}
			foreach (PhysGrabber item in fieldValue.playerGrabbing.ToList())
			{
				if (!SemiFunc.IsMultiplayer())
				{
					item.ReleaseObject(0.1f);
					continue;
				}
				item.photonView.RPC("ReleaseObjectRPC", (RpcTarget)0, new object[2] { false, 0.1f });
			}
			Vector3 val = targetSpot - fieldValue.centerPoint;
			val = Vector3.Lerp(((Component)thisBaby).transform.forward, val, 0.5f);
			fieldValue.ResetMass();
			float num = 20f * fieldValue.rb.mass;
			num = Mathf.Min(num, 100f);
			fieldValue.ResetIndestructible();
			fieldValue.rb.AddForce(val * num, (ForceMode)1);
			fieldValue.rb.AddTorque(((Component)fieldValue).transform.right * 0.5f, (ForceMode)1);
			PhysGrabObjectImpactDetector fieldValue2 = ReflectionUtils.GetFieldValue<PhysGrabObjectImpactDetector>(fieldValue, "impactDetector");
			fieldValue2.PlayerHurtMultiplier(5f, 2f);
			ReflectionUtils.SetFieldValue(thisBaby, "valuableTarget", null);
		}
	}
	public class BangerPlayerController : EnemyControllerBase
	{
		public EnemyBang thisBang = null;

		public void Setup(int actorNumber, EnemyBang bang)
		{
			thisBang = bang;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(bang, "enemy");
			OnSetup(actorNumber, ((Component)bang).gameObject, fieldValue, ((Component)bang).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					ReflectionUtils.InvokeMethod(thisBang, "ExplodeRPC", new object[0]);
				}
			}
			catch
			{
			}
		}
	}
	public class BowtiePlayerController : EnemyControllerBase
	{
		public EnemyBowtie thisBowtie = null;

		public void Setup(int actorNumber, EnemyBowtie bowtie)
		{
			thisBowtie = bowtie;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(bowtie, "enemy");
			OnSetup(actorNumber, ((Component)bowtie).gameObject, fieldValue, ((Component)bowtie).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (!((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					return;
				}
				if ((int)thisBowtie.currentState == 5)
				{
					EnemyControllerBase.mls.LogInfo((object)"Stopping bowtie attack mode");
					ReflectionUtils.InvokeMethod(thisBowtie, "UpdateState", new object[1] { (object)(State)6 });
					DelayUtility.RunAfterDelay(0.25f, delegate
					{
						ReflectionUtils.InvokeMethod(thisBowtie, "UpdateState", new object[1] { (object)(State)1 });
					});
				}
				else if (ConfigVariables.allowAttackToggle)
				{
					EnemyControllerBase.mls.LogInfo((object)"Starting bowtie attack mode");
					ReflectionUtils.InvokeMethod(thisBowtie, "UpdateState", new object[1] { (object)(State)5 });
				}
			}
			catch
			{
			}
		}
	}
	public class MentalistPlayerController : EnemyControllerBase
	{
		public EnemyFloater thisMentalist = null;

		public void Setup(int actorNumber, EnemyFloater mentalist)
		{
			thisMentalist = mentalist;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(mentalist, "enemy");
			OnSetup(actorNumber, ((Component)mentalist).gameObject, fieldValue, ((Component)mentalist).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			//IL_0026: 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_0054: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame && ConfigVariables.allowAttackToggle)
				{
					if ((int)thisMentalist.currentState == 9)
					{
						EnemyControllerBase.mls.LogInfo((object)"Stopping mentalist attack");
						ReflectionUtils.InvokeMethod(thisMentalist, "UpdateState", new object[1] { (object)(State)1 });
					}
					else
					{
						EnemyControllerBase.mls.LogInfo((object)"Starting mentalist attack");
						ReflectionUtils.InvokeMethod(thisMentalist, "UpdateState", new object[1] { (object)(State)7 });
						DelayUtility.RunAfterDelay(0.5f, delegate
						{
							ReflectionUtils.InvokeMethod(thisMentalist, "UpdateState", new object[1] { (object)(State)9 });
						});
					}
				}
			}
			catch
			{
			}
			try
			{
				if (((ButtonControl)Keyboard.current[(Key)1]).wasPressedThisFrame)
				{
					if (isHost)
					{
						SpecialMovement(1);
					}
					else
					{
						EnemySpawnerNetwork.Instance.TriggerSpecialMovement(1, controlActorNumber);
					}
				}
			}
			catch
			{
			}
			try
			{
				if (((ButtonControl)Keyboard.current[(Key)55]).wasPressedThisFrame)
				{
					if (isHost)
					{
						SpecialMovement(0);
					}
					else
					{
						EnemySpawnerNetwork.Instance.TriggerSpecialMovement(0, controlActorNumber);
					}
				}
			}
			catch
			{
			}
		}

		public override void SpecialMovement(int num)
		{
			//IL_0028: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			switch (num)
			{
			case 1:
			{
				EnemyRigidbody fieldValue3 = ReflectionUtils.GetFieldValue<EnemyRigidbody>(thisEnemyEnemy, "Rigidbody");
				Rigidbody fieldValue4 = ReflectionUtils.GetFieldValue<Rigidbody>(fieldValue3, "rb");
				fieldValue4.AddForce(Vector3.up * 1f, (ForceMode)1);
				break;
			}
			case 0:
			{
				EnemyRigidbody fieldValue = ReflectionUtils.GetFieldValue<EnemyRigidbody>(thisEnemyEnemy, "Rigidbody");
				Rigidbody fieldValue2 = ReflectionUtils.GetFieldValue<Rigidbody>(fieldValue, "rb");
				fieldValue2.AddForce(Vector3.down * 1f, (ForceMode)1);
				break;
			}
			}
		}
	}
	public class UpscreamPlayerController : EnemyControllerBase
	{
		public EnemyUpscream thisUpscream = null;

		public void Setup(int actorNumber, EnemyUpscream upscream)
		{
			thisUpscream = upscream;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(upscream, "enemy");
			OnSetup(actorNumber, ((Component)upscream).gameObject, fieldValue, ((Component)upscream).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class TrudgePlayerController : EnemyControllerBase
	{
		public EnemySlowWalker thisTrudge = null;

		public void Setup(int actorNumber, EnemySlowWalker trudge)
		{
			thisTrudge = trudge;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(trudge, "enemy");
			OnSetup(actorNumber, ((Component)trudge).gameObject, fieldValue, ((Component)trudge).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
				if ((int)thisTrudge.currentState == 1)
				{
					ReflectionUtils.InvokeMethod(thisTrudge, "UpdateState", new object[1] { (object)(State)2 });
				}
			}
		}

		private void handleInput()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (!((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					return;
				}
				ReflectionUtils.InvokeMethod(thisTrudge, "UpdateState", new object[1] { (object)(State)7 });
				DelayUtility.RunAfterDelay(4f, delegate
				{
					attackNearbyEnemies();
					DelayUtility.RunAfterDelay(1f, delegate
					{
						ReflectionUtils.InvokeMethod(thisTrudge, "UpdateState", new object[1] { (object)(State)1 });
					});
				});
			}
			catch
			{
			}
		}

		private void attackNearbyEnemies()
		{
			//IL_000c: 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_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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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)
			List<Enemy> list = GeneralUtil.FindCloseEnemies(((Component)thisTrudge).transform.position, 6f);
			foreach (Enemy item in list)
			{
				if (!((Object)(object)item != (Object)null) || ((Object)item).GetInstanceID() == ((Object)thisTrudge.enemy).GetInstanceID())
				{
					continue;
				}
				Vector3 val = ((Component)item).transform.position - ((Component)thisTrudge).transform.position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				float num = Vector3.Angle(((Component)thisTrudge).transform.forward, normalized);
				if (num < 50f)
				{
					EnemyHealth fieldValue = ReflectionUtils.GetFieldValue<EnemyHealth>(item, "Health");
					if ((Object)(object)fieldValue != (Object)null)
					{
						val = ((Component)item).transform.position - ((Component)thisTrudge).transform.position;
						Vector3 normalized2 = ((Vector3)(ref val)).normalized;
						fieldValue.Hurt(120, normalized2);
					}
					else
					{
						EnemyControllerBase.mls.LogError((object)("Health component not found for enemy: " + ((Object)item).name));
					}
				}
			}
		}
	}
	public class SpewerPlayerController : EnemyControllerBase
	{
		public EnemySlowMouth thisMouth = null;

		public void Setup(int actorNumber, EnemySlowMouth mouth)
		{
			thisMouth = mouth;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(mouth, "enemy");
			OnSetup(actorNumber, ((Component)mouth).gameObject, fieldValue, ((Component)mouth).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class RobePlayerController : EnemyControllerBase
	{
		public EnemyRobe thisRobe = null;

		public void Setup(int actorNumber, EnemyRobe robe)
		{
			thisRobe = robe;
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(robe, "enemy");
			OnSetup(actorNumber, ((Component)robe).gameObject, fieldValue, ((Component)robe).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (!PublicVars.EnemyInBlendMode && !isInBlendMode)
			{
				FixedUpdateLogic();
			}
		}

		private void handleInput()
		{
			if (controlActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)
			{
			}
		}
	}
	public class EnemyControllerBase : MonoBehaviour
	{
		protected static ManualLogSource mls;

		public int controlActorNumber;

		public bool isInBlendMode;

		public GameObject thisEnemyGameObject;

		public Enemy thisEnemyEnemy;

		protected EnemyRigidbody erb;

		protected Rigidbody rb;

		protected bool isYourEnemy = false;

		protected bool isHost = false;

		protected float attackCooldown;

		protected Transform cameraTransform;

		private float syncTimer = 0f;

		private float syncInterval = 0.375f;

		private Transform thisEnemyTransform;

		private Vector3 moveDirection;

		private float moveSpeed = 3f;

		private float turnSpeed = 3f;

		private float jumpForce = 0.5f;

		private float mouseSensitivity = 0.25f;

		private float cameraPitch = 0f;

		private Vector3 cameraOffset = new Vector3(0f, 1.75f, -1.75f);

		private float cameraSmoothSpeed = 15f;

		private Vector3 targetLookDirection;

		private bool shouldJump = false;

		private bool slowFall = false;

		private GameObject nightLight;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		protected void OnSetup(int actorNumber, GameObject enemyGameObject, Enemy thisEnemy, Transform enemyTransform)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			controlActorNumber = actorNumber;
			isHost = PhotonNetwork.IsMasterClient;
			thisEnemyGameObject = enemyGameObject;
			thisEnemyEnemy = thisEnemy;
			thisEnemyTransform = enemyTransform;
			erb = ReflectionUtils.GetFieldValue<EnemyRigidbody>(thisEnemy, "Rigidbody");
			rb = ReflectionUtils.GetFieldValue<Rigidbody>(erb, "rb");
			if (PhotonNetwork.LocalPlayer.ActorNumber == controlActorNumber)
			{
				isYourEnemy = true;
				((Behaviour)PlayerController.instance).enabled = false;
				((Component)Camera.main).transform.SetParent(enemyGameObject.transform);
				((Component)Camera.main).transform.localPosition = cameraOffset;
				((Component)Camera.main).transform.localRotation = Quaternion.identity;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
				AddGlobalLight();
			}
			cameraTransform = ((Component)Camera.main).transform;
		}

		public void UpdateMovementAndRotation(Vector3 movement, Vector3 camForward, bool jump)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			moveDirection = movement;
			targetLookDirection = camForward;
			if (jump)
			{
				TriggerJump();
			}
		}

		protected void UpdateLogic()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_0112: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			if (!isYourEnemy)
			{
				return;
			}
			Vector2 val = (Vector2)((Keyboard.current != null) ? new Vector2((float)(((ButtonControl)Keyboard.current.aKey).isPressed ? (-1) : (((ButtonControl)Keyboard.current.dKey).isPressed ? 1 : 0)), (float)(((ButtonControl)Keyboard.current.sKey).isPressed ? (-1) : (((ButtonControl)Keyboard.current.wKey).isPressed ? 1 : 0))) : Vector2.zero);
			Transform transform = ((Component)this).transform;
			Vector3 val2 = new Vector3(val.x, 0f, val.y);
			moveDirection = transform.TransformDirection(((Vector3)(ref val2)).normalized);
			float num = ((InputControl<float>)(object)((Vector2Control)((Pointer)Mouse.current).delta).x).ReadValue() * mouseSensitivity;
			float num2 = ((InputControl<float>)(object)((Vector2Control)((Pointer)Mouse.current).delta).y).ReadValue() * mouseSensitivity;
			cameraPitch -= num2;
			cameraPitch = Mathf.Clamp(cameraPitch, -60f, 60f);
			((Component)this).transform.Rotate(Vector3.up * num);
			cameraTransform.localRotation = Quaternion.Euler(cameraPitch, 0f, 0f);
			shouldJump = ((ButtonControl)Keyboard.current.spaceKey).wasPressedThisFrame || shouldJump;
			if (!isHost)
			{
				syncTimer += Time.deltaTime;
				if (syncTimer >= syncInterval)
				{
					Vector3 forward = cameraTransform.forward;
					forward.y = 0f;
					((Vector3)(ref forward)).Normalize();
					EnemySpawnerNetwork.Instance.SendEnemyMovement(moveDirection, forward, controlActorNumber, shouldJump);
					shouldJump = false;
					syncTimer = 0f;
				}
			}
			handleInput();
		}

		protected void FixedUpdateLogic()
		{
			//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)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			if (PublicVars.EnemyInBlendMode || isInBlendMode)
			{
				return;
			}
			if ((isYourEnemy || isHost) && targetLookDirection != Vector3.zero)
			{
				Quaternion val = Quaternion.LookRotation(targetLookDirection);
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val, Time.deltaTime * 10f);
			}
			if (isHost)
			{
				erb.DisableFollowPosition(0.5f, 50f);
				rb.AddForce(new Vector3(moveDirection.x * moveSpeed, 0f, moveDirection.z * moveSpeed), (ForceMode)5);
				if (moveDirection.x == 0f && moveDirection.z == 0f)
				{
					Vector3 velocity = rb.velocity;
					Vector3 val2 = default(Vector3);
					((Vector3)(ref val2))..ctor(velocity.x, 0f, velocity.z);
					val2 = Vector3.Lerp(val2, Vector3.zero, Time.fixedDeltaTime * 5f);
					rb.velocity = new Vector3(val2.x, velocity.y, val2.z);
				}
				thisEnemyGameObject.transform.position = ((Component)rb).transform.position;
			}
			if (isYourEnemy)
			{
				cameraTransform.position = new Vector3(cameraTransform.position.x, ((Component)rb).transform.position.y + cameraOffset.y, cameraTransform.position.z);
			}
		}

		private void handleInput()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			if (((ButtonControl)Keyboard.current.spaceKey).wasPressedThisFrame && PhotonNetwork.IsMasterClient)
			{
				TriggerJump();
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.selfDestructKey]).wasPressedThisFrame)
				{
					EnemyHealth fieldValue = ReflectionUtils.GetFieldValue<EnemyHealth>(thisEnemyEnemy, "Health");
					ReflectionUtils.InvokeMethod(fieldValue, "Death", new object[1] { Vector3.zero });
					mls.LogMessage((object)"Killed controlled enemy");
				}
			}
			catch
			{
			}
			try
			{
				if (!((ButtonControl)Keyboard.current[ConfigVariables.toggleBlendModeKey]).wasPressedThisFrame)
				{
					return;
				}
				if (PublicVars.EnemyInBlendMode)
				{
					mls.LogInfo((object)"Leaving Blend mode");
					PublicVars.EnemyInBlendMode = false;
					if (PhotonNetwork.IsMasterClient)
					{
						GeneralUtil.BreakEnemyAI(thisEnemyEnemy);
					}
					else
					{
						EnemySpawnerNetwork.Instance.BreakEnemyAI(controlActorNumber);
					}
				}
				else
				{
					mls.LogInfo((object)"Starting blend mode");
					PublicVars.EnemyInBlendMode = true;
					if (PhotonNetwork.IsMasterClient)
					{
						GeneralUtil.EnableEnemyAI(thisEnemyEnemy);
					}
					else
					{
						EnemySpawnerNetwork.Instance.EnableEnemyAI(controlActorNumber);
					}
				}
			}
			catch
			{
			}
		}

		public virtual void SpecialAttack(Vector3 pos, Vector3 rot)
		{
			mls.LogWarning((object)"Special attack was hit in base controller, it should be override");
		}

		public virtual void SpecialMovement(int num)
		{
			mls.LogWarning((object)"Special movement was hit in base controller, it should be override");
		}

		private void TriggerJump()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)thisEnemyEnemy == (Object)null))
			{
				object fieldValue = ReflectionUtils.GetFieldValue<object>(thisEnemyEnemy, "Jump");
				if (fieldValue != null)
				{
					ReflectionUtils.InvokeMethod(fieldValue, "StuckTrigger", new object[1] { Vector3.up });
					rb.AddForce(Vector3.up * jumpForce, (ForceMode)1);
				}
			}
		}

		private void AddGlobalLight()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)nightLight != (Object)null))
			{
				nightLight = new GameObject("EnemyVisionLight");
				Light val = nightLight.AddComponent<Light>();
				val.type = (LightType)1;
				val.intensity = 1.25f;
				val.color = new Color(0.6f, 1f, 0.6f);
				((Component)val).transform.rotation = Quaternion.Euler(60f, -40f, 0f);
				val.shadows = (LightShadows)2;
				val.shadowStrength = 0.3f;
				val.range = 20f;
				Object.DontDestroyOnLoad((Object)(object)nightLight);
				nightLight.transform.SetParent(((Component)thisEnemyTransform).transform);
			}
		}
	}
	public class DuckPlayerController : EnemyControllerBase
	{
		public EnemyDuck thisDuck = null;

		public void Setup(int actorNumber, EnemyDuck duck)
		{
			thisDuck = duck;
			OnSetup(actorNumber, ((Component)duck).gameObject, duck.enemy, ((Component)duck).transform);
		}

		private void Update()
		{
			if (isYourEnemy)
			{
				UpdateLogic();
				handleInput();
			}
		}

		private void FixedUpdate()
		{
			if (PublicVars.EnemyInBlendMode || isInBlendMode)
			{
				return;
			}
			FixedUpdateLogic();
			if (isYourEnemy)
			{
				if (attackCooldown > 0f)
				{
					attackCooldown -= Time.fixedDeltaTime;
				}
				if (attackCooldown <= 0f)
				{
					attackNearbyEnemies();
					attackCooldown = 0.75f;
				}
			}
		}

		private void handleInput()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			if (controlActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				return;
			}
			try
			{
				if (((ButtonControl)Keyboard.current[ConfigVariables.attackButtonKey]).wasPressedThisFrame)
				{
					if ((int)thisDuck.currentState == 11)
					{
						EnemyControllerBase.mls.LogInfo((object)"Stopping duck attack mode");
						ReflectionUtils.InvokeMethod(thisDuck, "UpdateState", new object[1] { (object)(State)1 });
					}
					else if (ConfigVariables.allowAttackToggle)
					{
						EnemyControllerBase.mls.LogInfo((object)"Starting duck attack mode");
						ReflectionUtils.InvokeMethod(thisDuck, "UpdateState", new object[1] { (object)(State)11 });
					}
				}
			}
			catch
			{
			}
		}

		private void attackNearbyEnemies()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if ((int)thisDuck.currentState != 11)
			{
				return;
			}
			List<Enemy> list = GeneralUtil.FindCloseEnemies(((Component)thisDuck).transform.position, 2.25f);
			foreach (Enemy item in list)
			{
				if (!((Object)(object)item != (Object)null) || ((Object)item).GetInstanceID() == ((Object)thisDuck.enemy).GetInstanceID())
				{
					continue;
				}
				Vector3 val = ((Component)item).transform.position - ((Component)thisDuck).transform.position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				float num = Vector3.Angle(((Component)thisDuck).transform.forward, normalized);
				if (num < 50f)
				{
					EnemyHealth fieldValue = ReflectionUtils.GetFieldValue<EnemyHealth>(item, "Health");
					if ((Object)(object)fieldValue != (Object)null)
					{
						val = ((Component)item).transform.position - ((Component)thisDuck).transform.position;
						Vector3 normalized2 = ((Vector3)(ref val)).normalized;
						fieldValue.Hurt(20, normalized2);
					}
					else
					{
						EnemyControllerBase.mls.LogError((object)("Health component not found for enemy: " + ((Object)item).name));
					}
				}
			}
		}
	}
}
namespace OpJosModREPO.IAmEnemy
{
	public static class ConfigVariables
	{
		public static EnemyTypes whatEnemyYouSpawnAs;

		public static bool allowAttackToggle;

		public static Key attackButtonKey;

		public static Key selfDestructKey;

		public static Key toggleBlendModeKey;

		public static bool limitEnemiesPerLevel;

		public static int maxEnemiesPerLevel;

		public static bool hostOnly;
	}
	public static class EnemyMaps
	{
		private static readonly Dictionary<EnemyTypes, string> prefabPaths = new Dictionary<EnemyTypes, string>
		{
			{
				EnemyTypes.Duck,
				"Enemies/Enemy - Duck"
			},
			{
				EnemyTypes.ShadowChild,
				"Enemies/Enemy - Thin Man"
			},
			{
				EnemyTypes.Gnome,
				"Enemies/Enemy - Gnome"
			},
			{
				EnemyTypes.Spewer,
				"Enemies/Enemy - Slow Mouth"
			},
			{
				EnemyTypes.Baby,
				"Enemies/Enemy - Valuable Thrower"
			},
			{
				EnemyTypes.Upscream,
				"Enemies/Enemy - Upscream"
			},
			{
				EnemyTypes.Bowtie,
				"Enemies/Enemy - Bowtie"
			},
			{
				EnemyTypes.Mentalist,
				"Enemies/Enemy - Floater"
			},
			{
				EnemyTypes.Banger,
				"Enemies/Enemy - Bang"
			},
			{
				EnemyTypes.Robe,
				"Enemies/Enemy - Robe"
			},
			{
				EnemyTypes.Huntsman,
				"Enemies/Enemy - Hunter"
			},
			{
				EnemyTypes.Reaper,
				"Enemies/Enemy - Runner"
			},
			{
				EnemyTypes.Clown,
				"Enemies/Enemy - Beamer"
			},
			{
				EnemyTypes.Trudge,
				"Enemies/Enemy - Slow Walker"
			}
		};

		private static readonly Dictionary<EnemyTypes, Type> enemyComponentTypes = new Dictionary<EnemyTypes, Type>
		{
			{
				EnemyTypes.Duck,
				typeof(EnemyDuck)
			},
			{
				EnemyTypes.ShadowChild,
				typeof(EnemyThinMan)
			},
			{
				EnemyTypes.Gnome,
				typeof(EnemyGnome)
			},
			{
				EnemyTypes.Spewer,
				typeof(EnemySlowMouth)
			},
			{
				EnemyTypes.Baby,
				typeof(EnemyValuableThrower)
			},
			{
				EnemyTypes.Upscream,
				typeof(EnemyUpscream)
			},
			{
				EnemyTypes.Bowtie,
				typeof(EnemyBowtie)
			},
			{
				EnemyTypes.Mentalist,
				typeof(EnemyFloater)
			},
			{
				EnemyTypes.Banger,
				typeof(EnemyBang)
			},
			{
				EnemyTypes.Robe,
				typeof(EnemyRobe)
			},
			{
				EnemyTypes.Huntsman,
				typeof(EnemyHunter)
			},
			{
				EnemyTypes.Reaper,
				typeof(EnemyRunner)
			},
			{
				EnemyTypes.Clown,
				typeof(EnemyBeamer)
			},
			{
				EnemyTypes.Trudge,
				typeof(EnemySlowWalker)
			}
		};

		private static readonly Dictionary<EnemyTypes, Type> enemyControllerTypes = new Dictionary<EnemyTypes, Type>
		{
			{
				EnemyTypes.Duck,
				typeof(DuckPlayerController)
			},
			{
				EnemyTypes.Robe,
				typeof(RobePlayerController)
			},
			{
				EnemyTypes.Spewer,
				typeof(SpewerPlayerController)
			},
			{
				EnemyTypes.Reaper,
				typeof(ReaperPlayerController)
			},
			{
				EnemyTypes.Clown,
				typeof(ClownPlayerController)
			},
			{
				EnemyTypes.Gnome,
				typeof(GnomePlayerController)
			},
			{
				EnemyTypes.ShadowChild,
				typeof(ShadowChildPlayerController)
			},
			{
				EnemyTypes.Huntsman,
				typeof(HuntsmanPlayerController)
			},
			{
				EnemyTypes.Baby,
				typeof(BabyPlayerController)
			},
			{
				EnemyTypes.Banger,
				typeof(BangerPlayerController)
			},
			{
				EnemyTypes.Bowtie,
				typeof(BowtiePlayerController)
			},
			{
				EnemyTypes.Trudge,
				typeof(TrudgePlayerController)
			},
			{
				EnemyTypes.Upscream,
				typeof(UpscreamPlayerController)
			},
			{
				EnemyTypes.Mentalist,
				typeof(MentalistPlayerController)
			}
		};

		public static IReadOnlyDictionary<EnemyTypes, Type> ControllerTypes => enemyControllerTypes;

		public static string GetPrefabPath(EnemyTypes type)
		{
			if (prefabPaths.TryGetValue(type, out var value))
			{
				return value;
			}
			return null;
		}

		public static Type GetEnemyType(EnemyTypes type)
		{
			if (enemyComponentTypes.TryGetValue(type, out var value))
			{
				return value;
			}
			return null;
		}

		public static EnemyTypes? GetEnemyTypeFromInstance(Enemy enemyInstance)
		{
			foreach (KeyValuePair<EnemyTypes, Type> enemyComponentType in enemyComponentTypes)
			{
				if ((Object)(object)((Component)enemyInstance).GetComponent(enemyComponentType.Value) != (Object)null)
				{
					return enemyComponentType.Key;
				}
			}
			return null;
		}

		public static Type GetControllerType(EnemyTypes type)
		{
			if (enemyControllerTypes.TryGetValue(type, out var value))
			{
				return value;
			}
			return null;
		}
	}
	public enum EnemyTypes
	{
		Random,
		ShadowChild,
		Gnome,
		Duck,
		Spewer,
		Baby,
		Upscream,
		Bowtie,
		Mentalist,
		Banger,
		Robe,
		Huntsman,
		Reaper,
		Clown,
		Trudge
	}
	[BepInPlugin("OpJosModREPO.IAmEnemy", "IAmEnemy", "0.7.1")]
	public class OpJosModBase : BaseUnityPlugin
	{
		private const string modGUID = "OpJosModREPO.IAmEnemy";

		private const string modName = "IAmEnemy";

		private const string modVersion = "0.7.1";

		private readonly Harmony harmoy = new Harmony("OpJosModREPO.IAmEnemy");

		private static OpJosModBase Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("OpJosModREPO.IAmEnemy");
			mls.LogInfo((object)"IAmEnemy has started!");
			setupConfig();
			PlayerAvatarPatch.SetLogSource(mls);
			EnemyHealthPatch.SetLogSource(mls);
			EnemyControllerBase.SetLogSource(mls);
			GeneralUtil.SetLogSource(mls);
			harmoy.PatchAll();
		}

		private void setupConfig()
		{
			//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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<EnemyTypes> val = ((BaseUnityPlugin)this).Config.Bind<EnemyTypes>("What Enemy You Spawn As", "WhatEnemySpawnAs", EnemyTypes.Random, "Which enemy do you want to spawn as?");
			ConfigEntry<bool> val2 = ((BaseUnityPlugin)this).Config.Bind<bool>("Limit Enemy Spawns Per Level", "LimitEnemySpawnPerLevel", false, "Should the player be limited on how many times they can be an enemy per level?");
			ConfigEntry<int> val3 = ((BaseUnityPlugin)this).Config.Bind<int>("Max Enemies Per Level", "MaxEnemiesPerLevel", 1, "How many times a player can become an enemy? per player");
			ConfigEntry<bool> val4 = ((BaseUnityPlugin)this).Config.Bind<bool>("Allow Attack Toggle", "AllowAttackToggle", true, "Should the enemy be able to manually start attack mode?");
			ConfigEntry<Key> val5 = ((BaseUnityPlugin)this).Config.Bind<Key>("Attack Mode Button", "AttackModeButton", (Key)19, "Button to toggle on and off enemy's attack or to trigger an attack (depends on enemy)");
			ConfigEntry<Key> val6 = ((BaseUnityPlugin)this).Config.Bind<Key>("Self Destruct Button", "SelfDestructButton", (Key)25, "Button to self destruct the controlled enemy");
			ConfigEntry<Key> val7 = ((BaseUnityPlugin)this).Config.Bind<Key>("Toggle Blend Mode Button", "ToggleBlendModeButton", (Key)16, "Button to turn on the enemy's AI to blend in as a normal enemy");
			ConfigEntry<bool> val8 = ((BaseUnityPlugin)this).Config.Bind<bool>("Host Only", "HostOnly", false, "Should only the host be able to turn into enemies?");
			ConfigVariables.whatEnemyYouSpawnAs = val.Value;
			ConfigVariables.allowAttackToggle = val4.Value;
			ConfigVariables.attackButtonKey = val5.Value;
			ConfigVariables.selfDestructKey = val6.Value;
			ConfigVariables.toggleBlendModeKey = val7.Value;
			ConfigVariables.limitEnemiesPerLevel = val2.Value;
			ConfigVariables.maxEnemiesPerLevel = val3.Value;
			ConfigVariables.hostOnly = val8.Value;
		}
	}
	public static class PublicVars
	{
		public static int TimesSpawnedEnemy;

		public static bool EnemyCleanupInProgress;

		public static bool EnemyInBlendMode;

		public static EnemyTypes NextSpawnType;

		public static void SetNextSpawnType()
		{
			NextSpawnType = ConfigVariables.whatEnemyYouSpawnAs;
			if (ConfigVariables.whatEnemyYouSpawnAs == EnemyTypes.Random)
			{
				NextSpawnType = (EnemyTypes)Random.Range(1, Enum.GetValues(typeof(EnemyTypes)).Length);
			}
		}
	}
}
namespace OpJosModREPO.IAmEnemy.Patches
{
	[HarmonyPatch(typeof(EnemyHealth))]
	internal class EnemyHealthPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("DeathRPC")]
		[HarmonyPrefix]
		private static void DeathRPCPatch(EnemyHealth __instance)
		{
			Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(__instance, "enemy");
			if ((Object)(object)fieldValue == (Object)null)
			{
				return;
			}
			if (PublicVars.EnemyCleanupInProgress)
			{
				mls.LogInfo((object)"Enemy cleanup already in progress — skipping DeathRPC patch.");
				return;
			}
			EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController(fieldValue);
			if ((Object)(object)enemyControllerBase == (Object)null)
			{
				mls.LogWarning((object)"No PlayerController found for enemy. Skipping DeathRPC handling.");
			}
			else if (PhotonNetwork.LocalPlayer.ActorNumber == enemyControllerBase.controlActorNumber && ReflectionUtils.GetFieldValue<bool>(PlayerAvatar.instance, "deadSet"))
			{
				mls.LogInfo((object)"enemy dying is enemy being controlled, release control of enemy");
				GeneralUtil.ReleaseEnemyControlToSpectate();
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				Object.Destroy((Object)(object)enemyControllerBase);
				mls.LogInfo((object)$"Player{enemyControllerBase.controlActorNumber}'s enemy controller destroyed.");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal class PlayerAvatarPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("PlayerDeath")]
		[HarmonyPostfix]
		private static void PlayerDeathPatch(PlayerAvatar __instance)
		{
			//IL_00c0: 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)
			PublicVars.SetNextSpawnType();
			if (ConfigVariables.limitEnemiesPerLevel && PublicVars.TimesSpawnedEnemy >= ConfigVariables.maxEnemiesPerLevel)
			{
				mls.LogInfo((object)"Can't spawn enemy again, set to spectate");
				GeneralUtil.ReleaseEnemyControlToSpectate();
				return;
			}
			PublicVars.TimesSpawnedEnemy++;
			if (PhotonNetwork.IsMasterClient)
			{
				mls.LogMessage((object)"Player is dead, spawning enemy as host");
				GeneralUtil.SpawnEnemyAt(((Component)__instance).transform.position, 1, PublicVars.NextSpawnType);
			}
			else
			{
				mls.LogMessage((object)"Player is dead, sending spawn enemy request to host");
				mls.LogInfo((object)$"[CLIENT] Sending enemy spawn request. My actor number: {PhotonNetwork.LocalPlayer.ActorNumber}");
				EnemySpawnerNetwork.Instance.RequestSpawnEnemy(((Component)__instance).transform.position, PublicVars.NextSpawnType);
			}
		}

		[HarmonyPatch("ReviveRPC")]
		[HarmonyPostfix]
		private static void ReviveRPCPatch(PlayerAvatar __instance)
		{
			int ownerActorNr = __instance.photonView.OwnerActorNr;
			if (ownerActorNr == PhotonNetwork.LocalPlayer.ActorNumber)
			{
				mls.LogInfo((object)$"Handling local player respawn: {ownerActorNr}");
				EnemyControllerBase enemyController = GeneralUtil.FindEnemyController((int?)ownerActorNr);
				GeneralUtil.ReattatchCameraToPlayer();
				GeneralUtil.RemoveSpawnedControllableEnemy(enemyController);
				PublicVars.EnemyCleanupInProgress = false;
				PublicVars.EnemyInBlendMode = false;
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				mls.LogInfo((object)$"[HOST] Cleaning up enemy for revived player: {ownerActorNr}");
				EnemyControllerBase enemyController2 = GeneralUtil.FindEnemyController((int?)ownerActorNr);
				GeneralUtil.RemoveSpawnedControllableEnemy(enemyController2);
			}
		}

		[HarmonyPatch("LoadingLevelAnimationCompleted")]
		[HarmonyPostfix]
		private static void LoadingLevelAnimationCompletedPatch(PlayerAvatar __instance)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			if (((Object)__instance).GetInstanceID() != ((Object)PlayerAvatar.instance).GetInstanceID())
			{
				return;
			}
			mls.LogMessage((object)"New Level, allow being an enemy again");
			PublicVars.TimesSpawnedEnemy = 0;
			PublicVars.EnemyCleanupInProgress = false;
			PublicVars.EnemyInBlendMode = false;
			if ((Object)(object)EnemySpawnerNetwork.Instance == (Object)null)
			{
				GameObject val = new GameObject("EnemySpawnerNetwork");
				EnemySpawnerNetwork enemySpawnerNetwork = val.AddComponent<EnemySpawnerNetwork>();
				PhotonView val2 = val.AddComponent<PhotonView>();
				if (PhotonNetwork.IsMasterClient)
				{
					val2.ViewID = 1738;
					mls.LogInfo((object)$"[HOST] Allocated ViewID for EnemySpawnerNetwork: {val2.ViewID}");
				}
				else
				{
					val2.ViewID = 1738;
					mls.LogInfo((object)$"[CLIENT] Using known ViewID for EnemySpawnerNetwork: {val2.ViewID}");
				}
				Object.DontDestroyOnLoad((Object)(object)val);
				mls.LogInfo((object)"EnemySpawnerNetwork initialized");
			}
		}
	}
}
namespace OpJosModREPO.IAmEnemy.Networking
{
	public class EnemySpawnerNetwork : MonoBehaviourPun
	{
		public static EnemySpawnerNetwork Instance;

		private void Awake()
		{
			Instance = this;
		}

		[PunRPC]
		public void RPC_RequestSpawnEnemy(Vector3 position, int enemyTypeInt, PhotonMessageInfo info)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				GeneralUtil.SpawnEnemyAt(position, info.Sender.ActorNumber, (EnemyTypes)enemyTypeInt);
			}
		}

		public void RequestSpawnEnemy(Vector3 position, EnemyTypes enemyType)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviourPun)this).photonView.RPC("RPC_RequestSpawnEnemy", (RpcTarget)2, new object[2]
			{
				position,
				(int)enemyType
			});
		}

		[PunRPC]
		public void RPC_SendEnemyMovement(Vector3 movement, Vector3 camForward, int actorNumber, bool jump, PhotonMessageInfo info)
		{
			//IL_002e: 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)
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController((int?)actorNumber);
				if ((Object)(object)enemyControllerBase != (Object)null)
				{
					enemyControllerBase.UpdateMovementAndRotation(movement, camForward, jump);
				}
			}
		}

		public void SendEnemyMovement(Vector3 movement, Vector3 camForward, int actorNumber, bool jump)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviourPun)this).photonView.RPC("RPC_SendEnemyMovement", (RpcTarget)2, new object[4] { movement, camForward, actorNumber, jump });
		}

		[PunRPC]
		public void RPC_EnableEnemyAI(int actorNumber)
		{
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController((int?)actorNumber);
				enemyControllerBase.isInBlendMode = true;
				GeneralUtil.EnableEnemyAI(enemyControllerBase.thisEnemyEnemy);
			}
		}

		public void EnableEnemyAI(int actorNumber)
		{
			((MonoBehaviourPun)this).photonView.RPC("RPC_EnableEnemyAI", (RpcTarget)2, new object[1] { actorNumber });
		}

		[PunRPC]
		public void RPC_BreakEnemyAI(int actorNumber)
		{
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController((int?)actorNumber);
				enemyControllerBase.isInBlendMode = false;
				GeneralUtil.BreakEnemyAI(enemyControllerBase.thisEnemyEnemy);
			}
		}

		public void BreakEnemyAI(int actorNumber)
		{
			((MonoBehaviourPun)this).photonView.RPC("RPC_BreakEnemyAI", (RpcTarget)2, new object[1] { actorNumber });
		}

		[PunRPC]
		public void RPC_ControlEnemy(Vector3 pos, int actorNumber, int enemyTypeId)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.LocalPlayer.ActorNumber == actorNumber && !PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				GeneralUtil.ControlClosestEnemy(pos, actorNumber, (EnemyTypes)enemyTypeId);
			}
		}

		public void ControlEnemy(Vector3 pos, int actorNumber, EnemyTypes enemyType)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviourPun)this).photonView.RPC("RPC_ControlEnemy", (RpcTarget)0, new object[3]
			{
				pos,
				actorNumber,
				(int)enemyType
			});
		}

		[PunRPC]
		public void RPC_TriggerSpecialAttack(Vector3 pos, Vector3 rot, int actorNumber)
		{
			//IL_0023: 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)
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController((int?)actorNumber);
				enemyControllerBase.SpecialAttack(pos, rot);
			}
		}

		public void TriggerSpecialAttack(Vector3 pos, Vector3 rot, int actorNumber)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviourPun)this).photonView.RPC("RPC_TriggerSpecialAttack", (RpcTarget)2, new object[3] { pos, rot, actorNumber });
		}

		[PunRPC]
		public void RPC_TriggerSpecialMovement(int num, int actorNumber)
		{
			if (PhotonNetwork.IsMasterClient && !ConfigVariables.hostOnly)
			{
				EnemyControllerBase enemyControllerBase = GeneralUtil.FindEnemyController((int?)actorNumber);
				enemyControllerBase.SpecialMovement(num);
			}
		}

		public void TriggerSpecialMovement(int num, int actorNumber)
		{
			((MonoBehaviourPun)this).photonView.RPC("RPC_TriggerSpecialMovement", (RpcTarget)2, new object[2] { num, actorNumber });
		}
	}
}
namespace OpJosModREPO.IAmEnemy.Util
{
	public class DelayUtility : MonoBehaviour
	{
		private static DelayUtility _instance;

		public static DelayUtility Instance
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("DelayUtility");
					_instance = val.AddComponent<DelayUtility>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return _instance;
			}
		}

		private void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			else if ((Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public static void RunAfterDelay(float seconds, Action action)
		{
			((MonoBehaviour)Instance).StartCoroutine(Instance.DelayCoroutine(seconds, action));
		}

		private IEnumerator DelayCoroutine(float seconds, Action action)
		{
			yield return (object)new WaitForSeconds(seconds);
			action?.Invoke();
		}

		public static void RunUntil(Func<bool> condition, Action onSuccess, float timeoutSeconds = 10f, Action onTimeout = null)
		{
			((MonoBehaviour)Instance).StartCoroutine(RunUntilCoroutine(condition, onSuccess, timeoutSeconds, onTimeout));
		}

		private static IEnumerator RunUntilCoroutine(Func<bool> condition, Action onSuccess, float timeout, Action onTimeout)
		{
			float timer = 0f;
			for (float checkInterval = 3f; timer < timeout; timer += checkInterval)
			{
				if (condition())
				{
					onSuccess();
					yield break;
				}
				yield return (object)new WaitForSeconds(checkInterval);
			}
			onTimeout?.Invoke();
		}
	}
	public static class GeneralUtil
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		public static Enemy FindClosestEnemy(Vector3 pos, EnemyTypes type)
		{
			//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)
			Type enemyType = EnemyMaps.GetEnemyType(type);
			if (enemyType == null)
			{
				mls.LogWarning((object)$"Unknown enemy type: {type}");
				return null;
			}
			Enemy result = null;
			float num = float.MaxValue;
			Enemy[] array = Object.FindObjectsOfType<Enemy>();
			foreach (Enemy val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent(enemyType) == (Object)null) && !HasController(val))
				{
					float num2 = Vector3.Distance(((Component)val).transform.position, pos);
					if (num2 < num)
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}

		public static Enemy FindClosestEnemyWithoutController(Vector3 pos, EnemyTypes type)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Type enemyType = EnemyMaps.GetEnemyType(type);
			if (enemyType == null)
			{
				mls.LogError((object)$"No wrapper type mapped for EnemyType {type}");
				return null;
			}
			Enemy result = null;
			float num = float.MaxValue;
			Object[] array = Object.FindObjectsOfType(enemyType);
			foreach (Object obj in array)
			{
				Enemy fieldValue = ReflectionUtils.GetFieldValue<Enemy>(obj, "enemy");
				if (!((Object)(object)fieldValue == (Object)null) && !HasController(fieldValue))
				{
					float num2 = Vector3.Distance(((Component)fieldValue).transform.position, pos);
					if (num2 < num)
					{
						result = fieldValue;
						num = num2;
					}
				}
			}
			return result;
		}

		public static bool HasController(Enemy enemy)
		{
			EnemyControllerBase[] array = Object.FindObjectsOfType<EnemyControllerBase>();
			foreach (EnemyControllerBase enemyControllerBase in array)
			{
				if ((Object)(object)enemyControllerBase != (Object)null && (Object)(object)enemyControllerBase.thisEnemyGameObject != (Object)null && ((Object)enemyControllerBase.thisEnemyGameObject).GetInstanceID() == ((enemy != null) ? new int?(((Object)((Component)enemy).gameObject).GetInstanceID()) : null))
				{
					return true;
				}
			}
			return false;
		}

		public static EnemyControllerBase FindEnemyController(int? actorNumber)
		{
			EnemyControllerBase[] array = Object.FindObjectsOfType<EnemyControllerBase>();
			foreach (EnemyControllerBase enemyControllerBase in array)
			{
				if (enemyControllerBase.controlActorNumber == actorNumber)
				{
					return enemyControllerBase;
				}
			}
			return null;
		}

		public static EnemyControllerBase FindEnemyController(Enemy enemy)
		{
			EnemyControllerBase[] array = Object.FindObjectsOfType<EnemyControllerBase>();
			foreach (EnemyControllerBase enemyControllerBase in array)
			{
				if (((Object)enemyControllerBase.thisEnemyEnemy).GetInstanceID() == ((Object)enemy).GetInstanceID())
				{
					return enemyControllerBase;
				}
			}
			return null;
		}

		public static List<Enemy> FindCloseEnemies(Vector3 pos, float range)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			List<Enemy> list = new List<Enemy>();
			Enemy[] array = Object.FindObjectsOfType<Enemy>();
			foreach (Enemy val in array)
			{
				float num = Vector3.Distance(((Component)val).gameObject.transform.position, pos);
				if (num <= range)
				{
					list.Add(val);
				}
			}
			return list;
		}

		public static void MoveEnemyToPos(Enemy enemy, Vector3 pos, EnemyTypes enemyType)
		{
			//IL_005e: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy == (Object)null)
			{
				mls.LogError((object)"No enemy provided to move.");
				return;
			}
			GameObject gameObject = ((Component)enemy).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				mls.LogError((object)"Enemy's GameObject is null.");
				return;
			}
			mls.LogMessage((object)$"Found enemy at {gameObject.transform.position}, moving it to {pos}.");
			Type enemyType2 = EnemyMaps.GetEnemyType(enemyType);
			if (enemyType2 != null)
			{
				Component component = gameObject.GetComponent(enemyType2);
				if ((Object)(object)component != (Object)null)
				{
					PropertyInfo property = enemyType2.GetProperty("enabled");
					if (property != null && property.CanWrite)
					{
						property.SetValue(component, false);
					}
					FieldInfo field = enemyType2.GetField("currentState");
					if (field != null)
					{
						object obj = Enum.GetValues(field.FieldType).Cast<object>().FirstOrDefault((object val) => val.ToString().Equals("Idle", StringComparison.OrdinalIgnoreCase));
						if (obj != null)
						{
							field.SetValue(component, obj);
						}
					}
					FieldInfo field2 = enemyType2.GetField("playerTarget");
					if (field2 != null)
					{
						ReflectionUtils.SetFieldValue(component, "playerTarget", null);
					}
				}
			}
			NavMeshAgent component2 = gameObject.GetComponent<NavMeshAgent>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.SetDestination(pos);
			}
			else
			{
				mls.LogWarning((object)"Enemy has no NavMeshAgent; cannot set destination.");
			}
			EnemyParent fieldValue = ReflectionUtils.GetFieldValue<EnemyParent>(enemy, "EnemyParent");
			if ((Object)(object)fieldValue != (Object)null)
			{
				fieldValue.SpawnedTimer = float.PositiveInfinity;
			}
			else
			{
				mls.LogWarning((object)"Could not access EnemyParent to prevent despawning.");
			}
			mls.LogMessage((object)$"Enemy moving toward {pos}.");
		}

		public static void ControlClosestEnemy(Vector3 pos, int actorNumber, EnemyTypes enemyType)
		{
			//IL_003c: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			if (!ReflectionUtils.GetFieldValue<bool>(PlayerAvatar.instance, "deadSet") && PhotonNetwork.LocalPlayer.ActorNumber == actorNumber)
			{
				mls.LogWarning((object)"Player is not dead, cannot control enemy.");
				return;
			}
			Enemy val = FindClosestEnemy(pos, enemyType);
			if ((Object)(object)val != (Object)null)
			{
				mls.LogInfo((object)$"Found closest enemy at {((Component)val).gameObject.transform.position}, transferring control to player.");
				BreakEnemyAI(val);
				Type controllerType = EnemyMaps.GetControllerType(enemyType);
				if (controllerType == null)
				{
					mls.LogError((object)$"No controller mapped for enemy type {enemyType}.");
					return;
				}
				Component component = ((Component)val).gameObject.GetComponent(controllerType);
				MonoBehaviour val2 = (MonoBehaviour)(object)((component is MonoBehaviour) ? component : null);
				if (val2 != null)
				{
					mls.LogInfo((object)"Controller already exists, using existing one.");
				}
				else
				{
					val2 = (MonoBehaviour)((Component)val).gameObject.AddComponent(controllerType);
				}
				Type enemyType2 = EnemyMaps.GetEnemyType(enemyType);
				Component component2 = ((Component)val).GetComponent(enemyType2);
				if ((Object)(object)component2 == (Object)null)
				{
					mls.LogError((object)$"Enemy is missing expected component of type {enemyType2}.");
					return;
				}
				ReflectionUtils.InvokeMethod(val2, "Setup", new object[2] { actorNumber, component2 });
				mls.LogInfo((object)"Control transferred to the enemy.");
			}
			else
			{
				mls.LogInfo((object)"No enemy found to transfer control.");
			}
		}

		public static void BreakEnemyAI(Enemy enemy)
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if ((Object)(object)enemy == (Object)null)
			{
				mls.LogError((object)"enemy is null, cannot break AI.");
				return;
			}
			mls.LogInfo((object)("Breaking AI for enemy of type " + ((object)enemy).GetType().Name));
			MonoBehaviour val = null;
			FieldInfo fieldInfo = null;
			MonoBehaviour[] components = ((Component)enemy).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val2 in components)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					fieldInfo = ((object)val2).GetType().GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (fieldInfo != null)
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				((Behaviour)val).enabled = false;
				mls.LogInfo((object)("Disabled component " + ((object)val).GetType().Name));
				try
				{
					Type fieldType = fieldInfo.FieldType;
					object value = Enum.Parse(fieldType, "Idle");
					ReflectionUtils.SetFieldValue(val, "currentState", value);
				}
				catch (Exception ex)
				{
					mls.LogWarning((object)("Could not set currentState to Idle: " + ex.Message));
				}
			}
			else
			{
				mls.LogWarning((object)"Could not find currentState field.");
			}
			EnemyRigidbody componentInChildren = ((Component)enemy).GetComponentInChildren<EnemyRigidbody>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = false;
				Rigidbody fieldValue = ReflectionUtils.GetFieldValue<Rigidbody>(componentInChildren, "rb");
				fieldValue.drag = 5000f;
				fieldValue.constraints = (RigidbodyConstraints)80;
				fieldValue.useGravity = true;
			}
			else
			{
				mls.LogWarning((object)"No EnemyRigidbody found.");
			}
			NavMeshAgent component = ((Component)enemy).GetComponent<NavMeshAgent>();
			if ((Object)(object)component != (Object)null)
			{
				component.isStopped = true;
				((Behaviour)component).enabled = false;
				mls.LogInfo((object)"Disabled NavMeshAgent.");
			}
			mls.LogInfo((object)"Enemy AI break complete.");
		}

		public static void EnableEnemyAI(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				mls.LogError((object)"enemy is null, cannot restore AI.");
				return;
			}
			mls.LogInfo((object)("Restoring AI for enemy of type " + ((object)enemy).GetType().Name));
			MonoBehaviour val = null;
			FieldInfo fieldInfo = null;
			MonoBehaviour[] components = ((Component)enemy).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val2 in components)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					fieldInfo = ((object)val2).GetType().GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (fieldInfo != null)
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				((Behaviour)val).enabled = true;
				mls.LogInfo((object)("Enabled component " + ((object)val).GetType().Name));
				try
				{
					Type fieldType = fieldInfo.FieldType;
					object value = Enum.Parse(fieldType, "Roam");
					ReflectionUtils.SetFieldValue(val, "currentState", value);
				}
				catch (Exception ex)
				{
					mls.LogWarning((object)("Could not set currentState to Roam: " + ex.Message));
				}
			}
			else
			{
				mls.LogWarning((object)"Could not find currentState field.");
			}
			EnemyRigidbody componentInChildren = ((Component)enemy).GetComponentInChildren<EnemyRigidbody>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = true;
				Rigidbody fieldValue = ReflectionUtils.GetFieldValue<Rigidbody>(componentInChildren, "rb");
				fieldValue.constraints = (RigidbodyConstraints)126;
				fieldValue.useGravity = false;
				fieldValue.drag = 0f;
			}
			else
			{
				mls.LogWarning((object)"No EnemyRigidbody found.");
			}
			NavMeshAgent component = ((Component)enemy).GetComponent<NavMeshAgent>();
			if ((Object)(object)component != (Object)null)
			{
				component.isStopped = false;
				((Behaviour)component).enabled = true;
				component.ResetPath();
				mls.LogInfo((object)"Re-enabled NavMeshAgent.");
			}
			mls.LogInfo((object)"Enemy AI restore complete.");
		}

		public static void RemoveSpawnedControllableEnemy(EnemyControllerBase enemyController)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemyController == (Object)null)
			{
				mls.LogWarning((object)"enemy controller is null, cannot destroy.");
				return;
			}
			Object.Destroy((Object)(object)enemyController);
			mls.LogInfo((object)"enemy controller destroyed.");
			if (PhotonNetwork.IsMasterClient)
			{
				PlayerController instance = PlayerController.instance;
				if ((Object)(object)enemyController.thisEnemyGameObject != (Object)null)
				{
					EnemyHealth fieldValue = ReflectionUtils.GetFieldValue<EnemyHealth>(enemyController.thisEnemyEnemy, "Health");
					ReflectionUtils.InvokeMethod(fieldValue, "Death", new object[1] { Vector3.zero });
					mls.LogMessage((object)"Killed controlled enemy");
				}
			}
		}

		public static void ReattatchCameraToPlayer()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			PlayerController pc = PlayerController.instance;
			Camera val = Camera.main ?? Object.FindObjectOfType<Camera>();
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).tag = "MainCamera";
				((Behaviour)val).enabled = true;
				((Component)val).gameObject.SetActive(true);
				if ((Object)(object)pc.cameraGameObject != (Object)null)
				{
					((Component)val).transform.SetParent(pc.cameraGameObject.transform);
					((Component)val).transform.localPosition = Vector3.zero;
					((Component)val).transform.localRotation = Quaternion.identity;
					((Component)val).transform.localScale = Vector3.one;
				}
				mls.LogInfo((object)"Camera moved back to player.");
			}
			else
			{
				mls.LogWarning((object)"No main camera found when trying to move back to player.");
			}
			if ((Object)(object)SpectateCamera.instance != (Object)null)
			{
				SpectateCamera.instance.StopSpectate();
				mls.LogInfo((object)"Stopped spectate camera.");
			}
			((Behaviour)pc).enabled = true;
			if ((Object)(object)pc.cameraGameObject != (Object)null)
			{
				pc.cameraGameObject.SetActive(true);
			}
			if ((Object)(object)pc.cameraGameObjectLocal != (Object)null)
			{
				pc.cameraGameObjectLocal.SetActive(true);
			}
			DelayUtility.RunAfterDelay(0.25f, delegate
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				CameraAim instance = CameraAim.Instance;
				if (instance != null)
				{
					instance.CameraAimSpawn(((Component)pc).transform.eulerAngles.y);
				}
			});
		}

		public static void ReleaseEnemyControlToSpectate()
		{
			if (PublicVars.EnemyCleanupInProgress)
			{
				mls.LogInfo((object)"Enemy cleanup already in progress — skipping duplicate call of ReleaseEnemyControlToSpectate");
				return;
			}
			PublicVars.EnemyCleanupInProgress = true;
			ReattatchCameraToPlayer();
			foreach (KeyValuePair<EnemyTypes, Type> controllerType in EnemyMaps.ControllerTypes)
			{
				Type value = controllerType.Value;
				Object obj = Object.FindObjectOfType(value);
				MonoBehaviour val = (MonoBehaviour)(object)((obj is MonoBehaviour) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
					mls.LogInfo((object)("Destroyed enemy controller of type " + value.Name + "."));
				}
			}
			if ((Object)(object)PlayerAvatar.instance != (Object)null && ReflectionUtils.GetFieldValue<bool>(PlayerAvatar.instance, "deadSet"))
			{
				mls.LogInfo((object)"Calling SetSpectate to enter true spectator mode...");
				PlayerAvatar.instance.SetSpectate();
				DelayUtility.RunAfterDelay(0.25f, delegate
				{
					//IL_00ee: 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_013a: Unknown result type (might be due to invalid IL or missing references)
					SpectateCamera instance = SpectateCamera.instance;
					if ((Object)(object)instance != (Object)null)
					{
						bool flag = ReflectionUtils.InvokeMethod<bool>(instance, "CheckState", new object[1] { Enum.Parse(typeof(State), "Normal") });
						Transform val2 = PlayerAvatar.instance?.spectatePoint;
						if ((Object)(object)val2 != (Object)null)
						{
							if (!flag)
							{
								ReflectionUtils.InvokeMethod(instance, "UpdateState", new object[1] { Enum.Parse(typeof(State), "Normal") });
								mls.LogWarning((object)"SpectateCamera was not in Normal state — forcing it.");
							}
							Camera fieldValue = ReflectionUtils.GetFieldValue<Camera>(instance, "MainCamera");
							Transform normalTransformDistance = instance.normalTransformDistance;
							if ((Object)(object)fieldValue != (Object)null && (Object)(object)normalTransformDistance != (Object)null)
							{
								((Component)fieldValue).transform.SetParent(normalTransformDistance);
								((Component)fieldValue).transform.localPosition = Vector3.zero;
								((Component)fieldValue).transform.localRotation = Quaternion.identity;
								((Component)fieldValue).tag = "MainCamera";
								((Behaviour)fieldValue).enabled = true;
								((Component)fieldValue).gameObject.SetActive(true);
								fieldValue.clearFlags = (CameraClearFlags)1;
								fieldValue.backgroundColor = Color.black;
							}
							else
							{
								mls.LogWarning((object)"Missing MainCamera or follow transform during spectate setup.");
							}
						}
					}
					else
					{
						mls.LogWarning((object)"SpectateCamera.instance was null.");
					}
					PublicVars.EnemyCleanupInProgress = false;
				});
			}
			else
			{
				mls.LogWarning((object)"PlayerAvatar.instance was null when trying to spectate.");
				PublicVars.EnemyCleanupInProgress = false;
			}
		}

		public static void SpawnEnemyAt(Vector3 spawnPos, int actorNumber, EnemyTypes enemyType)
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			mls.LogMessage((object)$"Spawning enemy at {spawnPos}");
			string prefabPath = EnemyMaps.GetPrefabPath(enemyType);
			GameObject val = Resources.Load<GameObject>(prefabPath);
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)$"Enemy prefab not found at path: {val}");
				return;
			}
			GameObject val2 = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject("Enemies/" + ((Object)val).name, spawnPos, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(val, spawnPos, Quaternion.identity));
			EnemyParent component = val2.GetComponent<EnemyParent>();
			if (Object.op_Implicit((Object)(object)component))
			{
				ReflectionUtils.SetFieldValue(component, "SetupDone", true);
				val2.GetComponentInChildren<Enemy>().EnemyTeleported(spawnPos);
				ReflectionUtils.SetFieldValue(LevelGenerator.Instance, "EnemiesSpawnTarget", ReflectionUtils.GetFieldValue<int>(LevelGenerator.Instance, "EnemiesSpawnTarget") + 1);
				EnemyDirector.instance.FirstSpawnPointAdd(component);
			}
			mls.LogInfo((object)"Enemy spawned successfully.");
			Enemy targetEnemy = null;
			DelayUtility.RunAfterDelay(10f, delegate
			{
				//IL_0003: 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)
				targetEnemy = FindClosestEnemyWithoutController(spawnPos, enemyType);
				MoveEnemyToPos(targetEnemy, spawnPos, enemyType);
			});
			DelayUtility.RunUntil(delegate
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)targetEnemy == (Object)null)
				{
					return false;
				}
				float num = Vector3.Distance(((Component)targetEnemy).transform.position, spawnPos);
				mls.LogMessage((object)$"Enemy distance: {num} from goal");
				return num < 1.5f;
			}, delegate
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				ControlClosestEnemy(spawnPos, actorNumber, enemyType);
				Player val3 = (PhotonNetwork.CurrentRoom.Players.ContainsKey(actorNumber) ? PhotonNetwork.CurrentRoom.Players[actorNumber] : null);
				if (val3 == null)
				{
					mls.LogError((object)$"Target player with actor number {actorNumber} not found.");
				}
				else
				{
					EnemySpawnerNetwork.Instance.ControlEnemy(spawnPos, actorNumber, enemyType);
				}
			}, 60f, delegate
			{
				//IL_0012: 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)
				mls.LogWarning((object)"enemy never reached goal, attempting to control anyway...");
				ControlClosestEnemy(spawnPos, actorNumber, enemyType);
				EnemySpawnerNetwork.Instance.ControlEnemy(spawnPos, actorNumber, enemyType);
			});
		}
	}
	public class ReflectionUtils
	{
		public static void InvokeMethod(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void InvokeMethod(object obj, Type forceType, string methodName, object[] parameters)
		{
			MethodInfo method = forceType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void SetPropertyValue(object obj, string propertyName, object value)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			property.SetValue(obj, value);
		}

		public static T InvokeMethod<T>(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)method.Invoke(obj, parameters);
		}

		public static T GetFieldValue<T>(object obj, string fieldName)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)field.GetValue(obj);
		}

		public static void SetFieldValue(object obj, string fieldName, object value)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			field.SetValue(obj, value);
		}
	}
}