Decompiled source of EnemyFriend v1.0.0

BepInEx/plugins/OsculeadorMod/OsculeadorMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("OsculeadorMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OsculeadorMod")]
[assembly: AssemblyTitle("OsculeadorMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OsculeadorMod;

[BepInPlugin("com.stream.repop", "RE_POP", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public static Plugin Instance;

	public static EnemySetup EnemySetup;

	public static GameObject EnemyPrefab;

	public static AudioClip AttackClip;

	public static AudioClip RoamClip;

	public static AudioClip AfterKillClip;

	public static AudioClip ReceiveDamageClip;

	public static AudioClip ReceiveDamageClip1;

	public static AudioClip ReceiveDamageClip2;

	public static AudioClip DeadClip;

	public static AnimationClip[] AnimClips;

	public static AudioClip RandomHitClip()
	{
		List<AudioClip> list = new List<AudioClip>(3);
		if ((Object)(object)ReceiveDamageClip != (Object)null)
		{
			list.Add(ReceiveDamageClip);
		}
		if ((Object)(object)ReceiveDamageClip1 != (Object)null)
		{
			list.Add(ReceiveDamageClip1);
		}
		if ((Object)(object)ReceiveDamageClip2 != (Object)null)
		{
			list.Add(ReceiveDamageClip2);
		}
		if (list.Count == 0)
		{
			return null;
		}
		return list[Random.Range(0, list.Count)];
	}

	private void Awake()
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Expected O, but got Unknown
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "osculeador"));
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"No se pudo cargar el AssetBundle 'osculeador'");
			return;
		}
		EnemyPrefab = val.LoadAsset<GameObject>("EnemyCustomFriend");
		AnimClips = val.LoadAllAssets<AnimationClip>();
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Clips del bundle ({0}): {1}", AnimClips.Length, string.Join(", ", Array.ConvertAll(AnimClips, (AnimationClip c) => ((Object)c).name))));
		EnemySetup = ScriptableObject.CreateInstance<EnemySetup>();
		PrefabRef val2 = new PrefabRef();
		((PrefabRef<GameObject>)(object)val2).SetPrefab(val, "EnemyCustomFriend");
		EnemySetup.spawnObjects = new List<PrefabRef> { val2 };
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "osculeador_atack.mp3"), delegate(AudioClip c)
		{
			AttackClip = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "osculeador_roam.mp3"), delegate(AudioClip c)
		{
			RoamClip = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "after_kill.mp3"), delegate(AudioClip c)
		{
			AfterKillClip = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "receive_damage.mp3"), delegate(AudioClip c)
		{
			ReceiveDamageClip = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "received_damaged1.mp3"), delegate(AudioClip c)
		{
			ReceiveDamageClip1 = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "received_damaged2.mp3"), delegate(AudioClip c)
		{
			ReceiveDamageClip2 = c;
		}));
		((MonoBehaviour)this).StartCoroutine(LoadAudio(Path.Combine(directoryName, "dead.mp3"), delegate(AudioClip c)
		{
			DeadClip = c;
		}));
		new Harmony("com.stream.repop").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Osculeador cargado!");
	}

	private static IEnumerator LoadAudio(string path, Action<AudioClip> onLoaded)
	{
		ManualLogSource log = Logger.CreateLogSource("RE_POP");
		if (!File.Exists(path))
		{
			log.LogWarning((object)("Audio no existe: " + path));
			yield break;
		}
		UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file:///" + path.Replace('\\', '/'), (AudioType)13);
		DownloadHandlerAudioClip dh = (DownloadHandlerAudioClip)req.downloadHandler;
		dh.streamAudio = false;
		yield return req.SendWebRequest();
		if ((int)req.result != 1)
		{
			log.LogWarning((object)("Audio fallo: " + path + " -> " + req.error));
			req.Dispose();
			yield break;
		}
		AudioClip clip = dh.audioClip;
		if ((Object)(object)clip == (Object)null)
		{
			log.LogWarning((object)("Audio clip null: " + path));
			req.Dispose();
			yield break;
		}
		((Object)clip).name = Path.GetFileNameWithoutExtension(path);
		while ((int)clip.loadState == 1)
		{
			yield return null;
		}
		if ((int)clip.loadState == 3)
		{
			log.LogWarning((object)("Audio decodificación fallo: " + path));
			req.Dispose();
		}
		else
		{
			log.LogInfo((object)$"Audio cargado: {((Object)clip).name} ({clip.length:F2}s, state={clip.loadState})");
			onLoaded(clip);
		}
	}
}
[HarmonyPatch(typeof(RunManager), "Awake")]
public class RunManagerPatch
{
	private static readonly BindingFlags BF = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static void Postfix(RunManager __instance)
	{
		if ((Object)(object)Plugin.EnemyPrefab == (Object)null)
		{
			return;
		}
		ManualLogSource val = Logger.CreateLogSource("RE_POP");
		string text = null;
		if ((Object)(object)Plugin.EnemySetup != (Object)null && Plugin.EnemySetup.spawnObjects != null && Plugin.EnemySetup.spawnObjects.Count > 0)
		{
			text = ((PrefabRef<GameObject>)(object)Plugin.EnemySetup.spawnObjects[0]).ResourcePath;
		}
		val.LogInfo((object)("EnemyPrefab ResourcePath='" + text + "'"));
		IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
		DefaultPool val2 = (DefaultPool)(object)((prefabPool is DefaultPool) ? prefabPool : null);
		if (val2 != null)
		{
			val2.ResourceCache["EnemyCustomFriend"] = Plugin.EnemyPrefab;
			if (!string.IsNullOrEmpty(text))
			{
				val2.ResourceCache[text] = Plugin.EnemyPrefab;
			}
			val.LogInfo((object)"Prefab registrado en DefaultPool");
		}
		object obj = typeof(RunManager).GetField("multiplayerPool", BF)?.GetValue(__instance);
		if ((object)obj?.GetType().GetField("ResourceCache", BF) == null)
		{
			obj?.GetType().GetProperty("ResourceCache", BF)?.DeclaringType?.GetField("ResourceCache", BF);
		}
		if (obj != null && obj.GetType().GetField("ResourceCache", BF)?.GetValue(obj) is Dictionary<string, GameObject> dictionary)
		{
			dictionary["EnemyCustomFriend"] = Plugin.EnemyPrefab;
			if (!string.IsNullOrEmpty(text))
			{
				dictionary[text] = Plugin.EnemyPrefab;
			}
		}
		if (typeof(RunManager).GetField("singleplayerPool", BF)?.GetValue(__instance) is Dictionary<string, Object> dictionary2)
		{
			dictionary2["EnemyCustomFriend"] = (Object)(object)Plugin.EnemyPrefab;
			if (!string.IsNullOrEmpty(text))
			{
				dictionary2[text] = (Object)(object)Plugin.EnemyPrefab;
			}
			val.LogInfo((object)"Prefab registrado en singleplayerPool");
		}
		else
		{
			val.LogWarning((object)"singleplayerPool no accesible");
		}
	}
}
[HarmonyPatch(typeof(EnemyParent), "Awake")]
public class EnemyParentAwakePatch
{
	private static readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static void Postfix(EnemyParent __instance)
	{
		//IL_0093: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c7: Expected O, but got Unknown
		//IL_04da: Unknown result type (might be due to invalid IL or missing references)
		//IL_04df: Unknown result type (might be due to invalid IL or missing references)
		//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0500: Unknown result type (might be due to invalid IL or missing references)
		//IL_0526: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((Component)__instance).transform.Find("Enable/Rigidbody/[VISUALS]/enemigo_animaciones") == (Object)null && (Object)(object)((Component)__instance).transform.Find("Enable/[VISUALS]/enemigo_animaciones") == (Object)null)
		{
			return;
		}
		ManualLogSource val = Logger.CreateLogSource("RE_POP");
		Transform val2 = ((Component)__instance).transform.Find("Enable/Controller");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		GameObject gameObject = ((Component)val2).gameObject;
		Transform val3 = ((Component)__instance).transform.Find("Enable/Rigidbody/[VISUALS]/enemigo_animaciones");
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = ((Component)__instance).transform.Find("Enable/[VISUALS]/enemigo_animaciones");
		}
		if ((Object)(object)val3 != (Object)null)
		{
			val3.localScale = Vector3.one * 3f;
			val3.localPosition = Vector3.zero;
			val3.localRotation = Quaternion.Euler(0f, 115f, 0f);
		}
		if ((Object)(object)__instance.EnableObject == (Object)null)
		{
			Transform val4 = ((Component)__instance).transform.Find("Enable");
			if ((Object)(object)val4 != (Object)null)
			{
				__instance.EnableObject = ((Component)val4).gameObject;
			}
		}
		Transform val5 = ((Component)__instance).transform.Find("Enable/Rigidbody");
		if ((Object)(object)val5 != (Object)null)
		{
			int num = 0;
			CapsuleCollider[] componentsInChildren = ((Component)val5).GetComponentsInChildren<CapsuleCollider>(true);
			foreach (CapsuleCollider val6 in componentsInChildren)
			{
				val6.height = Mathf.Max(val6.height, 4f);
				Vector3 center = val6.center;
				center.y = 1.5f;
				val6.center = center;
				val6.radius = Mathf.Max(val6.radius, 0.7f);
				((Collider)val6).isTrigger = false;
				((Component)val6).gameObject.layer = LayerMask.NameToLayer("PhysGrabObject");
				try
				{
					((Component)val6).gameObject.tag = "Phys Grab Object";
				}
				catch
				{
				}
				PhysGrabObjectCollider val7 = ((Component)val6).GetComponent<PhysGrabObjectCollider>();
				if ((Object)(object)val7 == (Object)null)
				{
					val7 = ((Component)val6).gameObject.AddComponent<PhysGrabObjectCollider>();
				}
				val7.colliderID = num++;
			}
			try
			{
				((Component)val5).gameObject.tag = "Phys Grab Object";
			}
			catch
			{
			}
			Rigidbody component = ((Component)val5).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.isKinematic = false;
				component.useGravity = true;
				component.mass = 1.5f;
				component.drag = 1f;
				component.angularDrag = 2f;
			}
			((Component)val5).gameObject.layer = LayerMask.NameToLayer("PhysGrabObject");
			PhysGrabObject component2 = ((Component)val5).GetComponent<PhysGrabObject>();
			if ((Object)(object)component2 != (Object)null)
			{
				typeof(PhysGrabObject).GetField("massOriginal", flags)?.SetValue(component2, 1.5f);
			}
			EnemyRigidbody component3 = ((Component)val5).GetComponent<EnemyRigidbody>();
			if ((Object)(object)component3 != (Object)null && (Object)(object)val2 != (Object)null)
			{
				FieldInfo field = typeof(EnemyRigidbody).GetField("followTarget", flags);
				if (field != null && field.GetValue(component3) == null)
				{
					field.SetValue(component3, val2);
				}
			}
		}
		__instance.SpawnedTimeMin = 999f;
		__instance.SpawnedTimeMax = 999f;
		__instance.DespawnedTimeMin = 3f;
		__instance.DespawnedTimeMax = 5f;
		object? obj3 = typeof(EnemyParent).GetField("Enemy", flags)?.GetValue(__instance);
		MonoBehaviour val8 = (MonoBehaviour)((obj3 is MonoBehaviour) ? obj3 : null);
		if ((Object)(object)val8 == (Object)null)
		{
			return;
		}
		Type type = ((object)val8).GetType();
		FieldInfo field2 = type.GetField("CenterTransform", flags);
		Transform val9 = ((Component)__instance).transform.Find("Enable/Rigidbody/Center");
		if (field2 != null && field2.GetValue(val8) == null && (Object)(object)val9 != (Object)null)
		{
			field2.SetValue(val8, val9);
			val.LogInfo((object)"CenterTransform asignado");
		}
		EnemyVision val10 = gameObject.GetComponent<EnemyVision>();
		if ((Object)(object)val10 == (Object)null)
		{
			val10 = gameObject.AddComponent<EnemyVision>();
			val10.VisionTransform = (((Object)(object)val9 != (Object)null) ? val9 : ((Component)val8).transform);
			val10.VisionDistance = 20f;
			type.GetField("Vision", flags)?.SetValue(val8, val10);
			type.GetField("HasVision", flags)?.SetValue(val8, true);
			int num2 = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) + LayerMask.GetMask(new string[1] { "HideTriggers" });
			type.GetField("VisionMask", flags)?.SetValue(val8, LayerMask.op_Implicit(num2));
			val.LogInfo((object)"EnemyVision agregado");
		}
		if (val10.onVisionTriggered == null)
		{
			val10.onVisionTriggered = new UnityEvent();
		}
		if ((Object)(object)gameObject.GetComponent<Light>() == (Object)null)
		{
			GameObject val11 = new GameObject("OsculeadorGlow");
			val11.transform.SetParent(val2);
			val11.transform.localPosition = new Vector3(0f, 1.5f, 0f);
			Light obj4 = val11.AddComponent<Light>();
			obj4.type = (LightType)2;
			obj4.color = new Color(0.1f, 1f, 0.3f);
			obj4.intensity = 4f;
			obj4.range = 7f;
			obj4.shadows = (LightShadows)0;
		}
		OsculeadorAI osculeadorAI = gameObject.GetComponent<OsculeadorAI>();
		if ((Object)(object)osculeadorAI == (Object)null)
		{
			osculeadorAI = gameObject.AddComponent<OsculeadorAI>();
		}
		osculeadorAI.SetEnemyMono(val8);
		osculeadorAI.SetEnemyParent(__instance);
		Transform val12 = ((Component)__instance).transform.Find("Enable/Rigidbody/[VISUALS]") ?? ((Component)__instance).transform.Find("Enable/[VISUALS]");
		if ((Object)(object)val12 != (Object)null)
		{
			osculeadorAI.SetVisualsTransform(val12);
		}
		Transform val13 = ((Component)__instance).transform.Find("Enable/Rigidbody");
		if ((Object)(object)val13 != (Object)null)
		{
			osculeadorAI.SetRigidbodyTransform(val13);
		}
		PhotonView val14 = ((Component)__instance).GetComponentInChildren<PhotonView>(true);
		if ((Object)(object)val14 == (Object)null)
		{
			val14 = ((Component)__instance).GetComponentInParent<PhotonView>();
		}
		if ((Object)(object)val14 != (Object)null)
		{
			OsculeadorNet osculeadorNet = ((Component)val14).gameObject.GetComponent<OsculeadorNet>();
			if ((Object)(object)osculeadorNet == (Object)null)
			{
				osculeadorNet = ((Component)val14).gameObject.AddComponent<OsculeadorNet>();
			}
			osculeadorNet.ai = osculeadorAI;
			osculeadorAI.net = osculeadorNet;
			val.LogInfo((object)$"OsculeadorNet enlazado en PhotonView {val14.ViewID}");
		}
		else
		{
			val.LogWarning((object)"No se encontró PhotonView para el Osculeador — animaciones/sonidos no se sincronizarán");
		}
		AudioSource[] components = gameObject.GetComponents<AudioSource>();
		AudioSource obj5 = ((components.Length != 0) ? components[0] : gameObject.AddComponent<AudioSource>());
		AudioSource val15 = ((components.Length > 1) ? components[1] : gameObject.AddComponent<AudioSource>());
		obj5.spatialBlend = 1f;
		obj5.rolloffMode = (AudioRolloffMode)1;
		obj5.maxDistance = 20f;
		obj5.loop = true;
		obj5.playOnAwake = false;
		val15.spatialBlend = 1f;
		val15.rolloffMode = (AudioRolloffMode)1;
		val15.maxDistance = 15f;
		val15.loop = false;
		val15.playOnAwake = false;
		if ((Object)(object)gameObject.GetComponent<Rigidbody>() == (Object)null)
		{
			Rigidbody obj6 = gameObject.AddComponent<Rigidbody>();
			obj6.isKinematic = true;
			obj6.useGravity = false;
		}
		if ((Object)(object)gameObject.GetComponent<OsculeadorHealth>() == (Object)null)
		{
			gameObject.AddComponent<OsculeadorHealth>();
		}
		if ((Object)(object)val3 != (Object)null && Plugin.AnimClips != null && Plugin.AnimClips.Length != 0)
		{
			Animator componentInChildren = ((Component)val3).GetComponentInChildren<Animator>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				string name = ((Object)((Component)componentInChildren).gameObject).name;
				RuntimeAnimatorController runtimeAnimatorController = componentInChildren.runtimeAnimatorController;
				val.LogInfo((object)("Animator encontrado en: " + name + ", controller=" + (((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "NULL")));
				((Behaviour)componentInChildren).enabled = true;
				osculeadorAI.InitPlayables(componentInChildren);
			}
			else
			{
				val.LogInfo((object)"Animator NO encontrado en el modelo");
			}
		}
	}
}
[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
public class EnemyParentSpawnPatch
{
	private static readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static void Postfix(EnemyParent __instance)
	{
		//IL_0042: 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_0091: 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_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((Component)__instance).transform.Find("Enable/Rigidbody/[VISUALS]/enemigo_animaciones") == (Object)null && (Object)(object)((Component)__instance).transform.Find("Enable/[VISUALS]/enemigo_animaciones") == (Object)null)
		{
			return;
		}
		ManualLogSource val = Logger.CreateLogSource("RE_POP");
		NavMeshHit val2 = default(NavMeshHit);
		if (!NavMesh.SamplePosition(((Component)__instance).transform.position, ref val2, 30f, -1))
		{
			val.LogWarning((object)$"SpawnRPC: no NavMesh cerca de {((Component)__instance).transform.position}");
			return;
		}
		((Component)__instance).transform.position = ((NavMeshHit)(ref val2)).position;
		val.LogInfo((object)$"Osculeador SPAWNED en {((NavMeshHit)(ref val2)).position}");
		Transform val3 = ((Component)__instance).transform.Find("Enable/Controller");
		if ((Object)(object)val3 == (Object)null)
		{
			return;
		}
		GameObject gameObject = ((Component)val3).gameObject;
		NavMeshAgent val4 = gameObject.GetComponent<NavMeshAgent>() ?? gameObject.AddComponent<NavMeshAgent>();
		val4.speed = 1f;
		val4.acceleration = 4f;
		val4.angularSpeed = 120f;
		val4.stoppingDistance = 0.5f;
		val4.radius = 0.4f;
		val4.height = 1.8f;
		val4.Warp(((NavMeshHit)(ref val2)).position);
		val4.updateRotation = false;
		EnemyNavMeshAgent val5 = gameObject.GetComponent<EnemyNavMeshAgent>() ?? gameObject.AddComponent<EnemyNavMeshAgent>();
		val.LogInfo((object)$"EnemyNavMeshAgent agregado, onNavMesh={val4.isOnNavMesh}");
		object? obj = typeof(EnemyParent).GetField("Enemy", flags)?.GetValue(__instance);
		MonoBehaviour val6 = (MonoBehaviour)((obj is MonoBehaviour) ? obj : null);
		if ((Object)(object)val6 != (Object)null)
		{
			Type type = ((object)val6).GetType();
			type.GetField("NavMeshAgent", flags)?.SetValue(val6, val5);
			type.GetField("HasNavMeshAgent", flags)?.SetValue(val6, true);
		}
		OsculeadorAI component = gameObject.GetComponent<OsculeadorAI>();
		if ((Object)(object)component != (Object)null)
		{
			component.InitNavAgent(val5);
		}
		if (!PhotonNetwork.IsMasterClient || !((Object)(object)component != (Object)null) || !((Object)(object)component.DecoyEnemy == (Object)null))
		{
			return;
		}
		try
		{
			GameObject val7 = PhotonNetwork.InstantiateRoomObject("Enemies/Enemy - Duck", ((Component)__instance).transform.position, Quaternion.identity, (byte)0, (object[])null);
			if (!((Object)(object)val7 != (Object)null))
			{
				return;
			}
			component.DecoyEnemy = val7;
			MonoBehaviour[] componentsInChildren = val7.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val8 in componentsInChildren)
			{
				if (val8 is OsculeadorAI)
				{
					continue;
				}
				string name = ((object)val8).GetType().Name;
				switch (name)
				{
				default:
					if (!name.StartsWith("EnemyDuck"))
					{
						continue;
					}
					break;
				case "EnemyDuck":
				case "Enemy":
				case "EnemyStateMachine":
					break;
				}
				((Behaviour)val8).enabled = false;
			}
			NavMeshAgent componentInChildren = val7.GetComponentInChildren<NavMeshAgent>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = false;
			}
			Renderer[] componentsInChildren2 = val7.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			Logger.CreateLogSource("RE_POP").LogInfo((object)"Decoy (Duck) spawneado para clientes sin mod");
		}
		catch (Exception ex)
		{
			Logger.CreateLogSource("RE_POP").LogWarning((object)("No se pudo spawnear decoy: " + ex.Message));
		}
	}
}
public class OsculeadorAI : MonoBehaviour
{
	private enum State
	{
		Idle,
		Roam,
		Investigate,
		GoToPlayer,
		PickupPlayer,
		MoveWithPlayer,
		AttackPlayer,
		Leave
	}

	private const string ANIM_WALK = "Armature|Armature|Armature|NlaTrack.005";

	private const string ANIM_ATTACK = "Armature|Armature|Armature|NlaTrack.002";

	private const string ANIM_IDLE = "Armature|Armature|Armature|NlaTrack";

	private const string ANIM_HIT = "Armature|Armature|NlaTrack.003";

	private float hitAnimTimer;

	private State currentState;

	private bool stateImpulse = true;

	private float stateTimer;

	private EnemyNavMeshAgent navAgent;

	private Animator animator;

	private MonoBehaviour enemyMono;

	private Enemy enemy;

	private EnemyParent enemyParent;

	private PlayerAvatar playerTarget;

	private Transform pickupPoint;

	private AudioSource srcAttack;

	private AudioSource srcRoam;

	private LayerMask visionBlockMask;

	private PlayableGraph graph;

	private AnimationPlayableOutput playableOutput;

	private AnimationClipPlayable currentPlayable;

	private string currentClipName;

	private bool graphInitialized;

	public OsculeadorNet net;

	private bool attackAnimActive;

	private GameObject sampleRoot;

	private AnimationClip sampleClip;

	private bool sampleLoop;

	private float sampleTime;

	private Vector3 sampleRootLocalPos;

	private Quaternion sampleRootLocalRot;

	private bool sampleRootCached;

	private Vector3 agentDestination;

	private Vector3 lastPosition;

	private bool wasMoving;

	private float roamAudioTimer;

	private Vector3 noisePoint;

	private bool hasNoiseLead;

	private float attackTimer;

	private int attackCount;

	private const int MAX_ATTACKS = 15;

	private const float ATTACK_PERIOD = 0.6f;

	private static readonly BindingFlags BF = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static readonly FieldInfo f_playerHealth = typeof(PlayerAvatar).GetField("playerHealth", BF);

	private static readonly MethodInfo m_enemyGetIndex = typeof(SemiFunc).GetMethod("EnemyGetIndex", BF | BindingFlags.Static);

	private static MethodInfo m_hurtOther;

	private static MethodInfo m_healthHeal;

	private const int DRAIN_PER_HIT = 5;

	private int totalDrained;

	private static readonly FieldInfo f_tumble = typeof(PlayerAvatar).GetField("tumble", BF);

	private static readonly FieldInfo f_localCamera = typeof(PlayerAvatar).GetField("localCameraTransform", BF) ?? typeof(PlayerAvatar).GetField("cameraTransform", BF) ?? typeof(PlayerAvatar).GetField("localCamera", BF);

	private static readonly FieldInfo f_isDisabled = typeof(PlayerAvatar).GetField("isDisabled", BF);

	private static readonly FieldInfo f_isCrouching = typeof(PlayerAvatar).GetField("isCrouching", BF);

	private static readonly FieldInfo f_isSprinting = typeof(PlayerAvatar).GetField("isSprinting", BF);

	private static readonly FieldInfo f_isTumbling = typeof(PlayerAvatar).GetField("isTumbling", BF);

	private static readonly FieldInfo f_visionFreeze = typeof(PlayerAvatar).GetField("enemyVisionFreezeTimer", BF);

	private static readonly MethodInfo m_fallDmgReset = typeof(PlayerAvatar).GetMethod("FallDamageResetSet", BF);

	private static readonly MethodInfo m_overrideMass = typeof(PhysGrabObject).GetMethod("OverrideMass", BF);

	private static readonly MethodInfo m_overrideDrag = typeof(PhysGrabObject).GetMethod("OverrideDrag", BF);

	private static readonly MethodInfo m_overrideAngDrag = typeof(PhysGrabObject).GetMethod("OverrideAngularDrag", BF);

	private MethodInfo m_TumbleRequest;

	private MethodInfo m_TumbleOverride;

	private MethodInfo m_TumbleEnemyHurt;

	private FieldInfo f_TumbleRb;

	private FieldInfo f_IsTumbling;

	private FieldInfo f_PhysGrabObj;

	private Transform visualsT;

	private Transform rigidbodyT;

	public GameObject DecoyEnemy;

	private float flashTimer;

	private SkinnedMeshRenderer[] cachedSmrs;

	private MaterialPropertyBlock mpb;

	private float otherAudioBlockTimer;

	private float lostSightTimer;

	private static FieldInfo f_enemyVision = typeof(Enemy).GetField("Vision", BindingFlags.Instance | BindingFlags.NonPublic);

	private static bool GetBool(FieldInfo f, PlayerAvatar p)
	{
		object obj = f?.GetValue(p);
		bool flag = default(bool);
		int num;
		if (obj is bool)
		{
			flag = (bool)obj;
			num = 1;
		}
		else
		{
			num = 0;
		}
		return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
	}

	private static float GetFloat(FieldInfo f, PlayerAvatar p)
	{
		object obj = f?.GetValue(p);
		if (obj is float)
		{
			return (float)obj;
		}
		return 0f;
	}

	private static bool IsDisabled(PlayerAvatar p)
	{
		if ((Object)(object)p == (Object)null)
		{
			return true;
		}
		object obj = f_isDisabled?.GetValue(p);
		bool flag = default(bool);
		int num;
		if (obj is bool)
		{
			flag = (bool)obj;
			num = 1;
		}
		else
		{
			num = 0;
		}
		return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
	}

	private void ResolveTumbleMethods(object tumble)
	{
		if (!(m_TumbleRequest != null))
		{
			Type type = tumble.GetType();
			m_TumbleRequest = type.GetMethod("TumbleRequest", BF);
			m_TumbleOverride = type.GetMethod("TumbleOverrideTime", BF);
			m_TumbleEnemyHurt = type.GetMethod("OverrideEnemyHurt", BF);
			f_TumbleRb = type.GetField("rb", BF);
			f_IsTumbling = type.GetField("isTumbling", BF);
			f_PhysGrabObj = type.GetField("physGrabObject", BF);
		}
	}

	public void SetEnemyMono(MonoBehaviour mono)
	{
		enemyMono = mono;
		enemy = (Enemy)(object)((mono is Enemy) ? mono : null);
	}

	public void SetEnemyParent(EnemyParent ep)
	{
		enemyParent = ep;
	}

	public void SetVisualsTransform(Transform t)
	{
		visualsT = t;
	}

	public void SetRigidbodyTransform(Transform t)
	{
		rigidbodyT = t;
	}

	public void FlashRed()
	{
		if ((Object)(object)net != (Object)null)
		{
			net.HostPlayHit();
		}
		else
		{
			FlashRedLocal();
		}
	}

	public void FlashRedLocal()
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		AudioClip val = Plugin.RandomHitClip();
		PauseRoamAudio(((Object)(object)val != (Object)null) ? val.length : 1.5f);
		if ((Object)(object)val != (Object)null)
		{
			AudioSource component = ((Component)this).GetComponent<AudioSource>();
			if ((Object)(object)component != (Object)null)
			{
				component.PlayOneShot(val);
			}
		}
		if (cachedSmrs == null || cachedSmrs.Length == 0)
		{
			Transform val2 = (((Object)(object)((Component)this).transform.root != (Object)null) ? ((Component)this).transform.root : ((Component)this).transform);
			cachedSmrs = ((Component)val2).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		}
		if (mpb == null)
		{
			mpb = new MaterialPropertyBlock();
		}
		flashTimer = 0.35f;
		AnimationClip val3 = FindClip("Armature|Armature|NlaTrack.003");
		if ((Object)(object)val3 != (Object)null)
		{
			hitAnimTimer = val3.length;
			PlayAnim("Armature|Armature|NlaTrack.003", loop: false);
		}
	}

	public void BeginAttackVisual()
	{
		attackAnimActive = true;
		PauseRoamAudio();
		EnsureClips();
		if ((Object)(object)srcAttack != (Object)null)
		{
			if ((Object)(object)srcAttack.clip == (Object)null && (Object)(object)Plugin.AttackClip != (Object)null)
			{
				srcAttack.clip = Plugin.AttackClip;
			}
			srcAttack.loop = true;
			if (!srcAttack.isPlaying)
			{
				srcAttack.Play();
			}
		}
		PlayAnim("Armature|Armature|Armature|NlaTrack.002", loop: true);
		wasMoving = false;
	}

	public void EndAttackVisual()
	{
		attackAnimActive = false;
		if ((Object)(object)srcAttack != (Object)null)
		{
			if (srcAttack.isPlaying)
			{
				srcAttack.Stop();
			}
			srcAttack.loop = false;
		}
	}

	public void PlayAfterKillLocal()
	{
		if (!((Object)(object)Plugin.AfterKillClip == (Object)null) && !((Object)(object)srcAttack == (Object)null))
		{
			PauseRoamAudio(Plugin.AfterKillClip.length);
			srcAttack.PlayOneShot(Plugin.AfterKillClip);
		}
	}

	public void PlayDeadLocal()
	{
		//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_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		ManualLogSource val = Logger.CreateLogSource("RE_POP");
		if ((Object)(object)Plugin.DeadClip == (Object)null)
		{
			val.LogWarning((object)"PlayDeadLocal: DeadClip es null");
			return;
		}
		if ((Object)(object)srcAttack != (Object)null)
		{
			srcAttack.loop = false;
			if (srcAttack.isPlaying)
			{
				srcAttack.Stop();
			}
		}
		if ((Object)(object)srcRoam != (Object)null && srcRoam.isPlaying)
		{
			srcRoam.Stop();
		}
		attackAnimActive = false;
		PauseRoamAudio(Plugin.DeadClip.length + 1f);
		GameObject val2 = new GameObject("OsculeadorDeadAudio");
		val2.transform.position = ((Component)this).transform.position;
		AudioSource obj = val2.AddComponent<AudioSource>();
		obj.clip = Plugin.DeadClip;
		obj.spatialBlend = 1f;
		obj.rolloffMode = (AudioRolloffMode)1;
		obj.maxDistance = 25f;
		obj.volume = 1f;
		obj.Play();
		Object.Destroy((Object)val2, Plugin.DeadClip.length + 1f);
		val.LogInfo((object)$"PlayDeadLocal disparado ({Plugin.DeadClip.length:F2}s)");
	}

	private void UpdateFlash()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		if (flashTimer <= 0f || cachedSmrs == null)
		{
			return;
		}
		flashTimer -= Time.deltaTime;
		float num = Mathf.Clamp01(flashTimer / 0.35f);
		Color val = Color.Lerp(Color.white, Color.red, num);
		Color val2 = Color.red * (num * 2f);
		SkinnedMeshRenderer[] array = cachedSmrs;
		foreach (SkinnedMeshRenderer val3 in array)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				((Renderer)val3).GetPropertyBlock(mpb);
				mpb.SetColor("_Color", val);
				mpb.SetColor("_BaseColor", val);
				mpb.SetColor("_EmissionColor", val2);
				((Renderer)val3).SetPropertyBlock(mpb);
			}
		}
	}

	public void InitPlayables(Animator anim)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		animator = anim;
		sampleRoot = ((Component)anim).gameObject;
		sampleRootLocalPos = sampleRoot.transform.localPosition;
		sampleRootLocalRot = sampleRoot.transform.localRotation;
		sampleRootCached = true;
		if (!graphInitialized)
		{
			animator.cullingMode = (AnimatorCullingMode)0;
			animator.applyRootMotion = false;
			animator.updateMode = (AnimatorUpdateMode)0;
			graph = PlayableGraph.Create("OsculeadorAnim_" + ((Object)this).GetInstanceID());
			((PlayableGraph)(ref graph)).SetTimeUpdateMode((DirectorUpdateMode)1);
			playableOutput = AnimationPlayableOutput.Create(graph, "Animation", animator);
			((PlayableGraph)(ref graph)).Play();
			graphInitialized = true;
			ManualLogSource val = Logger.CreateLogSource("RE_POP");
			object[] obj = new object[4]
			{
				((Object)((Component)animator).gameObject).name,
				null,
				null,
				null
			};
			Avatar avatar = animator.avatar;
			obj[1] = ((avatar != null) ? ((Object)avatar).name : null) ?? "NULL";
			obj[2] = animator.isHuman;
			obj[3] = animator.hasBoundPlayables;
			val.LogInfo((object)string.Format("PlayableGraph init. animator.gameObject={0} avatar={1} isHuman={2} hasBoundPlayables={3}", obj));
			SkinnedMeshRenderer[] componentsInChildren = ((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				string name = ((Object)((Component)val2).gameObject).name;
				Transform rootBone = val2.rootBone;
				string arg = ((rootBone != null) ? ((Object)rootBone).name : null) ?? "NULL";
				Transform[] bones = val2.bones;
				val.LogInfo((object)$"  SMR: {name} rootBone={arg} bones={((bones != null) ? bones.Length : 0)}");
			}
		}
	}

	private void OnDestroy()
	{
		if (graphInitialized && ((PlayableGraph)(ref graph)).IsValid())
		{
			((PlayableGraph)(ref graph)).Destroy();
		}
	}

	public void InitNavAgent(EnemyNavMeshAgent agent)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		navAgent = agent;
		lastPosition = ((Component)this).transform.position;
		if ((Object)(object)animator == (Object)null)
		{
			animator = ((Component)this).GetComponentInChildren<Animator>(true);
		}
		AudioSource[] components = ((Component)this).GetComponents<AudioSource>();
		srcAttack = ((components.Length != 0) ? components[0] : null);
		srcRoam = ((components.Length > 1) ? components[1] : null);
		GameObject val = new GameObject("PickupPoint");
		val.transform.SetParent(((Component)this).transform);
		val.transform.localPosition = new Vector3(0f, 1f, 2f);
		pickupPoint = val.transform;
		ChangeState(State.Idle);
		Logger.CreateLogSource("RE_POP").LogInfo((object)"OsculeadorAI: listo");
	}

	private void Start()
	{
		if ((Object)(object)animator == (Object)null)
		{
			animator = ((Component)this).GetComponentInChildren<Animator>(true);
		}
	}

	private AnimationClip FindClip(string clipName)
	{
		if (Plugin.AnimClips == null)
		{
			return null;
		}
		AnimationClip[] animClips = Plugin.AnimClips;
		foreach (AnimationClip val in animClips)
		{
			if ((Object)(object)val != (Object)null && ((Object)val).name == clipName)
			{
				return val;
			}
		}
		return null;
	}

	private void PlayAnim(string clipName, bool loop)
	{
		//IL_0077: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if (currentClipName == clipName && (Object)(object)sampleClip != (Object)null)
		{
			return;
		}
		AnimationClip val = FindClip(clipName);
		if ((Object)(object)val == (Object)null)
		{
			Logger.CreateLogSource("RE_POP").LogWarning((object)("PlayAnim: clip '" + clipName + "' no encontrado"));
			return;
		}
		sampleClip = val;
		sampleLoop = loop;
		sampleTime = 0f;
		currentClipName = clipName;
		if (graphInitialized)
		{
			if (PlayableExtensions.IsValid<AnimationClipPlayable>(currentPlayable))
			{
				PlayableExtensions.Destroy<AnimationClipPlayable>(currentPlayable);
			}
			currentPlayable = AnimationClipPlayable.Create(graph, val);
			((AnimationClipPlayable)(ref currentPlayable)).SetApplyFootIK(false);
			PlayableExtensions.SetSpeed<AnimationClipPlayable>(currentPlayable, 1.0);
			PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationClipPlayable>(playableOutput, currentPlayable);
		}
	}

	private void StopAnim()
	{
		//IL_0017: 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)
		sampleClip = null;
		currentClipName = null;
		if (graphInitialized && PlayableExtensions.IsValid<AnimationClipPlayable>(currentPlayable))
		{
			PlayableExtensions.SetSpeed<AnimationClipPlayable>(currentPlayable, 0.0);
		}
	}

	private void LateUpdate()
	{
		//IL_0088: 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)
		if (!((Object)(object)sampleClip == (Object)null) && !((Object)(object)sampleRoot == (Object)null))
		{
			sampleTime += Time.deltaTime;
			float num = (sampleLoop ? (sampleTime % sampleClip.length) : Mathf.Min(sampleTime, sampleClip.length));
			sampleClip.SampleAnimation(sampleRoot, num);
			if (sampleRootCached)
			{
				sampleRoot.transform.localPosition = sampleRootLocalPos;
				sampleRoot.transform.localRotation = sampleRootLocalRot;
			}
		}
	}

	private void EnsureClips()
	{
		if ((Object)(object)srcAttack != (Object)null && (Object)(object)srcAttack.clip == (Object)null && (Object)(object)Plugin.AttackClip != (Object)null)
		{
			srcAttack.clip = Plugin.AttackClip;
		}
		if ((Object)(object)srcRoam != (Object)null && (Object)(object)srcRoam.clip == (Object)null && (Object)(object)Plugin.RoamClip != (Object)null)
		{
			srcRoam.clip = Plugin.RoamClip;
		}
	}

	private void ChangeState(State s)
	{
		bool flag = currentState == State.AttackPlayer;
		currentState = s;
		stateImpulse = true;
		stateTimer = 0f;
		EnsureClips();
		if (s == State.AttackPlayer && !flag)
		{
			if ((Object)(object)net != (Object)null)
			{
				net.HostBeginAttack();
			}
			else
			{
				BeginAttackVisual();
			}
		}
		else if (flag && s != State.AttackPlayer)
		{
			if ((Object)(object)net != (Object)null)
			{
				net.HostEndAttack();
			}
			else
			{
				EndAttackVisual();
			}
		}
	}

	public void PauseRoamAudio(float cooldown = 2f)
	{
		if ((Object)(object)srcRoam != (Object)null && srcRoam.isPlaying)
		{
			srcRoam.Stop();
		}
		otherAudioBlockTimer = Mathf.Max(otherAudioBlockTimer, cooldown);
		roamAudioTimer = 0.4f;
	}

	private void UpdateRoamAudioShared(float speed)
	{
		if ((Object)(object)srcRoam == (Object)null)
		{
			return;
		}
		if ((Object)(object)srcRoam.clip == (Object)null && (Object)(object)Plugin.RoamClip != (Object)null)
		{
			srcRoam.clip = Plugin.RoamClip;
		}
		if ((Object)(object)srcRoam.clip == (Object)null)
		{
			return;
		}
		if (otherAudioBlockTimer > 0f)
		{
			otherAudioBlockTimer -= Time.deltaTime;
		}
		if (otherAudioBlockTimer > 0f)
		{
			return;
		}
		if (attackAnimActive)
		{
			roamAudioTimer = 0.4f;
		}
		else if ((Object)(object)srcAttack != (Object)null && srcAttack.isPlaying)
		{
			roamAudioTimer = 0.4f;
		}
		else if (!(speed <= 0.1f))
		{
			roamAudioTimer -= Time.deltaTime;
			if (roamAudioTimer <= 0f && !srcRoam.isPlaying)
			{
				srcRoam.Play();
				roamAudioTimer = srcRoam.clip.length + Random.Range(4f, 9f);
			}
		}
	}

	private void FixedUpdate()
	{
		if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)navAgent == (Object)null) && !((Object)(object)playerTarget == (Object)null) && !IsDisabled(playerTarget) && (currentState == State.PickupPlayer || currentState == State.MoveWithPlayer || currentState == State.AttackPlayer))
		{
			TumblePlayerPhysics();
		}
	}

	private void Update()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		UpdateFlash();
		bool num = SemiFunc.IsMasterClientOrSingleplayer();
		Vector3 val = ((Component)this).transform.position - lastPosition;
		float num2 = ((Vector3)(ref val)).magnitude / Mathf.Max(Time.deltaTime, 0.0001f);
		lastPosition = ((Component)this).transform.position;
		if (num && num2 > 0.1f)
		{
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val), Time.deltaTime * 8f);
			}
		}
		if (num)
		{
			if ((Object)(object)rigidbodyT != (Object)null)
			{
				rigidbodyT.rotation = ((Component)this).transform.rotation;
				rigidbodyT.position = ((Component)this).transform.position + Vector3.up * 0.65f;
			}
			else if ((Object)(object)visualsT != (Object)null)
			{
				visualsT.rotation = ((Component)this).transform.rotation;
			}
		}
		else if ((Object)(object)rigidbodyT != (Object)null)
		{
			((Component)this).transform.rotation = rigidbodyT.rotation;
		}
		if (hitAnimTimer > 0f)
		{
			hitAnimTimer -= Time.deltaTime;
		}
		bool flag = num2 > 0.1f && !attackAnimActive;
		if (hitAnimTimer <= 0f && !attackAnimActive)
		{
			if (flag)
			{
				PlayAnim("Armature|Armature|Armature|NlaTrack.005", loop: true);
			}
			else
			{
				PlayAnim("Armature|Armature|Armature|NlaTrack", loop: true);
			}
		}
		wasMoving = flag;
		if (SemiFunc.IsMainMenu() || SemiFunc.RunIsLobbyMenu())
		{
			if ((Object)(object)srcRoam != (Object)null && srcRoam.isPlaying)
			{
				srcRoam.Stop();
			}
			if ((Object)(object)srcAttack != (Object)null && srcAttack.isPlaying)
			{
				srcAttack.Stop();
			}
		}
		else if ((Object)(object)navAgent != (Object)null)
		{
			UpdateRoamAudioShared(num2);
		}
		if (!num)
		{
			return;
		}
		if ((Object)(object)DecoyEnemy != (Object)null)
		{
			DecoyEnemy.transform.position = ((Component)this).transform.position;
			DecoyEnemy.transform.rotation = ((Component)this).transform.rotation;
		}
		if ((Object)(object)navAgent == (Object)null)
		{
			return;
		}
		if ((Object)(object)enemy != (Object)null && enemy.IsStunned())
		{
			StopAnim();
			return;
		}
		if ((Object)(object)enemyParent != (Object)null)
		{
			Vector3 position = ((Component)this).transform.position;
			Vector3 val2 = ((Component)enemyParent).transform.position - position;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				((Component)enemyParent).transform.position = position;
				((Component)this).transform.localPosition = Vector3.zero;
			}
		}
		switch (currentState)
		{
		case State.Idle:
			StateIdle();
			break;
		case State.Roam:
			StateRoam();
			break;
		case State.Investigate:
			StateInvestigate();
			break;
		case State.GoToPlayer:
			StateGoToPlayer();
			break;
		case State.PickupPlayer:
			StatePickupPlayer();
			break;
		case State.MoveWithPlayer:
			StateMoveWithPlayer();
			break;
		case State.AttackPlayer:
			StateAttackPlayer();
			break;
		case State.Leave:
			StateLeave();
			break;
		}
	}

	private void StateInvestigate()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 12f;
			navAgent.SetDestination(noisePoint);
		}
		navAgent.UpdateAgent(2.2f, 7f);
		stateTimer -= Time.deltaTime;
		TryDetectPlayer();
		if (Vector3.Distance(((Component)this).transform.position, noisePoint) < 1.8f || stateTimer <= 0f || !navAgent.HasPath())
		{
			hasNoiseLead = false;
			ChangeState(State.Idle);
		}
	}

	private void StateIdle()
	{
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = Random.Range(2f, 5f);
			navAgent.ResetPath();
		}
		stateTimer -= Time.deltaTime;
		if (stateTimer <= 0f)
		{
			ChangeState(State.Roam);
			return;
		}
		TryDetectPlayer();
		if (currentState == State.Idle && TryDetectNoise())
		{
			ChangeState(State.Investigate);
		}
	}

	private void StateRoam()
	{
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 8f;
			SetRoamDestination();
		}
		navAgent.UpdateAgent(1.8f, 6f);
		stateTimer -= Time.deltaTime;
		if (stateTimer <= 0f || !navAgent.HasPath())
		{
			ChangeState(State.Idle);
			return;
		}
		TryDetectPlayer();
		if (currentState == State.Roam && TryDetectNoise())
		{
			ChangeState(State.Investigate);
		}
	}

	private bool TryDetectNoise()
	{
		//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_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		List<PlayerAvatar> list = GameDirector.instance?.PlayerList;
		if (list == null)
		{
			return false;
		}
		float num = 25f;
		Vector3 val = Vector3.zero;
		bool flag = false;
		foreach (PlayerAvatar item in list)
		{
			if (!((Object)(object)item == (Object)null) && !IsDisabled(item) && !(GetFloat(f_visionFreeze, item) > 0f) && (GetBool(f_isSprinting, item) || GetBool(f_isTumbling, item)) && !GetBool(f_isCrouching, item))
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)item).transform.position);
				if (!(num2 >= num))
				{
					num = num2;
					val = ((Component)item).transform.position;
					flag = true;
				}
			}
		}
		NavMeshHit val2 = default(NavMeshHit);
		if (flag && NavMesh.SamplePosition(val, ref val2, 5f, -1))
		{
			noisePoint = ((NavMeshHit)(ref val2)).position;
			hasNoiseLead = true;
			return true;
		}
		return false;
	}

	private void StateGoToPlayer()
	{
		//IL_00c5: 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_0110: Unknown result type (might be due to invalid IL or missing references)
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 8f;
			lostSightTimer = 0f;
		}
		stateTimer -= Time.deltaTime;
		if (!Object.op_Implicit((Object)(object)playerTarget) || IsDisabled(playerTarget) || stateTimer <= 0f)
		{
			playerTarget = null;
			ChangeState(State.Leave);
			return;
		}
		if (!CanSeePlayer(playerTarget))
		{
			lostSightTimer += Time.deltaTime;
			if (lostSightTimer >= 1.5f)
			{
				playerTarget = null;
				ChangeState(State.Roam);
				return;
			}
		}
		else
		{
			lostSightTimer = 0f;
		}
		navAgent.SetDestination(((Component)playerTarget).transform.position);
		navAgent.UpdateAgent(1.5f, 6f);
		FaceTarget(((Component)playerTarget).transform.position);
		if (Vector3.Distance(((Component)this).transform.position, ((Component)playerTarget).transform.position) < 1.8f)
		{
			ChangeState(State.AttackPlayer);
		}
	}

	private bool CanSeePlayer(PlayerAvatar p)
	{
		if ((Object)(object)p == (Object)null || (Object)(object)enemy == (Object)null || f_enemyVision == null)
		{
			return false;
		}
		object? value = f_enemyVision.GetValue(enemy);
		EnemyVision val = (EnemyVision)((value is EnemyVision) ? value : null);
		if ((Object)(object)val == (Object)null || val.VisionTriggered == null)
		{
			return false;
		}
		int num = (((Object)(object)p.photonView != (Object)null) ? p.photonView.ViewID : (-1));
		bool value2 = default(bool);
		return num >= 0 && val.VisionTriggered.TryGetValue(num, out value2) && value2;
	}

	private void StatePickupPlayer()
	{
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 1f;
		}
		if (!Object.op_Implicit((Object)(object)playerTarget) || IsDisabled(playerTarget))
		{
			ChangeState(State.Leave);
			return;
		}
		stateTimer -= Time.deltaTime;
		if (stateTimer <= 0f)
		{
			ChangeState(State.MoveWithPlayer);
		}
	}

	private void StateMoveWithPlayer()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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)
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 10f;
			agentDestination = FindFarPoint(((Component)playerTarget).transform.position);
		}
		if (!Object.op_Implicit((Object)(object)playerTarget) || IsDisabled(playerTarget))
		{
			ChangeState(State.Leave);
			return;
		}
		navAgent.SetDestination(agentDestination);
		navAgent.UpdateAgent(2.6f, 10f);
		stateTimer -= Time.deltaTime;
		if (Vector3.Distance(((Component)this).transform.position, agentDestination) < 1.5f || stateTimer <= 0f || !navAgent.HasPath())
		{
			navAgent.ResetPath();
			ChangeState(State.AttackPlayer);
		}
	}

	private void StateAttackPlayer()
	{
		//IL_004e: 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_00ad: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (stateImpulse)
		{
			stateImpulse = false;
			attackCount = 0;
			attackTimer = 0f;
		}
		if (!Object.op_Implicit((Object)(object)playerTarget) || IsDisabled(playerTarget))
		{
			ChangeState(State.Leave);
			return;
		}
		Vector3 val = ((Component)playerTarget).transform.forward;
		if (f_localCamera != null)
		{
			object? value = f_localCamera.GetValue(playerTarget);
			Transform val2 = (Transform)((value is Transform) ? value : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 forward = val2.forward;
				forward.y = 0f;
				if (((Vector3)(ref forward)).sqrMagnitude > 0.001f)
				{
					val = ((Vector3)(ref forward)).normalized;
				}
			}
		}
		Vector3 val3 = -val * 0.8f;
		Vector3 val4 = ((Component)playerTarget).transform.position + val3;
		if (Vector3.Distance(((Component)this).transform.position, ((Component)playerTarget).transform.position) > 3f)
		{
			ChangeState(State.GoToPlayer);
			return;
		}
		navAgent.ResetPath();
		((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val4, Time.deltaTime * 8f);
		Vector3 val5 = ((Component)playerTarget).transform.position - ((Component)this).transform.position;
		val5.y = 0f;
		if (((Vector3)(ref val5)).sqrMagnitude > 0.001f)
		{
			((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val5), Time.deltaTime * 10f);
		}
		attackTimer -= Time.deltaTime;
		if (attackTimer <= 0f)
		{
			attackTimer = 0.6f;
			SuckHP();
			attackCount++;
			if (attackCount >= 15)
			{
				ChangeState(State.Leave);
			}
		}
	}

	private void SuckHP()
	{
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)playerTarget == (Object)null)
		{
			return;
		}
		object obj = f_playerHealth?.GetValue(playerTarget);
		if (obj == null)
		{
			return;
		}
		if (m_hurtOther == null)
		{
			m_hurtOther = obj.GetType().GetMethod("HurtOther", BF);
		}
		int num = 0;
		if (m_enemyGetIndex != null && (Object)(object)enemy != (Object)null && m_enemyGetIndex.Invoke(null, new object[1] { enemy }) is int num2)
		{
			num = num2;
		}
		m_hurtOther?.Invoke(obj, new object[5]
		{
			5,
			((Component)playerTarget).transform.position,
			false,
			num,
			false
		});
		totalDrained += 5;
		FieldInfo field = obj.GetType().GetField("health", BF);
		if (field != null && field.GetValue(obj) is int num3 && num3 <= 0)
		{
			if ((Object)(object)net != (Object)null)
			{
				net.HostPlayAfterKill();
			}
			else
			{
				PlayAfterKillLocal();
			}
		}
		object obj2 = typeof(Enemy).GetField("Health", BF)?.GetValue(enemy);
		if (obj2 != null)
		{
			if (m_healthHeal == null)
			{
				m_healthHeal = obj2.GetType().GetMethod("Heal", BF);
			}
			m_healthHeal?.Invoke(obj2, new object[1] { 5 });
		}
	}

	private void StateLeave()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		if (stateImpulse)
		{
			stateImpulse = false;
			stateTimer = 6f;
			agentDestination = (((Object)(object)playerTarget != (Object)null) ? FindFarPoint(((Component)playerTarget).transform.position) : FindFarPoint(((Component)this).transform.position + Random.insideUnitSphere * 20f));
			playerTarget = null;
		}
		navAgent.SetDestination(agentDestination);
		navAgent.UpdateAgent(1.8f, 6f);
		stateTimer -= Time.deltaTime;
		if (stateTimer <= 0f || !navAgent.HasPath())
		{
			ChangeState(State.Idle);
		}
	}

	private void TryDetectPlayer()
	{
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemy == (Object)null || f_enemyVision == null)
		{
			return;
		}
		object? value = f_enemyVision.GetValue(enemy);
		EnemyVision val = (EnemyVision)((value is EnemyVision) ? value : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Dictionary<int, bool> visionTriggered = val.VisionTriggered;
		if (visionTriggered == null)
		{
			return;
		}
		PlayerAvatar val2 = null;
		float num = float.MaxValue;
		List<PlayerAvatar> list = GameDirector.instance?.PlayerList;
		if (list == null)
		{
			return;
		}
		foreach (PlayerAvatar item in list)
		{
			if ((Object)(object)item == (Object)null || IsDisabled(item) || GetFloat(f_visionFreeze, item) > 0f)
			{
				continue;
			}
			int num2 = (((Object)(object)item.photonView != (Object)null) ? item.photonView.ViewID : (-1));
			if (num2 >= 0 && visionTriggered.TryGetValue(num2, out var value2) && value2)
			{
				float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)item).transform.position);
				if (num3 < num)
				{
					num = num3;
					val2 = item;
				}
			}
		}
		if ((Object)(object)val2 != (Object)null)
		{
			playerTarget = val2;
			ChangeState(State.GoToPlayer);
		}
	}

	private void FaceTarget(Vector3 target)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = target - ((Component)this).transform.position;
		val.y = 0f;
		if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
		{
			((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val), Time.deltaTime * 10f);
		}
	}

	private void SetRoamDestination()
	{
		//IL_004c: 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_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)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints;
		NavMeshHit val = default(NavMeshHit);
		if (list != null && list.Count > 0)
		{
			navAgent.SetDestination(((Component)list[Random.Range(0, list.Count)]).transform.position);
		}
		else if (NavMesh.SamplePosition(((Component)this).transform.position + Random.insideUnitSphere * 15f, ref val, 15f, -1))
		{
			navAgent.SetDestination(((NavMeshHit)(ref val)).position);
		}
	}

	private Vector3 FindFarPoint(Vector3 awayFrom)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints;
		Vector3 position = ((Component)this).transform.position;
		float num = 0f;
		if (list != null)
		{
			foreach (LevelPoint item in list)
			{
				float num2 = Vector3.Distance(((Component)item).transform.position, awayFrom);
				if (num2 > num)
				{
					num = num2;
					position = ((Component)item).transform.position;
				}
			}
		}
		return position;
	}

	private void TumblePlayerPhysics()
	{
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)pickupPoint == (Object)null)
		{
			return;
		}
		object obj = f_tumble?.GetValue(playerTarget);
		if (obj == null)
		{
			return;
		}
		ResolveTumbleMethods(obj);
		MonoBehaviour val = (MonoBehaviour)((obj is MonoBehaviour) ? obj : null);
		if (!((Object)(object)val == (Object)null))
		{
			if (!(f_IsTumbling != null) || !(bool)f_IsTumbling.GetValue(obj))
			{
				m_TumbleRequest?.Invoke(obj, new object[2] { true, false });
			}
			m_TumbleOverride?.Invoke(obj, new object[1] { 1f });
			m_fallDmgReset?.Invoke(playerTarget, new object[1] { 0.1f });
			m_TumbleEnemyHurt?.Invoke(obj, new object[1] { 0.1f });
			object? obj2 = f_PhysGrabObj?.GetValue(obj);
			PhysGrabObject val2 = (PhysGrabObject)((obj2 is PhysGrabObject) ? obj2 : null);
			if ((Object)(object)val2 != (Object)null)
			{
				m_overrideMass?.Invoke(val2, new object[2] { 1f, 0.1f });
				m_overrideDrag?.Invoke(val2, new object[2] { 1f, 0.1f });
				m_overrideAngDrag?.Invoke(val2, new object[2] { 2f, 0.1f });
			}
			object? obj3 = f_TumbleRb?.GetValue(obj);
			Rigidbody val3 = (Rigidbody)((obj3 is Rigidbody) ? obj3 : null);
			if ((Object)(object)val3 != (Object)null)
			{
				float num = ((currentState == State.AttackPlayer) ? 1.5f : 1f);
				Vector3 val4 = SemiFunc.PhysFollowPosition(((Component)val).transform.position, pickupPoint.position, val3.velocity, 10f * num);
				val3.AddForce(val4 * (10f * Time.fixedDeltaTime * num), (ForceMode)1);
			}
		}
	}
}
public class OsculeadorHealth : MonoBehaviour
{
	private const float MAX_HP = 60f;

	private float hp = 60f;

	private float lastHitTime;

	private void OnCollisionEnter(Collision col)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Vector3 impulse = col.impulse;
		float magnitude = ((Vector3)(ref impulse)).magnitude;
		if (magnitude > 3f)
		{
			TakeDamage(magnitude * 0.5f);
		}
	}

	private void OnTriggerEnter(Collider other)
	{
		//IL_0012: 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)
		Rigidbody attachedRigidbody = other.attachedRigidbody;
		if ((Object)(object)attachedRigidbody == (Object)null)
		{
			return;
		}
		Vector3 velocity = attachedRigidbody.velocity;
		float magnitude = ((Vector3)(ref velocity)).magnitude;
		if (!(magnitude < 5f))
		{
			float num = magnitude * attachedRigidbody.mass * 0.4f;
			if (num > 1f)
			{
				TakeDamage(num);
			}
		}
	}

	public void TakeDamage(float amount)
	{
		if (Time.time - lastHitTime < 0.1f)
		{
			return;
		}
		lastHitTime = Time.time;
		hp -= amount;
		Logger.CreateLogSource("RE_POP").LogInfo((object)$"Daño {amount:F1} -> hp={hp:F1}");
		if (!(hp > 0f))
		{
			EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.Despawn();
			}
			else
			{
				Object.Destroy((Object)(object)((Component)((Component)this).transform.root).gameObject);
			}
		}
	}
}
[HarmonyPatch(typeof(EnemyHealth), "DeathImpulseRPC")]
public class EnemyHealthDeathPatch
{
	private static void Postfix(EnemyHealth __instance)
	{
		EnemyParent componentInParent = ((Component)__instance).GetComponentInParent<EnemyParent>();
		if ((Object)(object)componentInParent == (Object)null || componentInParent.enemyName != "Osculeador")
		{
			return;
		}
		OsculeadorAI componentInChildren = ((Component)__instance).GetComponentInChildren<OsculeadorAI>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			if ((Object)(object)componentInChildren.net != (Object)null)
			{
				componentInChildren.net.HostPlayDead();
			}
			else
			{
				componentInChildren.PlayDeadLocal();
			}
		}
		componentInParent.Despawn();
		componentInParent.SpawnedTimeMin = 99999f;
		componentInParent.SpawnedTimeMax = 99999f;
		Object.Destroy((Object)(object)((Component)componentInParent).gameObject, 5f);
	}
}
[HarmonyPatch(typeof(EnemyHealth), "Hurt")]
public class EnemyHealthHurtPatch
{
	private static void Postfix(EnemyHealth __instance)
	{
		EnemyParent componentInParent = ((Component)__instance).GetComponentInParent<EnemyParent>();
		if ((Object)(object)componentInParent == (Object)null || componentInParent.enemyName != "Osculeador" || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		OsculeadorAI componentInChildren = ((Component)__instance).GetComponentInChildren<OsculeadorAI>(true);
		if (!((Object)(object)componentInChildren == (Object)null))
		{
			if ((Object)(object)componentInChildren.net != (Object)null)
			{
				componentInChildren.net.HostPlayHit();
			}
			else
			{
				componentInChildren.FlashRedLocal();
			}
		}
	}
}
public class OsculeadorNet : MonoBehaviour
{
	public OsculeadorAI ai;

	private PhotonView pv;

	private void Awake()
	{
		pv = ((Component)this).GetComponent<PhotonView>();
	}

	public void HostBeginAttack()
	{
		if ((Object)(object)pv != (Object)null)
		{
			pv.RPC("RPC_BeginAttack", (RpcTarget)0, Array.Empty<object>());
		}
		else if ((Object)(object)ai != (Object)null)
		{
			ai.BeginAttackVisual();
		}
	}

	public void HostEndAttack()
	{
		if ((Object)(object)pv != (Object)null)
		{
			pv.RPC("RPC_EndAttack", (RpcTarget)0, Array.Empty<object>());
		}
		else if ((Object)(object)ai != (Object)null)
		{
			ai.EndAttackVisual();
		}
	}

	public void HostPlayHit()
	{
		if ((Object)(object)pv != (Object)null)
		{
			pv.RPC("RPC_PlayHit", (RpcTarget)0, Array.Empty<object>());
		}
		else if ((Object)(object)ai != (Object)null)
		{
			ai.FlashRedLocal();
		}
	}

	public void HostPlayAfterKill()
	{
		if ((Object)(object)pv != (Object)null)
		{
			pv.RPC("RPC_PlayAfterKill", (RpcTarget)0, Array.Empty<object>());
		}
		else if ((Object)(object)ai != (Object)null)
		{
			ai.PlayAfterKillLocal();
		}
	}

	public void HostPlayDead()
	{
		if ((Object)(object)pv != (Object)null)
		{
			pv.RPC("RPC_PlayDead", (RpcTarget)0, Array.Empty<object>());
		}
		else if ((Object)(object)ai != (Object)null)
		{
			ai.PlayDeadLocal();
		}
	}

	[PunRPC]
	private void RPC_BeginAttack()
	{
		if ((Object)(object)ai != (Object)null)
		{
			ai.BeginAttackVisual();
		}
	}

	[PunRPC]
	private void RPC_EndAttack()
	{
		if ((Object)(object)ai != (Object)null)
		{
			ai.EndAttackVisual();
		}
	}

	[PunRPC]
	private void RPC_PlayHit()
	{
		if ((Object)(object)ai != (Object)null)
		{
			ai.FlashRedLocal();
		}
	}

	[PunRPC]
	private void RPC_PlayAfterKill()
	{
		if ((Object)(object)ai != (Object)null)
		{
			ai.PlayAfterKillLocal();
		}
	}

	[PunRPC]
	private void RPC_PlayDead()
	{
		if ((Object)(object)ai != (Object)null)
		{
			ai.PlayDeadLocal();
		}
	}
}
[HarmonyPatch(typeof(EnemyDirector), "AmountSetup")]
public class EnemyDirectorPatch
{
	private static void Prefix(EnemyDirector __instance)
	{
		if (!((Object)(object)Plugin.EnemySetup == (Object)null))
		{
			if (!__instance.enemiesDifficulty1.Contains(Plugin.EnemySetup))
			{
				__instance.enemiesDifficulty1.Add(Plugin.EnemySetup);
			}
			if (!__instance.enemiesDifficulty2.Contains(Plugin.EnemySetup))
			{
				__instance.enemiesDifficulty2.Add(Plugin.EnemySetup);
			}
			if (!__instance.enemiesDifficulty3.Contains(Plugin.EnemySetup))
			{
				__instance.enemiesDifficulty3.Add(Plugin.EnemySetup);
			}
		}
	}
}
[HarmonyPatch(typeof(LevelGenerator), "GenerateDone")]
public class GenerateDoneTestPatch
{
	private static bool firedThisGen;

	private static void Postfix(LevelGenerator __instance)
	{
		ManualLogSource val = Logger.CreateLogSource("RE_POP_TEST");
		object arg = __instance.Generated;
		object arg2 = SemiFunc.IsMasterClientOrSingleplayer();
		RunManager instance = RunManager.instance;
		object arg3;
		if (instance == null)
		{
			arg3 = null;
		}
		else
		{
			Level levelCurrent = instance.levelCurrent;
			arg3 = ((levelCurrent != null) ? ((Object)levelCurrent).name : null);
		}
		val.LogInfo((object)$"GenerateDone postfix. Generated={arg} master={arg2} level={arg3}");
		if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)RunManager.instance == (Object)null))
		{
			Level levelCurrent2 = RunManager.instance.levelCurrent;
			if ((Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelLobby || (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelLobbyMenu || (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelMainMenu || (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelTutorial || SemiFunc.IsLevelShop(levelCurrent2))
			{
				val.LogInfo((object)"Filtrado por tipo de nivel");
				return;
			}
			if (firedThisGen)
			{
				val.LogInfo((object)"Ya disparado en esta generación");
				return;
			}
			firedThisGen = true;
			((MonoBehaviour)__instance).StartCoroutine(TestSpawnRunner.RunRoutine());
		}
	}
}
[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
public class ChangeLevelResetPatch
{
	private static void Postfix()
	{
		GenerateDoneTestPatch_ResetFlag();
	}

	public static void GenerateDoneTestPatch_ResetFlag()
	{
		typeof(GenerateDoneTestPatch).GetField("firedThisGen", BindingFlags.Static | BindingFlags.NonPublic)?.SetValue(null, false);
	}
}
public static class TestSpawnRunner
{
	private static bool dumpedKeys;

	public static IEnumerator RunRoutine()
	{
		ManualLogSource log = Logger.CreateLogSource("RE_POP_TEST");
		log.LogInfo((object)"RunRoutine arrancó");
		PlayerAvatar player = null;
		float waited = 0f;
		while (waited < 30f)
		{
			player = SemiFunc.PlayerAvatarLocal();
			if ((Object)(object)player != (Object)null)
			{
				Vector3 position = ((Component)player).transform.position;
				if (((Vector3)(ref position)).sqrMagnitude > 0.5f)
				{
					break;
				}
			}
			waited += 0.5f;
			yield return (object)new WaitForSeconds(0.5f);
		}
		if ((Object)(object)player == (Object)null)
		{
			log.LogWarning((object)$"No PlayerAvatarLocal tras {waited}s");
			yield break;
		}
		log.LogInfo((object)$"Player listo tras {waited:F1}s pos={((Component)player).transform.position}");
		yield return (object)new WaitForSeconds(1f);
		DoSpawn(player, log);
	}

	private static void DoSpawn(PlayerAvatar player, ManualLogSource log)
	{
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: 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_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		GameManager instance = GameManager.instance;
		log.LogInfo((object)$"DoSpawn arrancó. gameMode={((instance != null) ? new int?(instance.gameMode) : ((int?)null))}");
		if ((Object)(object)Plugin.EnemyPrefab != (Object)null)
		{
			try
			{
				Vector3 position = ((Component)player).transform.position;
				LevelPoint val = SemiFunc.LevelPointGet(position, 8f, 20f) ?? SemiFunc.LevelPointGet(position, 0f, 999f);
				Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : (position + new Vector3(6f, 0f, 0f)));
				GameObject val3;
				if (!((Object)(object)GameManager.instance != (Object)null) || GameManager.instance.gameMode == 0)
				{
					val3 = Object.Instantiate<GameObject>(Plugin.EnemyPrefab, val2, Quaternion.identity);
				}
				else
				{
					string text = ((Plugin.EnemySetup?.spawnObjects != null && Plugin.EnemySetup.spawnObjects.Count > 0) ? ((PrefabRef<GameObject>)(object)Plugin.EnemySetup.spawnObjects[0]).ResourcePath : "EnemyCustomFriend");
					log.LogInfo((object)("Spawn MP con resPath='" + text + "'"));
					val3 = PhotonNetwork.InstantiateRoomObject(text, val2, Quaternion.identity, (byte)0, (object[])null);
				}
				log.LogInfo((object)string.Format("Osculeador instanciado en {0} -> {1}", val2, ((Object)(object)val3 != (Object)null) ? "OK" : "NULL"));
				if ((Object)(object)val3 != (Object)null)
				{
					EnemyParent component = val3.GetComponent<EnemyParent>();
					if ((Object)(object)component != (Object)null)
					{
						typeof(EnemyParent).GetField("SetupDone", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(component, true);
					}
					Enemy componentInChildren = val3.GetComponentInChildren<Enemy>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.EnemyTeleported(val2);
					}
				}
			}
			catch (Exception arg)
			{
				log.LogError((object)$"Spawn Osculeador FAIL: {arg}");
			}
		}
		Vector3 val4 = ((Component)player).transform.position + Vector3.up * 1.5f;
		SpawnItem("Item Gun Handgun", val4 + ((Component)player).transform.forward * 0.5f, log);
		for (int i = 0; i < 10; i++)
		{
			float num = (float)i / 10f * MathF.PI * 2f;
			Vector3 pos = val4 + new Vector3(Mathf.Cos(num) * 0.6f, (float)i * 0.1f, Mathf.Sin(num) * 0.6f);
			SpawnItem("Item Upgrade Player Grab Strength", pos, log);
		}
	}

	private static void SpawnItem(string itemName, Vector3 pos, ManualLogSource log)
	{
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		StatsManager instance = StatsManager.instance;
		if ((Object)(object)instance == (Object)null || instance.itemDictionary == null)
		{
			log.LogWarning((object)"StatsManager no listo");
			return;
		}
		if (!dumpedKeys)
		{
			dumpedKeys = true;
			log.LogInfo((object)string.Format("itemDictionary keys ({0}): {1}", instance.itemDictionary.Count, string.Join(" | ", instance.itemDictionary.Keys)));
		}
		Item value = null;
		if (!instance.itemDictionary.TryGetValue(itemName, out value))
		{
			foreach (KeyValuePair<string, Item> item in instance.itemDictionary)
			{
				if (item.Key != null && item.Key.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					value = item.Value;
					log.LogInfo((object)("Match parcial key: '" + itemName + "' -> '" + item.Key + "'"));
					break;
				}
			}
		}
		if ((Object)(object)value == (Object)null)
		{
			foreach (KeyValuePair<string, Item> item2 in instance.itemDictionary)
			{
				if ((Object)(object)item2.Value != (Object)null && item2.Value.itemName != null && item2.Value.itemName.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					value = item2.Value;
					log.LogInfo((object)("Match por itemName: '" + itemName + "' -> '" + item2.Value.itemName + "' key='" + item2.Key + "'"));
					break;
				}
			}
		}
		if ((Object)(object)value == (Object)null)
		{
			log.LogWarning((object)("Item '" + itemName + "' no encontrado"));
			return;
		}
		if (value.prefab == null || string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath))
		{
			log.LogWarning((object)("PrefabRef vacío para '" + itemName + "'"));
			return;
		}
		try
		{
			GameObject val;
			if (!((Object)(object)GameManager.instance != (Object)null) || GameManager.instance.gameMode == 0)
			{
				GameObject prefab = ((PrefabRef<GameObject>)(object)value.prefab).Prefab;
				if ((Object)(object)prefab == (Object)null)
				{
					log.LogWarning((object)("Prefab null para '" + itemName + "'"));
					return;
				}
				val = Object.Instantiate<GameObject>(prefab, pos, Quaternion.identity);
			}
			else
			{
				val = PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath, pos, Quaternion.identity, (byte)0, (object[])null);
			}
			log.LogInfo((object)string.Format("Spawn '{0}' en {1} -> {2}", itemName, pos, ((Object)(object)val != (Object)null) ? "OK" : "NULL"));
		}
		catch (Exception ex)
		{
			log.LogWarning((object)("Spawn fallido '" + itemName + "': " + ex.Message));
		}
	}
}
public class _ObsoleteTestSpawnRunner
{
	private ManualLogSource log;

	private string lastSceneKey = "";

	private bool firedThisLevel;

	private float settleTimer;

	private bool dumpedKeys;

	private float heartbeatTimer;

	private int frameCount;

	private float diagTimer;

	private void Awake()
	{
		log = Logger.CreateLogSource("RE_POP_TEST");
		log.LogInfo((object)"TestSpawnRunner Awake");
	}

	private void LateUpdate()
	{
		frameCount++;
		heartbeatTimer += Time.unscaledDeltaTime;
		if (heartbeatTimer >= 5f)
		{
			heartbeatTimer = 0f;
			log.LogInfo((object)$"HB frames={frameCount} RM={(Object)(object)RunManager.instance != (Object)null} LG={(Object)(object)LevelGenerator.Instance != (Object)null} LGGen={(Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated} PlayerLocal={(Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)null}");
		}
	}

	private void Update()
	{
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		diagTimer += Time.deltaTime;
		bool flag = diagTimer >= 2f;
		if (flag)
		{
			diagTimer = 0f;
		}
		if ((Object)(object)RunManager.instance == (Object)null)
		{
			if (flag)
			{
				log.LogInfo((object)"DIAG: RunManager.instance == null");
			}
			return;
		}
		if ((Object)(object)LevelGenerator.Instance == (Object)null)
		{
			if (flag)
			{
				log.LogInfo((object)"DIAG: LevelGenerator.Instance == null");
			}
			return;
		}
		Level levelCurrent = RunManager.instance.levelCurrent;
		string text = ((levelCurrent != null) ? ((Object)levelCurrent).name : null) ?? "?";
		string text2 = text + "|" + RunManager.instance.levelsCompleted;
		if (text2 != lastSceneKey)
		{
			lastSceneKey = text2;
			firedThisLevel = false;
			settleTimer = 0f;
			log.LogInfo((object)("Nivel cambió: " + text2));
		}
		if (firedThisLevel)
		{
			return;
		}
		if (!LevelGenerator.Instance.Generated)
		{
			if (flag)
			{
				log.LogInfo((object)("DIAG: LG.Generated=false key=" + text2));
			}
			return;
		}
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			if (flag)
			{
				log.LogInfo((object)"DIAG: no master");
			}
			return;
		}
		Level levelCurrent2 = RunManager.instance.levelCurrent;
		bool flag2 = (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelLobby;
		bool flag3 = (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelLobbyMenu || (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelMainMenu;
		bool flag4 = (Object)(object)levelCurrent2 == (Object)(object)RunManager.instance.levelTutorial;
		bool flag5 = SemiFunc.IsLevelShop(levelCurrent2);
		if (flag2 || flag3 || flag4 || flag5)
		{
			if (flag)
			{
				log.LogInfo((object)$"DIAG: nivel filtrado lobby={flag2} menu={flag3} tut={flag4} shop={flag5} name={text}");
			}
			return;
		}
		PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
		if ((Object)(object)val == (Object)null)
		{
			if (flag)
			{
				log.LogInfo((object)"DIAG: PlayerAvatarLocal null");
			}
			return;
		}
		Vector3 position = ((Component)val).transform.position;
		if (((Vector3)(ref position)).sqrMagnitude < 0.5f)
		{
			if (flag)
			{
				log.LogInfo((object)$"DIAG: player pos cerca de 0: {((Component)val).transform.position}");
			}
			return;
		}
		settleTimer += Time.deltaTime;
		if (settleTimer < 2f)
		{
			if (flag)
			{
				log.LogInfo((object)$"DIAG: settle {settleTimer:F1}/2.0");
			}
		}
		else
		{
			firedThisLevel = true;
			DoSpawn(val);
		}
	}

	private void DoSpawn(PlayerAvatar player)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: 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_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		ManualLogSource obj = log;
		object arg = ((Component)player).transform.position;
		GameManager instance = GameManager.instance;
		obj.LogInfo((object)$"DoSpawn arrancó. player pos={arg} gameMode={((instance != null) ? new int?(instance.gameMode) : ((int?)null))}");
		if ((Object)(object)Plugin.EnemyPrefab != (Object)null)
		{
			try
			{
				Vector3 position = ((Component)player).transform.position;
				LevelPoint val = SemiFunc.LevelPointGet(position, 5f, 999f) ?? SemiFunc.LevelPointGet(position, 0f, 999f);
				Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : (position + new Vector3(8f, 0f, 0f)));
				GameObject val3;
				if (!((Object)(object)GameManager.instance != (Object)null) || GameManager.instance.gameMode == 0)
				{
					val3 = Object.Instantiate<GameObject>(Plugin.EnemyPrefab, val2, Quaternion.identity);
				}
				else
				{
					EnsurePhotonPoolKey("EnemyCustomFriend", Plugin.EnemyPrefab);
					val3 = PhotonNetwork.InstantiateRoomObject("EnemyCustomFriend", val2, Quaternion.identity, (byte)0, (object[])null);
				}
				log.LogInfo((object)string.Format("Osculeador instanciado en {0} -> {1}", val2, ((Object)(object)val3 != (Object)null) ? "OK" : "NULL"));
				if ((Object)(object)val3 != (Object)null)
				{
					EnemyParent component = val3.GetComponent<EnemyParent>();
					if ((Object)(object)component != (Object)null)
					{
						typeof(EnemyParent).GetField("SetupDone", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(component, true);
					}
					Enemy componentInChildren = val3.GetComponentInChildren<Enemy>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.EnemyTeleported(val2);
					}
				}
			}
			catch (Exception arg2)
			{
				log.LogError((object)$"Spawn Osculeador FAIL: {arg2}");
			}
		}
		else
		{
			log.LogWarning((object)"Plugin.EnemyPrefab es null");
		}
		Vector3 val4 = ((Component)player).transform.position + Vector3.up * 1.5f;
		SpawnItem("Item Gun Handgun", val4 + ((Component)player).transform.forward * 0.5f);
		for (int i = 0; i < 10; i++)
		{
			float num = (float)i / 10f * MathF.PI * 2f;
			Vector3 pos = val4 + new Vector3(Mathf.Cos(num) * 0.6f, (float)i * 0.1f, Mathf.Sin(num) * 0.6f);
			SpawnItem("Item Upgrade Player Grab Strength", pos);
		}
	}

	private void EnsurePhotonPoolKey(string key, GameObject prefab)
	{
		IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
		DefaultPool val = (DefaultPool)(object)((prefabPool is DefaultPool) ? prefabPool : null);
		if (val != null && !val.ResourceCache.ContainsKey(key))
		{
			val.ResourceCache[key] = prefab;
		}
	}

	private void SpawnItem(string itemName, Vector3 pos)
	{
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		StatsManager instance = StatsManager.instance;
		if ((Object)(object)instance == (Object)null || instance.itemDictionary == null)
		{
			log.LogWarning((object)"StatsManager no listo");
			return;
		}
		if (!dumpedKeys)
		{
			dumpedKeys = true;
			log.LogInfo((object)string.Format("itemDictionary keys ({0}): {1}", instance.itemDictionary.Count, string.Join(" | ", instance.itemDictionary.Keys)));
		}
		Item value = null;
		if (!instance.itemDictionary.TryGetValue(itemName, out value))
		{
			foreach (KeyValuePair<string, Item> item in instance.itemDictionary)
			{
				if (item.Key != null && item.Key.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					value = item.Value;
					log.LogInfo((object)("Match parcial: '" + itemName + "' -> '" + item.Key + "'"));
					break;
				}
			}
		}
		if ((Object)(object)value == (Object)null)
		{
			foreach (KeyValuePair<string, Item> item2 in instance.itemDictionary)
			{
				if ((Object)(object)item2.Value != (Object)null && item2.Value.itemName != null && item2.Value.itemName.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					value = item2.Value;
					log.LogInfo((object)("Match por itemName: '" + itemName + "' -> Item.itemName='" + item2.Value.itemName + "' key='" + item2.Key + "'"));
					break;
				}
			}
		}
		if ((Object)(object)value == (Object)null)
		{
			log.LogWarning((object)("Item '" + itemName + "' no encontrado"));
			return;
		}
		if (value.prefab == null || string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath))
		{
			log.LogWarning((object)("PrefabRef vacío para '" + itemName + "'"));
			return;
		}
		try
		{
			GameObject val;
			if (!((Object)(object)GameManager.instance != (Object)null) || GameManager.instance.gameMode == 0)
			{
				GameObject prefab = ((PrefabRef<GameObject>)(object)value.prefab).Prefab;
				if ((Object)(object)prefab == (Object)null)
				{
					log.LogWarning((object)("Prefab null para '" + itemName + "'"));
					return;
				}
				val = Object.Instantiate<GameObject>(prefab, pos, Quaternion.identity);
			}
			else
			{
				val = PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath, pos, Quaternion.identity, (byte)0, (object[])null);
			}
			log.LogInfo((object)string.Format("Spawn '{0}' en {1} -> {2}", itemName, pos, ((Object)(object)val != (Object)null) ? "OK" : "NULL"));
		}
		catch (Exception ex)
		{
			log.LogWarning((object)("Spawn fallido '" + itemName + "': " + ex.Message));
		}
	}
}
public class _DummyTestModeSpawnPatch_obsolete
{
	private static bool spawnedThisLevel;

	private static int lastLevelTracked = -1;

	private static bool dumpedKeys;

	private static void Postfix(LevelGenerator __instance)
	{
		if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)RunManager.instance == (Object)null)
		{
			return;
		}
		int levelsCompleted = RunManager.instance.levelsCompleted;
		if (levelsCompleted != lastLevelTracked)
		{
			spawnedThisLevel = false;
			lastLevelTracked = levelsCompleted;
		}
		if (!spawnedThisLevel)
		{
			Level levelCurrent = RunManager.instance.levelCurrent;
			if (!((Object)(object)levelCurrent == (Object)(object)RunManager.instance.levelLobby) && !((Object)(object)levelCurrent == (Object)(object)RunManager.instance.levelLobbyMenu) && !((Object)(object)levelCurrent == (Object)(object)RunManager.instance.levelMainMenu) && !((Object)(object)levelCurrent == (Object)(object)RunManager.instance.levelTutorial) && !SemiFunc.IsLevelShop(levelCurrent))
			{
				spawnedThisLevel = true;
				((MonoBehaviour)__instance).StartCoroutine(TestSpawnRoutine(__instance));
			}
		}
	}

	private static IEnumerator TestSpawnRoutine(LevelGenerator lg)
	{
		ManualLogSource log = Logger.CreateLogSource("RE_POP_TEST");
		log.LogInfo((object)"TestSpawnRoutine arrancó");
		PlayerAvatar player = null;
		float waited = 0f;
		while (waited < 30f)
		{
			player = SemiFunc.PlayerAvatarLocal();
			if ((Object)(object)player != (Object)null)
			{
				Vector3 position = ((Component)player).transform.position;
				if (((Vector3)(ref position)).sqrMagnitude > 0.5f)
				{
					break;
				}
			}
			waited += 0.5f;
			yield return (object)new WaitForSeconds(0.5f);
		}
		if ((Object)(object)player == (Object)null)
		{
			log.LogWarning((object)$"No se encontró PlayerAvatarLocal tras {waited}s — abort");
			yield break;
		}
		log.LogInfo((object)$"Player local listo tras {waited:F1}s en pos={((Component)player).transform.position}");
		if ((Object)(object)Plugin.EnemySetup != (Object)null)
		{
			try
			{
				Vector3 position2 = ((Component)player).transform.position;
				LevelPoint val = SemiFunc.LevelPointGet(position2, 5f, 999f) ?? SemiFunc.LevelPointGet(position2, 0f, 999f);
				Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : (position2 + Vector3.right * 8f));
				lg.EnemySpawn(Plugin.EnemySetup, val2);
				log.LogInfo((object)$"Osculeador forzado en {val2}");
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("No se pudo spawnear Osculeador: " + ex.Message));
			}
		}
		Vector3 val3 = ((Component)player).transform.position + Vector3.up * 1.5f;
		log.LogInfo((object)$"Spawneando items alrededor de basePos={val3}");
		SpawnItem("Item Gun Handgun", val3 + ((Component)player).transform.forward * 0.4f, log);
		for (int i = 0; i < 10; i++)
		{
			float num = (float)i / 10f * MathF.PI * 2f;
			Vector3 pos = val3 + new Vector3(Mathf.Cos(num) * 0.6f, (float)i * 0.1f, Mathf.Sin(num) * 0.6f);
			SpawnItem("Item Upgrade Player Grab Strength", pos, log);
		}
	}

	private static void SpawnItem(string itemName, Vector3 pos, ManualLogSource log)
	{
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		StatsManager instance = StatsManager.instance;
		if ((Object)(object)instance == (Object)null || instance.itemDictionary == null)
		{
			log.LogWarning((object)"StatsManager no listo");
			return;
		}
		if (!dumpedKeys)
		{
			dumpedKeys = true;
			log.LogInfo((object)string.Format("itemDictionary keys ({0}): {1}", instance.itemDictionary.Count, string.Join(" | ", instance.itemDictionary.Keys)));
		}
		Item value = null;
		if (!instance.itemDictionary.TryGetValue(itemName, out value))
		{
			foreach (KeyValuePair<string, Item> item in instance.itemDictionary)
			{
				if (item.Key != null && item.Key.IndexOf(itemName, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					value = item.Value;
					log.LogInfo((object)("Match parcial: '" + itemName + "' -> '" + item.Key + "'"));
					break;
				}
			}
		}
		if ((Object)(object)value == (Object)null)
		{
			log.LogWarning((object)("Item '" + itemName + "' no está en el diccionario"));
			return;
		}
		if (value.prefab == null || string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath))
		{
			log.LogWarning((object)("PrefabRef vacío para '" + itemName + "'"));
			return;
		}
		try
		{
			GameObject val = PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)value.prefab).ResourcePath, pos, Quaternion.identity, (byte)0, (object[])null);
			log.LogInfo((object)string.Format("Spawn '{0}' en {1} -> {2}", itemName, pos, ((Object)(object)val != (Object)null) ? "ok" : "null"));
		}
		catch (Exception ex)
		{
			log.LogWarning((object)("Spawn fallido '" + itemName + "': " + ex.Message));
		}
	}
}