Decompiled source of BloodWitch v1.0.2

plugins/Reiko888.BloodWitch.dll

Decompiled 2 days ago
#define DEBUG
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Dawn.Utils;
using Dusk;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reiko888.BloodWitch.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: AssemblyCompany("Reiko888.BloodWitch")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+f9d2a7d91a99870fa7aafc83342fe07b51feb3a6")]
[assembly: AssemblyProduct("Blood Witch")]
[assembly: AssemblyTitle("Reiko888.BloodWitch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BloodWitch
{
	[Serializable]
	public struct LevelMaterialSwap
	{
		public SkinnedMeshRenderer targetRenderer;

		public int materialIndex;

		public Material level1Material;

		public Material level2Material;

		public Material level3Material;

		public Material level4Material;
	}
	public class BloodWitchAI : EnemyAI
	{
		[Serializable]
		public class LimbGroup
		{
			public SkinnedMeshRenderer[] renderers;
		}

		private enum State
		{
			GrannyLevel1,
			GrannyLevel2,
			GrannyLevel3,
			MonsterLevel4
		}

		private Dictionary<ulong, int> previousPlayerHealths = new Dictionary<ulong, int>();

		[Header("Material Swaps")]
		public LevelMaterialSwap[] grannyMaterialSwaps;

		private Random enemyRandom = null;

		public GameObject[] outsideNodes;

		public SkinnedMeshRenderer[] skin;

		public Material[] thisMaterial;

		private bool hasLOS;

		private float LOStimer = 0f;

		public float chaseTimer = 0f;

		public bool canTeleport = true;

		public bool hasTeleported;

		private float chosenBloodTimer;

		private float teleportCooldownTimer;

		private Vector3 lastPosition;

		public Vector3 recentBlood;

		private Vector3 chosenTeleportNode;

		private const float MAX_ACCELERATION = 35f;

		private const float MIN_ACCELERATION = 10f;

		private const float MONSTER_SPEED_DIVISOR = 4.5f;

		private const float LINE_OF_SIGHT_DISTANCE = 120f;

		private Animator[] monsterAnimators;

		public LimbGroup[] removableLimbs;

		public GameObject[] severedLimbPrefabs;

		private float[] limbRegenTimers;

		private float limbRegenDuration;

		private bool[] isLimbDetached;

		private bool isConsumingBlood = false;

		private float consumeTimer = 0f;

		private Vector3 consumptionLockPosition;

		private float consumeDuration;

		public Transform currentBloodTarget;

		private List<Transform> consumedBloodTargets = new List<Transform>();

		private float bloodSearchTimer = 0f;

		private float bloodTargetWaitTimer = 0f;

		private float currentMonsterSpeed = 2f;

		private Vector3 previousPosition;

		private float averageVelocity;

		private float velocityInterval;

		private float velocityAverageCount;

		public GameObject geyserPrefab;

		private GameObject currentActiveGeyser;

		public GameObject playerBloodExplosionPrefab;

		[Header("Footprints")]
		public GameObject footprintPrefab;

		public int maxFootprints = 15;

		public float footprintDistanceThreshold = 1.5f;

		public float footprintLateralOffset = 0.3f;

		public float footprintBackwardOffset = 1.2f;

		public float footprintLifetime = 4f;

		private float accumulatedFootprintDistance = 0f;

		private Vector3 previousFootprintPosition;

		private bool alternateFootprint = false;

		private float activeFootprintTimer = 0f;

		private GameObject[] footprintPool;

		private float[] footprintTimers;

		private int currentFootprintIndex = 0;

		public GameObject bloodOrb;

		public GameObject dagger;

		public PlayAudioAnimationEvent grannyAudioAnimationEvent;

		public PlayAudioAnimationEvent monsterAudioAnimationEvent;

		[Header("Audio")]
		public AudioClip[] hitSFX;

		public AudioClip[] monsterAttackSFX;

		public AudioClip[] monsterSeePlayerSFX;

		public AudioClip[] monsterHitPlayerSFX;

		private float monsterSeePlayerCooldown = 0f;

		public AudioClip[] laughingClips;

		public AudioClip[] level3LaughingClips;

		public AudioClip[] levelUpScreams;

		public AudioClip[] levelUpScreamsDistant;

		private float laughCooldown = 0f;

		public AudioClip bloodExplosionSFX;

		public AudioClip boilTarget2DSFX;

		public AudioClip teleportSFX;

		public AudioClip consumeBloodSFX;

		public AudioClip transformationSFX;

		public AudioClip transformationSFXDistant;

		public AudioClip stabSFX;

		public AudioSource daggerAudioSource;

		public AudioSource breathingAudioSource;

		public AudioSource screamAudioSource;

		public AudioSource distantScreamAudioSource;

		private AudioSource boil2DAudioSource;

		public GameObject grannyModelContainer;

		public GameObject monsterModelContainer;

		public GameObject portalPrefab;

		public AudioClip portalStartSFX;

		public AudioClip portalCloseSFX;

		public GameObject[] level2EyeEffects;

		public ParticleSystem BloodSpurtParticleArmL;

		public ParticleSystem BloodSpurtParticleArmR;

		public ParticleSystem BloodSpurtParticleHead;

		public ParticleSystem BloodSpurtParticleBackL;

		public ParticleSystem BloodSpurtParticleBackR;

		private float timeSinceLastAttack;

		private bool isShipLeavingHandled = false;

		public int bloodConsumed = 0;

		private float explosionTimer = 0f;

		private float lastBoilTime = 0f;

		private float explosionThreshold = 5f;

		private float geyserCooldown;

		private float geyserCooldownThreshold;

		private float grannyAttackCooldownThreshold;

		private bool hasStartedTransformation = false;

		private bool isCurrentlyTransforming = false;

		private bool isWaitingForLevelUp = false;

		private bool isPausedAfterAttack = false;

		private bool isWalkingIntoPortal = false;

		private EntranceTeleport[] allTeleports;

		private float doorTransitionCooldown = 0f;

		private static FieldInfo currentBloodIndexField = typeof(PlayerControllerB).GetField("currentBloodIndex", BindingFlags.Instance | BindingFlags.NonPublic);

		private int Level1TPCooldown;

		private int Level2TPCooldown;

		private int Level3TPCooldown;

		private int Level1ConsumeReq;

		private int Level2ConsumeReq;

		private int Level3ConsumeReq;

		private bool canUseEnemyBlood;

		private bool canUsePlayerBlood;

		private bool canMonstGoOutside;

		private bool canGrannyGoOutside;

		private int granny1to2base;

		private int granny3base;

		private int monsterBaseSpeed;

		private int monsterMaxSpeed;

		private int limbHealth;

		private int currentLimbDamage = 0;

		private Vector3 targetPlayerLastPos;

		private Vector3 targetPlayerVelocity;

		private Coroutine consumeCoroutine;

		private Coroutine portalCoroutine;

		private GameObject entrancePortal;

		private GameObject exitPortal;

		public int CurrentLevel
		{
			get
			{
				if (bloodConsumed >= Level3ConsumeReq)
				{
					return 4;
				}
				if (bloodConsumed >= Level2ConsumeReq)
				{
					return 3;
				}
				if (bloodConsumed >= Level1ConsumeReq)
				{
					return 2;
				}
				return 1;
			}
		}

		[Conditional("DEBUG")]
		private void LogIfDebugBuild(string text)
		{
			if (Plugin.Logger != null)
			{
				Plugin.Logger.LogInfo((object)text);
			}
			else
			{
				Debug.Log((object)(" " + text));
			}
		}

		private void SpawnFootprint()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			if (footprintPool == null || footprintPool.Length == 0)
			{
				return;
			}
			GameObject val = footprintPool[currentFootprintIndex];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Vector3 forward = ((Component)this).transform.forward;
			if (forward == Vector3.zero)
			{
				forward = Vector3.forward;
			}
			Vector3 right = ((Component)this).transform.right;
			float num = (alternateFootprint ? footprintLateralOffset : (0f - footprintLateralOffset));
			Vector3 val2 = ((Component)this).transform.position - forward * footprintBackwardOffset + right * num + Vector3.up * 1f;
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			collidersAndRoomMaskAndDefault &= ~(1 << ((Component)this).gameObject.layer);
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2, Vector3.down, ref val3, 4f, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) && !(Vector3.Dot(((RaycastHit)(ref val3)).normal, Vector3.up) < 0.7f))
			{
				val.transform.position = ((RaycastHit)(ref val3)).point + Vector3.up * 0.02f;
				Vector3 val4 = Vector3.ProjectOnPlane(forward, ((RaycastHit)(ref val3)).normal);
				Vector3 normalized = ((Vector3)(ref val4)).normalized;
				if (normalized != Vector3.zero)
				{
					val.transform.rotation = Quaternion.LookRotation(-((RaycastHit)(ref val3)).normal, normalized);
				}
				Vector3 localScale = val.transform.localScale;
				localScale.x = (alternateFootprint ? Mathf.Abs(localScale.x) : (0f - Mathf.Abs(localScale.x)));
				val.transform.localScale = localScale;
				val.SetActive(true);
				footprintTimers[currentFootprintIndex] = footprintLifetime;
				alternateFootprint = !alternateFootprint;
				currentFootprintIndex = (currentFootprintIndex + 1) % maxFootprints;
			}
		}

		private void ApplyLevelMaterials(int level)
		{
			if (grannyMaterialSwaps == null || grannyMaterialSwaps.Length == 0)
			{
				return;
			}
			LevelMaterialSwap[] array = grannyMaterialSwaps;
			for (int i = 0; i < array.Length; i++)
			{
				LevelMaterialSwap levelMaterialSwap = array[i];
				if ((Object)(object)levelMaterialSwap.targetRenderer == (Object)null)
				{
					continue;
				}
				Material val = null;
				if (level == 1 && (Object)(object)levelMaterialSwap.level1Material != (Object)null)
				{
					val = levelMaterialSwap.level1Material;
				}
				else if (level == 2 && (Object)(object)levelMaterialSwap.level2Material != (Object)null)
				{
					val = levelMaterialSwap.level2Material;
				}
				else if (level == 3 && (Object)(object)levelMaterialSwap.level3Material != (Object)null)
				{
					val = levelMaterialSwap.level3Material;
				}
				else if (level >= 4 && (Object)(object)levelMaterialSwap.level4Material != (Object)null)
				{
					val = levelMaterialSwap.level4Material;
				}
				if ((Object)(object)val != (Object)null)
				{
					Material[] sharedMaterials = ((Renderer)levelMaterialSwap.targetRenderer).sharedMaterials;
					if (levelMaterialSwap.materialIndex >= 0 && levelMaterialSwap.materialIndex < sharedMaterials.Length)
					{
						sharedMaterials[levelMaterialSwap.materialIndex] = val;
						((Renderer)levelMaterialSwap.targetRenderer).sharedMaterials = sharedMaterials;
					}
				}
			}
			if (level2EyeEffects == null)
			{
				return;
			}
			GameObject[] array2 = level2EyeEffects;
			foreach (GameObject val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetActive(level >= 2);
				}
			}
		}

		public override void Start()
		{
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			Level1TPCooldown = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 1: Teleport cooldown").Value;
			consumeDuration = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Levels 1-3: Consume blood duration").Value;
			grannyAttackCooldownThreshold = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<float>("Levels 1-3: Granny stab attack cooldown").Value;
			explosionThreshold = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<float>("Level 3: Player explosion timer").Value;
			geyserCooldownThreshold = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<float>("Levels 2: Geyser ability cooldown").Value;
			Level2TPCooldown = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 2: Teleport cooldown").Value;
			Level3TPCooldown = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 3: Teleport cooldown").Value;
			Level1ConsumeReq = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 1: Blood Consumption level up requirement").Value;
			Level2ConsumeReq = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 2: Blood Consumption level up requirement").Value;
			Level3ConsumeReq = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 3: Blood Consumption level up requirement").Value;
			canUseEnemyBlood = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<bool>("Levels 1-3: Level up on enemy blood").Value;
			canUsePlayerBlood = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<bool>("Levels 1-3: Level up on player damage blood").Value;
			canMonstGoOutside = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<bool>("Level 4: Can monster go outside?").Value;
			canGrannyGoOutside = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<bool>("Levels 1-3: Consume outside blood").Value;
			granny1to2base = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Levels 1-2: Granny base speed").Value;
			granny3base = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 3: Speed of granny").Value;
			monsterBaseSpeed = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 4: Base monster speed").Value;
			monsterMaxSpeed = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Level 4: Max monster speed").Value;
			limbHealth = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<int>("Levels 1-3: Limb health").Value;
			limbRegenDuration = ((AssetBundleLoader<BWContentHandler.BWAssets>)(object)ContentHandler<BWContentHandler>.Instance.bwAssets).GetConfig<float>("Levels 1-3: Limb regeneration duration").Value;
			if ((Object)(object)monsterModelContainer != (Object)null)
			{
				monsterAnimators = monsterModelContainer.GetComponentsInChildren<Animator>(true);
			}
			base.updatePositionThreshold = 0.5f;
			ApplyLevelMaterials(CurrentLevel);
			if ((Object)(object)footprintPrefab != (Object)null)
			{
				footprintPool = (GameObject[])(object)new GameObject[maxFootprints];
				footprintTimers = new float[maxFootprints];
				for (int i = 0; i < maxFootprints; i++)
				{
					GameObject val = Object.Instantiate<GameObject>(footprintPrefab, Vector3.zero, Quaternion.identity);
					val.transform.SetParent((Transform)null, true);
					val.SetActive(false);
					footprintPool[i] = val;
					footprintTimers[i] = 0f;
				}
			}
			bloodSearchTimer = 2f;
			base.currentBehaviourStateIndex = 1;
			boil2DAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			boil2DAudioSource.clip = boilTarget2DSFX;
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			List<Material> list = new List<Material>();
			if (skin != null)
			{
				SkinnedMeshRenderer[] array = skin;
				foreach (SkinnedMeshRenderer val2 in array)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						list.AddRange(((Renderer)val2).materials);
					}
				}
			}
			if (!RoundManager.Instance.hasInitializedLevelRandomSeed)
			{
				RoundManager.Instance.InitializeRandomNumberGenerators();
			}
			((EnemyAI)this).GetAINodes();
			outsideNodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
			if (removableLimbs != null)
			{
				limbRegenTimers = new float[removableLimbs.Length];
				isLimbDetached = new bool[removableLimbs.Length];
			}
		}

		public void SyncStateSafely(int newStateIndex)
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				SyncStateSafelyClientRpc(newStateIndex);
			}
			else
			{
				SyncStateSafelyServerRpc(newStateIndex);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void SyncStateSafelyServerRpc(int newStateIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val2 = default(ServerRpcParams);
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(928502956u, val2, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val, newStateIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val, 928502956u, val2, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					SyncStateSafelyClientRpc(newStateIndex);
				}
			}
		}

		[ClientRpc]
		private void SyncStateSafelyClientRpc(int newStateIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val2 = default(ClientRpcParams);
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(632903206u, val2, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val, newStateIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val, 632903206u, val2, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					LogIfDebugBuild($"State changed from {(State)base.currentBehaviourStateIndex} to {(State)newStateIndex}");
					base.currentBehaviourStateIndex = newStateIndex;
				}
			}
		}

		private void HandleMonsterSpeed()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh && !isPausedAfterAttack && !isCurrentlyTransforming)
			{
				if ((Object)(object)base.targetPlayer != (Object)null && hasLOS)
				{
					currentMonsterSpeed += Time.deltaTime * 2.5f;
					base.agent.acceleration = Mathf.MoveTowards(base.agent.acceleration, 35f, Time.deltaTime * 5f);
				}
				else
				{
					currentMonsterSpeed -= Time.deltaTime * 4f;
					base.agent.acceleration = Mathf.MoveTowards(base.agent.acceleration, 10f, Time.deltaTime * 8f);
				}
				currentMonsterSpeed = Mathf.Clamp(currentMonsterSpeed, (float)monsterBaseSpeed, (float)monsterMaxSpeed);
				base.agent.speed = currentMonsterSpeed;
			}
			Vector3 val = ((Component)this).transform.position - previousPosition;
			float num = ((Vector3)(ref val)).magnitude / Time.deltaTime;
			averageVelocity = Mathf.Lerp(averageVelocity, num, Time.deltaTime * 10f);
			previousPosition = ((Component)this).transform.position;
			float num2 = Mathf.Clamp(averageVelocity / 4.5f, 0.5f, 4f);
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetFloat("monsterSpeedMult", num2);
			}
			if (monsterAnimators != null)
			{
				Animator[] array = monsterAnimators;
				foreach (Animator val2 in array)
				{
					val2.SetFloat("monsterSpeedMult", num2);
				}
			}
		}

		private void HandleFootprints()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_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)
			if (footprintPool != null && footprintTimers != null)
			{
				for (int i = 0; i < footprintPool.Length; i++)
				{
					if (footprintTimers[i] > 0f)
					{
						footprintTimers[i] -= Time.deltaTime;
						if (footprintTimers[i] <= 0f && (Object)(object)footprintPool[i] != (Object)null)
						{
							footprintPool[i].SetActive(false);
						}
					}
				}
			}
			if (activeFootprintTimer > 0f)
			{
				activeFootprintTimer -= Time.deltaTime;
			}
			if (activeFootprintTimer > 0f && !base.isEnemyDead && !isCurrentlyTransforming && !isConsumingBlood && footprintPool != null && footprintPool.Length != 0)
			{
				if (previousFootprintPosition == Vector3.zero)
				{
					previousFootprintPosition = ((Component)this).transform.position;
				}
				float num = Vector3.Distance(((Component)this).transform.position, previousFootprintPosition);
				accumulatedFootprintDistance += num;
				previousFootprintPosition = ((Component)this).transform.position;
				if (accumulatedFootprintDistance >= footprintDistanceThreshold)
				{
					accumulatedFootprintDistance = 0f;
					SpawnFootprint();
				}
			}
			else if (!isConsumingBlood)
			{
				previousFootprintPosition = ((Component)this).transform.position;
			}
		}

		private void HandleLimbRegeneration()
		{
			if (removableLimbs == null)
			{
				return;
			}
			for (int i = 0; i < removableLimbs.Length; i++)
			{
				if (!isLimbDetached[i])
				{
					continue;
				}
				limbRegenTimers[i] -= Time.deltaTime;
				if (limbRegenTimers[i] <= 0f)
				{
					isLimbDetached[i] = false;
					if (i == 0 && (Object)(object)bloodOrb != (Object)null)
					{
						bloodOrb.SetActive(true);
					}
					if (i == 1 && (Object)(object)dagger != (Object)null)
					{
						dagger.SetActive(true);
					}
					if (i == 2 && CurrentLevel >= 2 && level2EyeEffects != null)
					{
						GameObject[] array = level2EyeEffects;
						foreach (GameObject val in array)
						{
							if ((Object)(object)val != (Object)null)
							{
								val.SetActive(true);
							}
						}
					}
					if (removableLimbs[i] != null && removableLimbs[i].renderers != null)
					{
						SetLimbVisibility(i, 1f);
					}
				}
				else if (removableLimbs[i] != null && removableLimbs[i].renderers != null)
				{
					float progress = ((limbRegenDuration > 0f) ? (1f - limbRegenTimers[i] / limbRegenDuration) : 1f);
					SetLimbVisibility(i, progress);
				}
			}
		}

		public override void DoAIInterval()
		{
			//IL_06f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fb: 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_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: 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_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0793: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_077e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0675: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_063b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0847: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ad: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead || isCurrentlyTransforming || isPausedAfterAttack || base.stunNormalizedTimer > 0f || isWalkingIntoPortal)
			{
				return;
			}
			if (!isConsumingBlood)
			{
				((EnemyAI)this).DoAIInterval();
			}
			bool flag = hasLOS;
			int currentLevel = CurrentLevel;
			int num = currentLevel - 1;
			if (base.currentBehaviourStateIndex != num)
			{
				LogIfDebugBuild($"Switching state from {base.currentBehaviourStateIndex} to {num} (Level {currentLevel})");
				SyncStateSafely(num);
				if (currentLevel == 4 && !hasStartedTransformation)
				{
					hasStartedTransformation = true;
					canTeleport = false;
					TriggerTransformationClientRpc();
				}
				else if (currentLevel < 4)
				{
					if ((Object)(object)grannyModelContainer != (Object)null)
					{
						grannyModelContainer.SetActive(true);
					}
					if ((Object)(object)monsterModelContainer != (Object)null)
					{
						monsterModelContainer.SetActive(false);
					}
				}
			}
			if (isConsumingBlood)
			{
				return;
			}
			if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null)
			{
				switch ((State)base.currentBehaviourStateIndex)
				{
				case State.GrannyLevel1:
				case State.GrannyLevel2:
					base.agent.speed = granny1to2base;
					break;
				case State.GrannyLevel3:
					base.agent.speed = granny3base;
					break;
				}
			}
			if ((Object)(object)base.targetPlayer != (Object)null && !isConsumingBlood)
			{
				if (currentLevel == 4 && base.targetPlayer.isInsideFactory == base.isOutside)
				{
					base.movingTowardsTargetPlayer = false;
					EntranceTeleport closestDoorToMonster = GetClosestDoorToMonster();
					if (!((Object)(object)closestDoorToMonster != (Object)null))
					{
						return;
					}
					((EnemyAI)this).SetDestinationToPosition(((Component)closestDoorToMonster).transform.position, false);
					if (Vector3.Distance(((Component)this).transform.position, ((Component)closestDoorToMonster).transform.position) < 4f && doorTransitionCooldown <= 0f)
					{
						EntranceTeleport correspondingDoor = GetCorrespondingDoor(closestDoorToMonster);
						if ((Object)(object)correspondingDoor != (Object)null)
						{
							doorTransitionCooldown = 3f;
							TeleportEnemyServerRpc(correspondingDoor.entrancePoint.position, !base.isOutside);
						}
					}
					return;
				}
				if (((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer.gameplayCamera).transform.position, 120f, 60, -1f, (Transform)null))
				{
					hasLOS = true;
					lastPosition = ((Component)base.targetPlayer).transform.position;
					if (base.currentSearch != null && base.currentSearch.inProgress)
					{
						((EnemyAI)this).StopSearch(base.currentSearch, true);
					}
					((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
					bool flag2 = removableLimbs != null && isLimbDetached != null && isLimbDetached.Length != 0 && isLimbDetached[0];
					if (currentLevel == 3 && !flag2)
					{
						if (explosionTimer <= 0f && (Object)(object)base.creatureAnimator != (Object)null)
						{
							LogIfDebugBuild("Started boiling player " + base.targetPlayer.playerUsername);
							SyncBoilingAnimationClientRpc(isBoiling: true, exploded: false);
						}
						explosionTimer += base.AIIntervalTime;
						SyncBoilTargetClientRpc((int)base.targetPlayer.playerClientId, explosionTimer);
						if (explosionTimer >= explosionThreshold)
						{
							LogIfDebugBuild("Started boiling player " + base.targetPlayer.playerUsername);
							SyncBoilingAnimationClientRpc(isBoiling: true, exploded: false);
							base.targetPlayer.isSinking = false;
						}
						if (explosionTimer >= explosionThreshold)
						{
							LogIfDebugBuild("Exploding player " + base.targetPlayer.playerUsername);
							ExplodePlayer(base.targetPlayer);
							base.targetPlayer = null;
							explosionTimer = 0f;
							SyncBoilingAnimationClientRpc(isBoiling: false, exploded: true);
							SyncBoilTargetClientRpc(-1, 0f);
						}
					}
					else if (currentLevel == 2 && !flag2 && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < 15f && geyserCooldown <= 0f)
					{
						LogIfDebugBuild("Casting Geyser on player " + base.targetPlayer.playerUsername);
						CastBloodGeyser(base.targetPlayer);
						geyserCooldown = geyserCooldownThreshold;
					}
					if (flag2 && explosionTimer > 0f)
					{
						explosionTimer = 0f;
						SyncBoilingAnimationClientRpc(isBoiling: false, exploded: false);
						SyncBoilTargetClientRpc(-1, 0f);
					}
				}
				else
				{
					if (hasLOS)
					{
						LogIfDebugBuild("Lost Line of Sight to target player.");
					}
					hasLOS = false;
					if (explosionTimer > 0f)
					{
						explosionTimer = 0f;
						SyncBoilingAnimationClientRpc(isBoiling: false, exploded: false);
						SyncBoilTargetClientRpc(-1, 0f);
					}
					explosionTimer = 0f;
					if (chaseTimer <= 0f)
					{
						base.targetPlayer = null;
						if (base.currentSearch == null || !base.currentSearch.inProgress)
						{
							if (base.isOutside)
							{
								((EnemyAI)this).StartSearch(((EnemyAI)this).ChooseFarthestNodeFromPosition(((Component)this).transform.position, false, 0, false, 50, -1).position, (AISearchRoutine)null);
							}
							else
							{
								((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
							}
						}
					}
					else
					{
						((EnemyAI)this).SetDestinationToPosition(lastPosition, false);
						if (Vector3.Distance(((Component)this).transform.position, lastPosition) <= 2f)
						{
							chaseTimer = 0f;
						}
					}
				}
			}
			else
			{
				hasLOS = false;
				explosionTimer = 0f;
				if (((EnemyAI)this).TargetClosestPlayer(5f, true, 120f, false, false, true))
				{
					hasLOS = true;
					chaseTimer = 10f;
					lastPosition = ((Component)base.targetPlayer).transform.position;
					if (base.currentSearch != null && base.currentSearch.inProgress)
					{
						((EnemyAI)this).StopSearch(base.currentSearch, true);
					}
					((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
				}
				else if (base.currentSearch == null || !base.currentSearch.inProgress)
				{
					if (base.isOutside)
					{
						((EnemyAI)this).StartSearch(((EnemyAI)this).ChooseFarthestNodeFromPosition(((Component)this).transform.position, false, 0, false, 50, -1).position, (AISearchRoutine)null);
					}
					else
					{
						((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
					}
				}
				if (currentLevel == 4 && monsterSeePlayerCooldown <= 0f && Random.Range(0, 100) < 1)
				{
					monsterSeePlayerCooldown = 15f;
					if (((NetworkBehaviour)this).IsServer)
					{
						PlayMonsterSeePlayerSFXClientRpc();
					}
				}
				if (((currentLevel == 4 && canMonstGoOutside) || (currentLevel < 4 && canGrannyGoOutside)) && doorTransitionCooldown <= 0f)
				{
					EntranceTeleport closestDoorToMonster2 = GetClosestDoorToMonster();
					if ((Object)(object)closestDoorToMonster2 != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)closestDoorToMonster2).transform.position) < 4f)
					{
						if (Random.Range(0, 100) < 30)
						{
							EntranceTeleport correspondingDoor2 = GetCorrespondingDoor(closestDoorToMonster2);
							if ((Object)(object)correspondingDoor2 != (Object)null)
							{
								doorTransitionCooldown = 15f;
								TeleportEnemyServerRpc(correspondingDoor2.entrancePoint.position, !base.isOutside);
							}
						}
						else
						{
							doorTransitionCooldown = 5f;
						}
					}
				}
			}
			if (!flag && hasLOS && CurrentLevel == 4 && monsterSeePlayerCooldown <= 0f)
			{
				monsterSeePlayerCooldown = 5f;
				if (((NetworkBehaviour)this).IsServer)
				{
					PlayMonsterSeePlayerSFXClientRpc();
				}
			}
		}

		public override void Update()
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e1: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (((NetworkBehaviour)this).IsServer && (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayerScripts != null)
			{
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if ((Object)(object)val != (Object)null && !val.isPlayerDead)
					{
						if (!previousPlayerHealths.ContainsKey(val.playerClientId))
						{
							previousPlayerHealths[val.playerClientId] = val.health;
						}
						else if (val.health < previousPlayerHealths[val.playerClientId])
						{
							Vector3 onUnitSphere = Random.onUnitSphere;
							onUnitSphere.y = Mathf.Abs(onUnitSphere.y);
							val.DropBlood(onUnitSphere, true, false);
							PlayerBloodPatch.SpawnPersistentBlood(val);
							previousPlayerHealths[val.playerClientId] = val.health;
						}
						else if (val.health > previousPlayerHealths[val.playerClientId])
						{
							previousPlayerHealths[val.playerClientId] = val.health;
						}
					}
					else if ((Object)(object)val != (Object)null && val.isPlayerDead)
					{
						previousPlayerHealths[val.playerClientId] = 100;
					}
				}
			}
			if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving && !isShipLeavingHandled)
			{
				isShipLeavingHandled = true;
				HandleShipLeft();
			}
			if (base.isEnemyDead)
			{
				return;
			}
			if (base.stunNormalizedTimer > 0f)
			{
				if ((Object)(object)base.creatureAnimator != (Object)null && !base.creatureAnimator.GetBool("hasBeenStunned"))
				{
					base.creatureAnimator.SetBool("hasBeenStunned", true);
				}
				if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
				{
					base.agent.isStopped = true;
					base.agent.velocity = Vector3.zero;
				}
				return;
			}
			if ((Object)(object)base.creatureAnimator != (Object)null && base.creatureAnimator.GetBool("hasBeenStunned"))
			{
				base.creatureAnimator.SetBool("hasBeenStunned", false);
				if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
				{
					base.agent.isStopped = false;
				}
			}
			if (isWalkingIntoPortal)
			{
				return;
			}
			if (doorTransitionCooldown > 0f)
			{
				doorTransitionCooldown -= Time.deltaTime;
			}
			if (monsterSeePlayerCooldown > 0f)
			{
				monsterSeePlayerCooldown -= Time.deltaTime;
			}
			if ((Object)(object)base.targetPlayer != (Object)null)
			{
				targetPlayerVelocity = (((Component)base.targetPlayer).transform.position - targetPlayerLastPos) / Time.deltaTime;
				targetPlayerLastPos = ((Component)base.targetPlayer).transform.position;
			}
			if (hasTeleported)
			{
				LogIfDebugBuild("Processing hasTeleported and starting consumption.");
				hasTeleported = false;
				if (consumeCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(consumeCoroutine);
				}
				consumeCoroutine = ((MonoBehaviour)this).StartCoroutine(TeleportThenConsumeRoutine());
			}
			if (base.currentBehaviourStateIndex == 3)
			{
				HandleMonsterSpeed();
			}
			timeSinceLastAttack += Time.deltaTime;
			chosenBloodTimer -= Time.deltaTime;
			if (!isConsumingBlood && !isWalkingIntoPortal && !isCurrentlyTransforming)
			{
				teleportCooldownTimer -= Time.deltaTime;
			}
			geyserCooldown -= Time.deltaTime;
			laughCooldown -= Time.deltaTime;
			if (!base.isEnemyDead && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh && base.currentBehaviourStateIndex != 3 && !isWalkingIntoPortal)
			{
				base.agent.speed = 3.5f;
			}
			HandleFootprints();
			if (isConsumingBlood)
			{
				base.movingTowardsTargetPlayer = false;
				base.targetPlayer = null;
				((Component)this).transform.position = consumptionLockPosition;
				base.serverPosition = consumptionLockPosition;
				if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
				{
					base.agent.isStopped = true;
					base.agent.velocity = Vector3.zero;
				}
				return;
			}
			HandleLimbRegeneration();
			bool flag = removableLimbs != null && isLimbDetached != null && isLimbDetached.Length != 0 && isLimbDetached[0];
			if (!((NetworkBehaviour)this).IsServer || !canTeleport || !(teleportCooldownTimer <= 0f) || isConsumingBlood || !(explosionTimer <= 0f) || CurrentLevel >= 4 || flag)
			{
				return;
			}
			if (bloodTargetWaitTimer > 0f)
			{
				bloodTargetWaitTimer -= Time.deltaTime;
			}
			bloodSearchTimer -= Time.deltaTime;
			if (!(bloodSearchTimer <= 0f))
			{
				return;
			}
			bloodSearchTimer = 2f;
			if ((Object)(object)currentBloodTarget == (Object)null || !((Component)currentBloodTarget).gameObject.activeInHierarchy)
			{
				Transform val2 = FindBestBloodSource();
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)currentBloodTarget)
				{
					currentBloodTarget = val2;
					bloodTargetWaitTimer = 3f;
				}
			}
			if ((Object)(object)currentBloodTarget != (Object)null && bloodTargetWaitTimer <= 0f)
			{
				FindNodeNearestToBlood(currentBloodTarget.position);
			}
		}

		private IEnumerator TeleportThenConsumeRoutine()
		{
			isConsumingBlood = true;
			base.movingTowardsTargetPlayer = false;
			if (((NetworkBehaviour)this).IsServer)
			{
				if (base.currentSearch != null && base.currentSearch.inProgress)
				{
					((EnemyAI)this).StopSearch(base.currentSearch, true);
				}
				((EnemyAI)this).SetDestinationToPosition(((Component)this).transform.position, false);
				if ((Object)(object)base.agent != (Object)null)
				{
					base.agent.speed = 0f;
					base.agent.velocity = Vector3.zero;
					if (base.agent.isOnNavMesh)
					{
						base.agent.isStopped = true;
						base.agent.ResetPath();
					}
				}
			}
			yield return (object)new WaitForSeconds(0.1f);
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetBool("isConsuming", true);
			}
			if ((Object)(object)consumeBloodSFX != (Object)null && (Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.PlayOneShot(consumeBloodSFX);
			}
			yield return (object)new WaitForSeconds(consumeDuration - 0.2f);
			if (!isConsumingBlood)
			{
				yield break;
			}
			activeFootprintTimer = 20f;
			int tempBlood = bloodConsumed;
			tempBlood++;
			if (tempBlood < 9)
			{
				isConsumingBlood = false;
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetBool("isConsuming", false);
				}
				if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
				{
					base.agent.isStopped = false;
				}
			}
			else
			{
				isWaitingForLevelUp = true;
			}
			((MonoBehaviour)this).StartCoroutine(DelayedConsumeBlood(0.5f));
			if ((Object)(object)currentBloodTarget != (Object)null && !consumedBloodTargets.Contains(currentBloodTarget))
			{
				consumedBloodTargets.Add(currentBloodTarget);
				currentBloodTarget = null;
			}
		}

		private Transform FindBestBloodSource()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			Transform bestSource = null;
			float closestSqrDistance = float.MaxValue;
			Vector3 myPos = ((Component)this).transform.position;
			LogIfDebugBuild("FindBestBloodSource: Searching for blood sources...");
			bool canGoOutside = (CurrentLevel < 4 && canGrannyGoOutside) || (CurrentLevel == 4 && canMonstGoOutside);
			if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayerScripts != null)
			{
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if ((Object)(object)val != (Object)null && val.playerBloodPooledObjects != null)
					{
						foreach (GameObject playerBloodPooledObject in val.playerBloodPooledObjects)
						{
							if ((Object)(object)playerBloodPooledObject != (Object)null)
							{
								CheckSource(playerBloodPooledObject.transform);
							}
						}
					}
					if ((Object)(object)val != (Object)null && val.isPlayerDead && (Object)(object)val.deadBody != (Object)null)
					{
						CheckSource(((Component)val.deadBody).transform);
					}
				}
			}
			if (EnemyBloodPatch.enemyBloodDrops != null)
			{
				foreach (GameObject enemyBloodDrop in EnemyBloodPatch.enemyBloodDrops)
				{
					if (!((Object)(object)enemyBloodDrop == (Object)null))
					{
						if (((Object)enemyBloodDrop).name.StartsWith("PlayerPersistentBloodDrop"))
						{
							CheckSource(enemyBloodDrop.transform);
						}
						else if (((Object)enemyBloodDrop).name.StartsWith("EnemyBloodDrop"))
						{
							CheckSource(enemyBloodDrop.transform);
						}
					}
				}
			}
			if (canUseEnemyBlood && (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.SpawnedEnemies != null)
			{
				foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
				{
					if ((Object)(object)spawnedEnemy != (Object)null && (Object)(object)spawnedEnemy != (Object)(object)this && spawnedEnemy.isEnemyDead)
					{
						CheckSource(((Component)spawnedEnemy).transform);
					}
				}
			}
			if ((Object)(object)bestSource != (Object)null)
			{
				LogIfDebugBuild($"FindBestBloodSource: Found best source at {bestSource.position} with squared distance {closestSqrDistance}");
			}
			else
			{
				LogIfDebugBuild("FindBestBloodSource: No valid blood sources found.");
			}
			return bestSource;
			void CheckSource(Transform source)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)source == (Object)null) && ((Component)source).gameObject.activeInHierarchy && !consumedBloodTargets.Contains(source) && (canGoOutside || !IsPositionOutside(source.position)))
				{
					Vector3 val2 = myPos - source.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < closestSqrDistance)
					{
						closestSqrDistance = sqrMagnitude;
						bestSource = source;
					}
				}
			}
			static bool IsPositionOutside(Vector3 pos)
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: 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)RoundManager.Instance == (Object)null)
				{
					return false;
				}
				float num = float.MaxValue;
				float num2 = float.MaxValue;
				Vector3 val3;
				if (RoundManager.Instance.insideAINodes != null)
				{
					GameObject[] insideAINodes = RoundManager.Instance.insideAINodes;
					foreach (GameObject val2 in insideAINodes)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							val3 = val2.transform.position - pos;
							float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
							if (sqrMagnitude < num)
							{
								num = sqrMagnitude;
							}
						}
					}
				}
				if (RoundManager.Instance.outsideAINodes != null)
				{
					GameObject[] outsideAINodes = RoundManager.Instance.outsideAINodes;
					foreach (GameObject val4 in outsideAINodes)
					{
						if ((Object)(object)val4 != (Object)null)
						{
							val3 = val4.transform.position - pos;
							float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude;
							if (sqrMagnitude2 < num2)
							{
								num2 = sqrMagnitude2;
							}
						}
					}
				}
				return num2 < num;
			}
		}

		private void FindNodeNearestToBlood(Vector3 bloodLocation)
		{
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_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)
			//IL_0297: 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)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: 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_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!canTeleport)
			{
				return;
			}
			GameObject val = null;
			float num = float.MaxValue;
			bool setOutside = false;
			Vector3 val3;
			if ((Object)(object)RoundManager.Instance != (Object)null)
			{
				if (RoundManager.Instance.insideAINodes != null)
				{
					GameObject[] insideAINodes = RoundManager.Instance.insideAINodes;
					foreach (GameObject val2 in insideAINodes)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							val3 = val2.transform.position - bloodLocation;
							float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
							if (sqrMagnitude < num)
							{
								num = sqrMagnitude;
								val = val2;
								setOutside = false;
							}
						}
					}
				}
				if (((CurrentLevel < 4 && canGrannyGoOutside) || (CurrentLevel == 4 && canMonstGoOutside)) && RoundManager.Instance.outsideAINodes != null)
				{
					GameObject[] outsideAINodes = RoundManager.Instance.outsideAINodes;
					foreach (GameObject val4 in outsideAINodes)
					{
						if (!((Object)(object)val4 == (Object)null))
						{
							val3 = val4.transform.position - bloodLocation;
							float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude;
							if (sqrMagnitude2 < num)
							{
								num = sqrMagnitude2;
								val = val4;
								setOutside = true;
							}
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null && base.allAINodes != null)
			{
				GameObject[] allAINodes = base.allAINodes;
				foreach (GameObject val5 in allAINodes)
				{
					if (!((Object)(object)val5 == (Object)null))
					{
						val3 = val5.transform.position - bloodLocation;
						float sqrMagnitude3 = ((Vector3)(ref val3)).sqrMagnitude;
						if (sqrMagnitude3 < num)
						{
							num = sqrMagnitude3;
							val = val5;
							setOutside = base.isOutside;
						}
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				ResetTeleportCooldown(CurrentLevel);
				chosenTeleportNode = val.transform.position;
				Vector3 val6 = bloodLocation;
				NavMeshHit val7 = default(NavMeshHit);
				if (NavMesh.SamplePosition(bloodLocation, ref val7, 3f, -1))
				{
					val6 = ((NavMeshHit)(ref val7)).position;
					NavMeshHit val8 = default(NavMeshHit);
					if ((Object)(object)val != (Object)null && NavMesh.Raycast(val.transform.position, val6, ref val8, -1))
					{
						val6 = val.transform.position;
					}
				}
				else if ((Object)(object)val != (Object)null)
				{
					LogIfDebugBuild("Blood not on navmesh, chosing another spot");
					val6 = val.transform.position;
				}
				LogIfDebugBuild($"Found closest node at {num} squared units. Teleporting ontop of blood.");
				if (((NetworkBehaviour)this).IsServer)
				{
					if (portalCoroutine != null)
					{
						((MonoBehaviour)this).StopCoroutine(portalCoroutine);
					}
					portalCoroutine = ((MonoBehaviour)this).StartCoroutine(PortalSequenceRoutine(val6, setOutside));
				}
				else
				{
					TeleportBWServerRpc(val6, setOutside);
				}
			}
			else
			{
				LogIfDebugBuild("No AI nodes found at all. Teleport cancelled");
			}
		}

		[ClientRpc]
		public void SpawnEntrancePortalClientRpc(Vector3 position, Quaternion rotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(137346814u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref rotation);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 137346814u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if ((Object)(object)portalPrefab != (Object)null)
			{
				entrancePortal = Object.Instantiate<GameObject>(portalPrefab, position, rotation);
				ParticleSystem[] componentsInChildren = entrancePortal.GetComponentsInChildren<ParticleSystem>();
				ParticleSystem[] array = componentsInChildren;
				foreach (ParticleSystem val3 in array)
				{
					val3.Play();
				}
				VisualEffect[] componentsInChildren2 = entrancePortal.GetComponentsInChildren<VisualEffect>();
				VisualEffect[] array2 = componentsInChildren2;
				foreach (VisualEffect val4 in array2)
				{
					val4.Play();
				}
			}
			if ((Object)(object)portalStartSFX != (Object)null && (Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.PlayOneShot(portalStartSFX);
			}
		}

		[ClientRpc]
		public void SpawnExitPortalClientRpc(Vector3 position, Quaternion rotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2348840876u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref rotation);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 2348840876u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if ((Object)(object)portalPrefab != (Object)null)
			{
				exitPortal = Object.Instantiate<GameObject>(portalPrefab, position, rotation);
				ParticleSystem[] componentsInChildren = exitPortal.GetComponentsInChildren<ParticleSystem>();
				ParticleSystem[] array = componentsInChildren;
				foreach (ParticleSystem val3 in array)
				{
					val3.Play();
				}
				VisualEffect[] componentsInChildren2 = exitPortal.GetComponentsInChildren<VisualEffect>();
				VisualEffect[] array2 = componentsInChildren2;
				foreach (VisualEffect val4 in array2)
				{
					val4.Play();
				}
			}
		}

		[ClientRpc]
		public void ClosePortalsClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3985111250u, val2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 3985111250u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if ((Object)(object)portalCloseSFX != (Object)null && (Object)(object)base.creatureVoice != (Object)null)
				{
					base.creatureVoice.PlayOneShot(portalCloseSFX);
				}
				if ((Object)(object)entrancePortal != (Object)null)
				{
					Object.Destroy((Object)(object)entrancePortal);
				}
				if ((Object)(object)exitPortal != (Object)null)
				{
					Object.Destroy((Object)(object)exitPortal);
				}
			}
		}

		[ClientRpc]
		public void CancelInterruptibleActionsClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2103324487u, val2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 2103324487u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (isWalkingIntoPortal)
			{
				isWalkingIntoPortal = false;
				if (portalCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(portalCoroutine);
				}
				if ((Object)(object)entrancePortal != (Object)null)
				{
					Object.Destroy((Object)(object)entrancePortal);
				}
				if ((Object)(object)exitPortal != (Object)null)
				{
					Object.Destroy((Object)(object)exitPortal);
				}
			}
			if (isConsumingBlood)
			{
				isConsumingBlood = false;
				if (consumeCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(consumeCoroutine);
				}
			}
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetBool("isConsuming", false);
			}
			if ((Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.Stop();
			}
		}

		private IEnumerator PortalSequenceRoutine(Vector3 bloodLocation, bool setOutside)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			isWalkingIntoPortal = true;
			base.movingTowardsTargetPlayer = false;
			if (base.currentSearch != null && base.currentSearch.inProgress)
			{
				((EnemyAI)this).StopSearch(base.currentSearch, true);
			}
			Vector3 entrancePos = ((Component)this).transform.position + ((Component)this).transform.forward * 1.5f;
			entrancePos.y += 2f;
			SpawnEntrancePortalClientRpc(entrancePos, ((Component)this).transform.rotation);
			Quaternion exitRot = Quaternion.Euler(90f, 0f, 0f);
			SpawnExitPortalClientRpc(bloodLocation, exitRot);
			float t = 0f;
			if ((Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
			{
				base.agent.isStopped = false;
				base.agent.SetDestination(entrancePos);
				base.agent.speed = 3f;
			}
			while (t < 1f)
			{
				t += Time.deltaTime;
				yield return null;
			}
			TeleportBWClientRpc(bloodLocation, setOutside);
			isWalkingIntoPortal = false;
			yield return (object)new WaitForSeconds(2f);
			ClosePortalsClientRpc();
		}

		private void TeleportBloodWitch(Vector3 bloodLocation, bool setOutside)
		{
			//IL_006c: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			base.movingTowardsTargetPlayer = false;
			if (base.currentSearch != null && base.currentSearch.inProgress)
			{
				((EnemyAI)this).StopSearch(base.currentSearch, true);
			}
			if (base.isOutside != setOutside)
			{
				((EnemyAI)this).SetEnemyOutside(setOutside);
			}
			if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null)
			{
				base.agent.Warp(bloodLocation);
				base.agent.isStopped = true;
				base.agent.ResetPath();
				base.agent.velocity = Vector3.zero;
			}
			else if (!((NetworkBehaviour)this).IsServer)
			{
				((Component)this).transform.position = bloodLocation;
			}
			if ((Object)(object)teleportSFX != (Object)null && (Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.PlayOneShot(teleportSFX);
			}
			base.serverPosition = bloodLocation;
			consumptionLockPosition = bloodLocation;
		}

		[ServerRpc(RequireOwnership = false)]
		public void TeleportBWServerRpc(Vector3 bloodLocation, bool setOutside)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val2 = default(ServerRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2800373253u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref bloodLocation);
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref setOutside, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 2800373253u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (portalCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(portalCoroutine);
				}
				portalCoroutine = ((MonoBehaviour)this).StartCoroutine(PortalSequenceRoutine(bloodLocation, setOutside));
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void AddBloodSourceServerRpc(Vector3 bloodPosition, string playerUsername)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0129: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val2 = default(ServerRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2747021489u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref bloodPosition);
				bool flag = playerUsername != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(playerUsername, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 2747021489u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				GameObject val3 = new GameObject("PlayerPersistentBloodDrop_" + playerUsername);
				val3.transform.position = bloodPosition;
				EnemyBloodPatch.enemyBloodDrops.Add(val3);
				Object.Destroy((Object)(object)val3, 60f);
			}
		}

		[ClientRpc]
		public void TeleportBWClientRpc(Vector3 bloodLocation, bool setOutside)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00e9: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val2 = default(ClientRpcParams);
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2755236353u, val2, (RpcDelivery)0);
					((FastBufferWriter)(ref val)).WriteValueSafe(ref bloodLocation);
					((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref setOutside, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val, 2755236353u, val2, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					TeleportBloodWitch(bloodLocation, setOutside);
					hasTeleported = true;
				}
			}
		}

		private IEnumerator TransformationRoutine()
		{
			isConsumingBlood = false;
			isWaitingForLevelUp = false;
			isCurrentlyTransforming = true;
			if ((Object)(object)base.agent != (Object)null)
			{
				base.agent.speed = 0f;
				if (base.agent.isOnNavMesh)
				{
					base.agent.isStopped = true;
				}
			}
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetBool("isConsuming", false);
				base.creatureAnimator.SetBool("isTransforming", true);
			}
			if ((Object)(object)transformationSFX != (Object)null && (Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.PlayOneShot(transformationSFX);
			}
			if ((Object)(object)transformationSFXDistant != (Object)null && (Object)(object)distantScreamAudioSource != (Object)null)
			{
				distantScreamAudioSource.clip = transformationSFXDistant;
				distantScreamAudioSource.Play();
			}
			yield return (object)new WaitForSeconds(3f);
			if ((Object)(object)BloodSpurtParticleBackL != (Object)null)
			{
				BloodSpurtParticleBackL.Play();
			}
			if ((Object)(object)BloodSpurtParticleBackR != (Object)null)
			{
				BloodSpurtParticleBackR.Play();
			}
			yield return (object)new WaitForSeconds(3f);
			if ((Object)(object)grannyModelContainer != (Object)null)
			{
				grannyModelContainer.SetActive(false);
			}
			if ((Object)(object)monsterModelContainer != (Object)null)
			{
				monsterModelContainer.SetActive(true);
			}
			if (((NetworkBehaviour)this).IsServer && (Object)(object)base.agent != (Object)null)
			{
				if (base.agent.isOnNavMesh)
				{
					base.agent.isStopped = false;
				}
				base.agent.speed = 4f;
				base.agent.acceleration = 2f;
			}
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetBool("isTransforming", false);
			}
			isCurrentlyTransforming = false;
		}

		private IEnumerator DelayedConsumeBlood(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			ConsumeBlood();
		}

		public void ConsumeBlood()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				int currentLevel = CurrentLevel;
				bloodConsumed++;
				int currentLevel2 = CurrentLevel;
				ConsumeBloodClientRpc(bloodConsumed, currentLevel, currentLevel2);
				ResetTeleportCooldown(currentLevel2);
			}
		}

		private void ResetTeleportCooldown(int level)
		{
			switch (level)
			{
			case 3:
				teleportCooldownTimer = Level3TPCooldown;
				break;
			case 2:
				teleportCooldownTimer = Level2TPCooldown;
				break;
			default:
				teleportCooldownTimer = Level1TPCooldown;
				break;
			}
		}

		[ClientRpc]
		public void ConsumeBloodClientRpc(int newBloodCount, int oldLevel, int newLevel)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3612684352u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, newBloodCount);
				BytePacker.WriteValueBitPacked(val, oldLevel);
				BytePacker.WriteValueBitPacked(val, newLevel);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 3612684352u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			bloodConsumed = newBloodCount;
			LogIfDebugBuild($"Consumed blood! Level is now: {CurrentLevel}");
			if (newLevel > oldLevel)
			{
				ApplyLevelMaterials(newLevel);
			}
			if (newLevel > oldLevel && newLevel < 4 && levelUpScreams != null && levelUpScreams.Length != 0 && (Object)(object)screamAudioSource != (Object)null)
			{
				int num = Random.Range(0, levelUpScreams.Length);
				screamAudioSource.PlayOneShot(levelUpScreams[num]);
				if (levelUpScreamsDistant != null && levelUpScreamsDistant.Length > num && (Object)(object)distantScreamAudioSource != (Object)null)
				{
					distantScreamAudioSource.clip = levelUpScreamsDistant[num];
					distantScreamAudioSource.Play();
				}
			}
		}

		public void CastBloodGeyser(PlayerControllerB player)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsServer || (CurrentLevel < 4 && removableLimbs != null && isLimbDetached != null && isLimbDetached.Length != 0 && isLimbDetached[0]))
			{
				return;
			}
			LogIfDebugBuild("Casting blood geyser on " + player.playerUsername);
			SyncGeyserAnimationClientRpc();
			Vector3 position = ((Component)player).transform.position;
			if ((Object)(object)player == (Object)(object)base.targetPlayer)
			{
				Vector3 val = targetPlayerVelocity;
				if (((Vector3)(ref val)).magnitude > 10f)
				{
					val = ((Vector3)(ref val)).normalized * 10f;
				}
				position += val * 1.5f;
			}
			else
			{
				position += ((Component)player.playerBodyAnimator).transform.forward * 2f;
			}
			Transform val2 = ((EnemyAI)this).ChooseClosestNodeToPosition(position, false, 0);
			if ((Object)(object)val2 != (Object)null)
			{
				if (Vector3.Distance(val2.position, ((Component)player).transform.position) <= 10f)
				{
					position = val2.position;
				}
				else
				{
					Transform val3 = ((EnemyAI)this).ChooseClosestNodeToPosition(((Component)player).transform.position, false, 0);
					if ((Object)(object)val3 != (Object)null)
					{
						position = val3.position;
					}
				}
			}
			SpawnGeyserWarningClientRpc(position);
			((MonoBehaviour)this).StartCoroutine(GeyserAttackDelay(position));
		}

		[ClientRpc]
		public void SyncGeyserAnimationClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1271143743u, val2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 1271143743u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetTrigger("useGeyser");
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SpawnGeyserWarningServerRpc(Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val2 = default(ServerRpcParams);
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(114578014u, val2, (RpcDelivery)0);
					((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
					((NetworkBehaviour)this).__endSendServerRpc(ref val, 114578014u, val2, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					SpawnGeyserWarningClientRpc(position);
				}
			}
		}

		[ClientRpc]
		public void SpawnGeyserWarningClientRpc(Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(4007448664u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 4007448664u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!((Object)(object)geyserPrefab != (Object)null))
			{
				return;
			}
			currentActiveGeyser = Object.Instantiate<GameObject>(geyserPrefab, position, Quaternion.identity);
			Transform val3 = currentActiveGeyser.transform.Find("Warning");
			if ((Object)(object)val3 != (Object)null)
			{
				AudioSource component = ((Component)val3).GetComponent<AudioSource>();
				if ((Object)(object)component != (Object)null)
				{
					component.Play();
				}
			}
		}

		private IEnumerator GeyserAttackDelay(Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(1.5f);
			SpawnGeyserAttackClientRpc(position);
			yield return (object)new WaitForSeconds(2f);
			DestroyGeyserClientRpc();
		}

		[ClientRpc]
		public void SpawnGeyserAttackClientRpc(Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(846989029u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 846989029u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if ((Object)(object)currentActiveGeyser != (Object)null)
			{
				Animator componentInChildren = currentActiveGeyser.GetComponentInChildren<Animator>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.SetBool("Toggle Geyser", true);
				}
				VisualEffect componentInChildren2 = currentActiveGeyser.GetComponentInChildren<VisualEffect>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.SetBool("Toggle Geyser", true);
				}
				Transform val3 = currentActiveGeyser.transform.Find("Cast");
				if ((Object)(object)val3 != (Object)null)
				{
					AudioSource component = ((Component)val3).GetComponent<AudioSource>();
					if ((Object)(object)component != (Object)null)
					{
						component.Play();
					}
				}
			}
			((MonoBehaviour)this).StartCoroutine(ClientGeyserDamageRoutine(position));
		}

		private IEnumerator ClientGeyserDamageRoutine(Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			for (float l