Decompiled source of ZombieJoiner v1.0.1

ZombieJoiner.dll

Decompiled a day ago
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ZombieJoiner")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ZombieJoiner")]
[assembly: AssemblyTitle("ZombieJoiner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Zombiejoin
{
	[BepInPlugin("ZombieJoiner", "ZombieJoiner", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <SpawnZombieRoutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private Character <localCharacter>5__1;

			private Vector3 <spawnPos>5__2;

			private Quaternion <spawnRot>5__3;

			private Bodypart <torso>5__4;

			private GameObject <zombieObj>5__5;

			private MushroomZombie <zombie>5__6;

			private ZombiePlayerAgent <agent>5__7;

			private Vector3 <forward>5__8;

			private Exception <ex>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnZombieRoutine>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<localCharacter>5__1 = null;
				<torso>5__4 = null;
				<zombieObj>5__5 = null;
				<zombie>5__6 = null;
				<agent>5__7 = null;
				<ex>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//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_0079: 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_00b2: 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_00c8: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: 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_0174: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this._isSpawning = true;
					<localCharacter>5__1 = Character.localCharacter;
					if ((Object)(object)<localCharacter>5__1 == (Object)null)
					{
						<>4__this._isSpawning = false;
						return false;
					}
					<spawnPos>5__2 = <localCharacter>5__1.Center;
					<spawnRot>5__3 = Quaternion.identity;
					<torso>5__4 = <localCharacter>5__1.GetBodypart((BodypartType)2);
					if ((Object)(object)<torso>5__4 != (Object)null)
					{
						<spawnPos>5__2 = ((Component)<torso>5__4).transform.position;
						<spawnRot>5__3 = ((Component)<torso>5__4).transform.rotation;
					}
					if (<>4__this._spawnNearPlayer.Value)
					{
						<forward>5__8 = <localCharacter>5__1.data.lookDirection;
						if (<forward>5__8 == Vector3.zero)
						{
							<forward>5__8 = ((Component)<localCharacter>5__1).transform.forward;
						}
						<forward>5__8.y = 0f;
						if (((Vector3)(ref <forward>5__8)).sqrMagnitude < 0.001f)
						{
							<forward>5__8 = Vector3.forward;
						}
						((Vector3)(ref <forward>5__8)).Normalize();
						<spawnPos>5__2 += <forward>5__8 * <>4__this._spawnForwardOffset.Value;
					}
					try
					{
						<zombieObj>5__5 = PhotonNetwork.Instantiate(<>4__this._zombiePrefabName.Value, <spawnPos>5__2, <spawnRot>5__3, (byte)0, (object[])null);
					}
					catch (Exception ex)
					{
						<ex>5__9 = ex;
						Log.LogError((object)$"Failed to instantiate zombie prefab '{<>4__this._zombiePrefabName.Value}': {<ex>5__9}");
						<>4__this._isSpawning = false;
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if ((Object)(object)<zombieObj>5__5 == (Object)null)
					{
						Log.LogError((object)"Zombie instantiate returned null.");
						<>4__this._isSpawning = false;
						return false;
					}
					<zombie>5__6 = <zombieObj>5__5.GetComponent<MushroomZombie>();
					if ((Object)(object)<zombie>5__6 == (Object)null)
					{
						Log.LogError((object)"Spawned object does not contain MushroomZombie component.");
						<>4__this._isSpawning = false;
						return false;
					}
					<zombie>5__6.isNPCZombie = false;
					<zombie>5__6.spawner = null;
					<zombie>5__6.lifetime = 999999f;
					if ((Object)(object)ZombieManager.Instance != (Object)null)
					{
						ZombieManager.Instance.DeRegisterZombie(<zombie>5__6);
					}
					if ((Object)(object)<zombie>5__6.character == (Object)null || (Object)(object)<zombie>5__6.character.data == (Object)null)
					{
						Log.LogError((object)"Spawned zombie has no Character or CharacterData.");
						SafeDestroySpawnedObject(<zombieObj>5__5);
						<>4__this._isSpawning = false;
						return false;
					}
					<zombie>5__6.character.isZombie = true;
					<zombie>5__6.character.data.passedOut = false;
					<zombie>5__6.character.data.fullyPassedOut = false;
					<zombie>5__6.character.data.dead = false;
					<zombie>5__6.character.data.fallSeconds = 0f;
					<zombie>5__6.character.data.currentRagdollControll = 1f;
					<zombie>5__6.currentState = (State)2;
					if (!<zombie>5__6.visible)
					{
						((MonoBehaviour)<zombie>5__6).StartCoroutine(<zombie>5__6.RevealZombie());
					}
					<agent>5__7 = ((Component)<zombie>5__6).gameObject.GetComponent<ZombiePlayerAgent>();
					if ((Object)(object)<agent>5__7 == (Object)null)
					{
						<agent>5__7 = ((Component)<zombie>5__6).gameObject.AddComponent<ZombiePlayerAgent>();
					}
					<agent>5__7.Initialize(<zombie>5__6);
					Log.LogInfo((object)"Spawned one controlled zombie player.");
					<>4__this._isSpawning = false;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string ModGuid = "ZombieJoiner";

		public const string ModName = "ZombieJoiner";

		public const string ModVersion = "1.0.1";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private Harmony _harmony = null;

		private ConfigEntry<KeyCode> _spawnKey = null;

		private ConfigEntry<KeyCode> _deleteKey = null;

		private ConfigEntry<string> _zombiePrefabName = null;

		private ConfigEntry<float> _spawnForwardOffset = null;

		private ConfigEntry<bool> _spawnNearPlayer = null;

		private bool _isSpawning;

		private void Awake()
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_spawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "SpawnZombieKey", (KeyCode)106, "Press this key to spawn one controlled zombie player.");
			_deleteKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "DeleteZombieKey", (KeyCode)107, "Press this key to delete the nearest controlled zombie player.");
			_zombiePrefabName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ZombiePrefabName", "MushroomZombie", "Photon prefab name of the zombie to spawn.");
			_spawnForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnForwardOffset", 2.5f, "How far in front of the player to spawn the zombie.");
			_spawnNearPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SpawnNearPlayer", true, "Spawn zombie near the player.");
			_harmony = new Harmony("ZombieJoiner");
			_harmony.PatchAll();
			Log.LogInfo((object)"ZombieJoiner loaded.");
		}

		private void OnDestroy()
		{
			try
			{
				_harmony.UnpatchSelf();
			}
			catch (Exception arg)
			{
				Log.LogDebug((object)$"UnpatchSelf failed: {arg}");
			}
		}

		private void Update()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Input.GetKeyDown(_deleteKey.Value))
				{
					DeleteNearestZombie();
				}
				else if (Input.GetKeyDown(_spawnKey.Value) && !_isSpawning)
				{
					if (!PhotonNetwork.InRoom)
					{
						Log.LogWarning((object)"Not in a room.");
					}
					else if ((Object)(object)Character.localCharacter == (Object)null)
					{
						Log.LogWarning((object)"Local character not found.");
					}
					else
					{
						((MonoBehaviour)this).StartCoroutine(SpawnZombieRoutine());
					}
				}
			}
			catch (Exception arg)
			{
				Log.LogDebug((object)$"Plugin.Update failed: {arg}");
			}
		}

		private void DeleteNearestZombie()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!PhotonNetwork.InRoom)
				{
					Log.LogWarning((object)"Not in a room.");
					return;
				}
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null)
				{
					Log.LogWarning((object)"Local character not found.");
					return;
				}
				ZombiePlayerAgent zombiePlayerAgent = ZombiePlayerAgent.FindNearest(localCharacter.Center);
				if ((Object)(object)zombiePlayerAgent == (Object)null || (Object)(object)zombiePlayerAgent.Character == (Object)null)
				{
					Log.LogInfo((object)"No controlled zombie found to delete.");
					return;
				}
				int num = (((Object)(object)zombiePlayerAgent.View != (Object)null) ? zombiePlayerAgent.View.ViewID : (-1));
				zombiePlayerAgent.DeleteZombieNetworked();
				Log.LogInfo((object)$"Deleted controlled zombie [{num}].");
			}
			catch (Exception arg)
			{
				Log.LogDebug((object)$"DeleteNearestZombie failed: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<SpawnZombieRoutine>d__16))]
		private IEnumerator SpawnZombieRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnZombieRoutine>d__16(0)
			{
				<>4__this = this
			};
		}

		private static void SafeDestroySpawnedObject(GameObject obj)
		{
			try
			{
				if (!((Object)(object)obj == (Object)null))
				{
					PhotonView component = obj.GetComponent<PhotonView>();
					if ((Object)(object)component != (Object)null && PhotonNetwork.InRoom)
					{
						PhotonNetwork.Destroy(obj);
					}
					else
					{
						Object.Destroy((Object)(object)obj);
					}
				}
			}
			catch (Exception arg)
			{
				Log.LogDebug((object)$"SafeDestroySpawnedObject failed: {arg}");
				try
				{
					Object.Destroy((Object)(object)obj);
				}
				catch
				{
				}
			}
		}
	}
	internal enum ZombieBrainState
	{
		Idle,
		Chase,
		PrepareTallClimb,
		Reposition,
		Lunge,
		LungeRecovery,
		Dead
	}
	internal enum PathActionType
	{
		None,
		Direct,
		Detour,
		Climb,
		JumpGrab,
		GapJump,
		DropDown,
		Hold
	}
	internal sealed class PathPlan
	{
		public PathActionType Action = PathActionType.None;

		public Vector3 Goal;

		public Vector3 Anchor;

		public float RequiredStamina;

		public bool TargetAbove;

		public float EstimatedClimbHeight;

		public bool IsTallWall;

		public float ExpectedDropHeight;

		public bool UsesJumpDropImmunity;

		public bool ReachableWithinRecoverableBudget;

		public float Score;

		public bool NeedsJumpStart;

		public Vector3 ClimbTopPoint;

		public Vector3 ClimbSurfaceNormal;

		public Vector3 JumpGrabAimPoint;

		public float JumpGrabHorizontalDistance;
	}
	internal struct RouteProbe
	{
		public bool ObstacleAhead;

		public float ObstacleDistance;

		public Vector3 ObstaclePoint;

		public bool ClimbableAhead;

		public float ClimbHeightDelta;

		public Vector3 ClimbBasePoint;

		public bool NeedsJumpStart;

		public Vector3 ClimbTopPoint;

		public Vector3 ClimbSurfaceNormal;

		public bool UnsafeDropAhead;

		public float DropHeight;

		public bool SafeWalkDrop;

		public bool SafeJumpDrop;

		public Vector3 DropLandingPoint;

		public bool GapJumpable;

		public Vector3 GapLandingPoint;

		public float GapLandingDrop;
	}
	internal sealed class BlockedMemory
	{
		public Vector3 Point = Vector3.zero;

		public float Until;
	}
	internal struct PingTargetData
	{
		public Vector3 Point;

		public float Time;

		public int Sequence;
	}
	internal static class ZombiePingTracker
	{
		private static readonly Dictionary<int, PingTargetData> LastPingByCharacter = new Dictionary<int, PingTargetData>();

		private static int _sequence;

		public const float PingLifetime = 30f;

		private static int GetKey(Character character)
		{
			return ((Object)(object)character != (Object)null) ? ((Object)character).GetInstanceID() : 0;
		}

		public static void SetPing(Character character, Vector3 point)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)character == (Object)null))
			{
				LastPingByCharacter[GetKey(character)] = new PingTargetData
				{
					Point = point,
					Time = Time.time,
					Sequence = ++_sequence
				};
			}
		}

		public static bool TryGetLatestPingForZombie(Vector3 zombiePos, out Character? owner, out Vector3 point)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			owner = null;
			point = Vector3.zero;
			int num = int.MinValue;
			bool flag = false;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.isBot && !allCharacter.data.dead && !allCharacter.data.fullyPassedOut && TryGetPingData(allCharacter, out var data) && (!flag || data.Sequence > num))
				{
					flag = true;
					num = data.Sequence;
					owner = allCharacter;
					point = data.Point;
				}
			}
			return flag;
		}

		public static bool TryGetBestPingForZombie(Vector3 zombiePos, out Character? owner, out Vector3 point)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return TryGetLatestPingForZombie(zombiePos, out owner, out point);
		}

		public static bool TryGetPing(Character character, out Vector3 point)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			point = Vector3.zero;
			if (!TryGetPingData(character, out var data))
			{
				return false;
			}
			point = data.Point;
			return true;
		}

		private static bool TryGetPingData(Character character, out PingTargetData data)
		{
			data = default(PingTargetData);
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			int key = GetKey(character);
			if (!LastPingByCharacter.TryGetValue(key, out data))
			{
				return false;
			}
			if (Time.time - data.Time > 30f)
			{
				LastPingByCharacter.Remove(key);
				return false;
			}
			return true;
		}

		public static void ClearPing(Character character)
		{
			if (!((Object)(object)character == (Object)null))
			{
				LastPingByCharacter.Remove(GetKey(character));
			}
		}
	}
	[HarmonyPatch(typeof(PointPinger), "ReceivePoint_Rpc")]
	internal static class PointPingerReceivePatch
	{
		[HarmonyPostfix]
		private static void Postfix(PointPinger __instance, Vector3 point)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.character == (Object)null))
				{
					ZombiePingTracker.SetPing(__instance.character, point);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"PointPingerReceivePatch failed: {arg}");
			}
		}
	}
	internal sealed class ZombiePlayerAgent : MonoBehaviour
	{
		internal sealed class FailedSegmentMemory
		{
			public PathActionType Action = PathActionType.None;

			public Vector3 Position = Vector3.zero;

			public Vector3 Direction = Vector3.zero;

			public float Until;
		}

		private readonly List<FailedSegmentMemory> _failedSegments = new List<FailedSegmentMemory>();

		public static readonly List<ZombiePlayerAgent> All = new List<ZombiePlayerAgent>();

		private bool _rawGoalIsStandable;

		private const float ImmediateDirectClimbFlatDistance = 2.35f;

		private const float ImmediateDirectClimbVerticalSlack = 0.55f;

		private const float SmallObstacleHopCooldown = 0.12f;

		private const float SmallObstacleHopMinStamina = 0.02f;

		private const float GoalExactStandFlatRadius = 0.3f;

		private const float GoalExactStandVerticalTolerance = 0.3f;

		private const float ObstacleBypassJumpMinHeight = 0.28f;

		private const float ObstacleBypassJumpMaxHeight = 1.55f;

		private const float ObstacleBypassJumpMaxLandingDelta = 0.9f;

		public bool canBeCarriedAsZombie;

		public bool suppressZombieAI;

		public float zombieInteractionLock;

		public float lastZombieFedTime;

		private const float EdgeGoalSupportProbeRadius = 0.45f;

		private const float EdgeGoalSupportProbeHeight = 0.65f;

		private const float EdgeGoalSupportDropTolerance = 1.4f;

		private const float EdgeGoalResolvedReuseDistance = 0.9f;

		private const float EdgeGoalRawOffsetThreshold = 0.55f;

		private const float EdgeGoalArriveFlat = 1.85f;

		private const float EdgeGoalArriveVertical = 2.6f;

		private const float EdgeGoalNearPlanDistance = 2.2f;

		private PathPlan _lockedClimbPlan = new PathPlan();

		private bool _hasLockedClimbPlan;

		private readonly Queue<PathPlan> _segmentQueue = new Queue<PathPlan>();

		private PathPlan _activeSegment = new PathPlan();

		private bool _hasActiveSegment;

		private float _routeWindowStartTime;

		private float _routeWindowStartGoalDistance;

		private Vector3 _segmentStartPos;

		private float _segmentStartTime;

		private float _segmentStartGoalDistance;

		private Vector3 _lastAcceptedGoalPoint = Vector3.zero;

		private bool _hadAcceptedGoalPoint;

		private float _nextReplanTime;

		private const float ImmediateJumpGrabMaxFlatDistance = 3.2f;

		private const float ImmediateJumpGrabMinHeightDelta = 1f;

		private const float ImmediateJumpGrabMaxHeightDelta = 4.8f;

		private const float ImmediateJumpGrabAnchorRadius = 1.6f;

		private const float SegmentMinProgressTime = 1.2f;

		private const float SegmentProgressTimeout = 3f;

		private const float SegmentMinGoalProgress = 1f;

		private const float SegmentArriveDistance = 1.25f;

		private const float SegmentArriveVertical = 1.75f;

		private const float RouteNetProgressWindow = 2.5f;

		private const float RouteNetProgressMin = 0.9f;

		private const float ReplanCooldown = 0.25f;

		private const int MaxPlannedSegments = 4;

		private float _repositionUntil;

		private const float ClimbStartGraceTime = 0.45f;

		private const float RepositionMinDuration = 1.1f;

		private const float DirectBlockedPenaltyThreshold = 1.1f;

		private const float ClimbLastStaminaBurstThreshold = 0.05f;

		private MushroomZombie _zombie = null;

		private Character _character = null;

		private PhotonView _view = null;

		private ZombieBrainState _brainState = ZombieBrainState.Idle;

		private Character? _ownerCharacter;

		private Character? _target;

		private Vector3 _goalPoint;

		private bool _hasGoalPoint;

		private Vector3 _resolvedGoalPoint;

		private bool _hasResolvedGoalPoint;

		private bool _resolvedGoalIsStandable;

		private float _nextResolvedGoalRefreshTime;

		private float _nextTargetRefreshTime;

		private float _lastSeenTargetTime;

		private float _timeInChase;

		private float _timeInLunge;

		private float _stuckTimer;

		private Vector3 _stuckAnchor;

		private int _stuckCount;

		private float _climbTimer;

		private float _climbStartHeight;

		private int _failedClimbCount;

		private float _lastAutoJumpTime;

		private PathPlan _plan = new PathPlan();

		private readonly List<BlockedMemory> _blockedMemory = new List<BlockedMemory>();

		private bool _initialized;

		private State _lastVisualZombieState = (State)(-1);

		private bool _lastVisualBiteColliderEnabled;

		private bool _lastVisualSprintState;

		private bool _hasVisualStateSnapshot;

		private const float ProbeDistance = 2.2f;

		private const float GroundProbeHeight = 2.2f;

		private const float GroundProbeDepth = 16f;

		private const float ObstacleProbeRadius = 0.38f;

		private const float MaxSafeWalkDrop = 10f;

		private const float MaxSafeJumpDrop = 20f;

		private const float GapJumpNear = 1.8f;

		private const float GapJumpFar = 4.8f;

		private const float MaxClimbHeight = 4.2f;

		private const float TargetAboveThreshold = 1.4f;

		private const float OverheadSearchRadius = 3.5f;

		private const float TravelHopInterval = 0.2f;

		private const float ChainJumpStaminaThreshold = 0.35f;

		private const float StickyClimbMinTime = 0.8f;

		private const float StickyClimbTopReleaseFlat = 1.8f;

		private const float StickyClimbTopReleaseVertical = -1f;

		private const float TallWallHeightThreshold = 2.15f;

		private const float SmallWallFastClimbThreshold = 1.2f;

		private const float ClimbBurstStartProgress = 0.55f;

		private const float ClimbBurstMinStamina = 0.01f;

		private const float ClosePressureFlat = 1.65f;

		private const float ClosePressureVertical = 1.15f;

		private const float CloseStopFlat = 0.55f;

		private const float JumpGrabMinVertical = 1f;

		private const float JumpGrabMaxVertical = 4.6f;

		private const float JumpGrabPressInterval = 0.2f;

		private const float JumpGrabMinStamina = 0.04f;

		private const float ClimbTraverseStrongX = 0.95f;

		private const float ClimbTraverseWeakX = 0.6f;

		private const float ClimbDiagonalUp = 0.95f;

		private const float ClimbVerticalUp = 1f;

		private const float ClimbBurstSprintXBoost = 1.15f;

		private const float ClimbBurstSprintYBoost = 1.12f;

		private const float ClimbTopAssistDistance = 1.25f;

		private const float GoalArriveFlatDistance = 1.35f;

		private const float GoalArriveVerticalDistance = 2.25f;

		private const float ClimbWaitAnchorDistance = 1.35f;

		private const float ClimbResumeHysteresis = 0.02f;

		private const float GoalStandSearchRadius = 1.2f;

		private const float GoalStandPreferRadius = 0.95f;

		private const float ResolvedGoalRefreshInterval = 0.2f;

		private const float SmallObstacleHeightMax = 1.1f;

		private const float SmallObstacleForwardCheck = 1f;

		private static readonly float[] SearchAngles = new float[11]
		{
			0f, 20f, -20f, 40f, -40f, 60f, -60f, 90f, -90f, 120f,
			-120f
		};

		private static readonly float[] OverheadAngles = new float[14]
		{
			0f, 20f, -20f, 40f, -40f, 60f, -60f, 90f, -90f, 120f,
			-120f, 150f, -150f, 180f
		};

		private static readonly float[] LateralTraverseSamples = new float[4] { 0.7f, 1.1f, 1.5f, 2f };

		private static readonly int TerrainMask = LayerMask.GetMask(new string[2] { "Terrain", "Map" });

		private static readonly MethodInfo? PushStateMethod = AccessTools.Method(typeof(MushroomZombie), "PushState", (Type[])null, (Type[])null);

		private ZombieBrainState _lastLoggedBrainState = (ZombieBrainState)(-1);

		public Character? Character => _character;

		public PhotonView? View => _view;

		public static ZombiePlayerAgent? FindNearest(Vector3 point)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			ZombiePlayerAgent result = null;
			float num = float.PositiveInfinity;
			for (int num2 = All.Count - 1; num2 >= 0; num2--)
			{
				ZombiePlayerAgent zombiePlayerAgent = All[num2];
				if ((Object)(object)zombiePlayerAgent == (Object)null || !zombiePlayerAgent._initialized || (Object)(object)zombiePlayerAgent._character == (Object)null)
				{
					All.RemoveAt(num2);
				}
				else
				{
					float num3 = Vector3.Distance(point, zombiePlayerAgent._character.Center);
					if (num3 < num)
					{
						num = num3;
						result = zombiePlayerAgent;
					}
				}
			}
			return result;
		}

		public void Initialize(MushroomZombie zombie)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)zombie == (Object)null || (Object)(object)zombie.character == (Object)null || (Object)(object)zombie.character.data == (Object)null)
			{
				Plugin.Log.LogError((object)"ZombiePlayerAgent.Initialize failed: invalid zombie or character data.");
				((Behaviour)this).enabled = false;
				return;
			}
			_lockedClimbPlan = new PathPlan();
			_hasLockedClimbPlan = false;
			_repositionUntil = 0f;
			PhotonView component = ((Component)zombie).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)"ZombiePlayerAgent requires PhotonView on MushroomZombie object.");
				((Behaviour)this).enabled = false;
				return;
			}
			_zombie = zombie;
			_character = zombie.character;
			_view = component;
			_ownerCharacter = Character.localCharacter;
			_target = _ownerCharacter;
			_goalPoint = Vector3.zero;
			_hasGoalPoint = false;
			_resolvedGoalPoint = Vector3.zero;
			_hasResolvedGoalPoint = false;
			_resolvedGoalIsStandable = false;
			_nextResolvedGoalRefreshTime = 0f;
			_brainState = ZombieBrainState.Idle;
			_nextTargetRefreshTime = 0f;
			_lastSeenTargetTime = Time.time;
			_timeInChase = 0f;
			_timeInLunge = 0f;
			_stuckTimer = 0f;
			_stuckAnchor = _character.Center;
			_stuckCount = 0;
			_climbTimer = 0f;
			_climbStartHeight = 0f;
			_failedClimbCount = 0;
			_lastAutoJumpTime = -999f;
			_plan = new PathPlan();
			_blockedMemory.Clear();
			_failedSegments.Clear();
			_segmentQueue.Clear();
			ClearActiveSegment();
			ClearLockedClimbPlan();
			_lastVisualZombieState = (State)(-1);
			_lastVisualBiteColliderEnabled = false;
			_lastVisualSprintState = false;
			_hasVisualStateSnapshot = false;
			canBeCarriedAsZombie = true;
			suppressZombieAI = false;
			zombieInteractionLock = 0f;
			lastZombieFedTime = -999f;
			_initialized = true;
			if (!All.Contains(this))
			{
				All.Add(this);
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}

		public void DeleteZombieNetworked()
		{
			try
			{
				PrepareForDelete();
				if ((Object)(object)_view != (Object)null && PhotonNetwork.InRoom)
				{
					if (!_view.IsMine && !PhotonNetwork.IsMasterClient)
					{
						try
						{
							_view.RequestOwnership();
						}
						catch (Exception arg)
						{
							Plugin.Log.LogDebug((object)$"DeleteZombieNetworked RequestOwnership failed: {arg}");
						}
					}
					PhotonNetwork.Destroy(((Component)this).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogDebug((object)$"DeleteZombieNetworked failed: {arg2}");
				try
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				catch
				{
				}
			}
		}

		private void PrepareForDelete()
		{
			_initialized = false;
			suppressZombieAI = true;
			All.Remove(this);
			try
			{
				ResetInput();
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_character != (Object)null && (Object)(object)_character.data != (Object)null)
				{
					_character.data.grabbingPlayer = null;
					_character.data.grabbedPlayer = null;
					_character.data.carriedPlayer = null;
					_character.data.carrier = null;
					_character.data.isCarried = false;
					_character.data.currentItem = null;
				}
			}
			catch
			{
			}
		}

		private void UpdateInteractionState()
		{
			if (zombieInteractionLock > 0f)
			{
				zombieInteractionLock -= Time.deltaTime;
				if (zombieInteractionLock < 0f)
				{
					zombieInteractionLock = 0f;
				}
			}
			if (!((Object)(object)_character == (Object)null))
			{
				bool flag = (Object)(object)_character.data.grabbingPlayer != (Object)null;
				if (_character.data.isCarried || (Object)(object)_character.data.carrier != (Object)null)
				{
					suppressZombieAI = true;
					canBeCarriedAsZombie = true;
					zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f);
				}
				else if (flag)
				{
					suppressZombieAI = true;
					canBeCarriedAsZombie = true;
					zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f);
				}
				else if (zombieInteractionLock <= 0f)
				{
					suppressZombieAI = false;
					canBeCarriedAsZombie = true;
				}
			}
		}

		public void NotifyGrabbedByPlayer(Character player)
		{
			suppressZombieAI = true;
			canBeCarriedAsZombie = true;
			zombieInteractionLock = Mathf.Max(zombieInteractionLock, 2f);
		}

		public void NotifyReleasedByPlayer(Character player)
		{
			zombieInteractionLock = Mathf.Max(zombieInteractionLock, 1.25f);
			if (!_character.data.isCarried)
			{
				suppressZombieAI = false;
			}
		}

		public void NotifyCarriedByPlayer(Character player)
		{
			suppressZombieAI = true;
			canBeCarriedAsZombie = true;
			zombieInteractionLock = 999f;
		}

		public void NotifyDroppedByPlayer(Character player)
		{
			zombieInteractionLock = 1.5f;
			suppressZombieAI = false;
			canBeCarriedAsZombie = true;
		}

		[PunRPC]
		public void RPC_AssistDrag(Vector3 helperCenter, float force)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null) && (!((Object)(object)_view != (Object)null) || _view.IsMine || PhotonNetwork.IsMasterClient))
				{
					_character.DragTowards(helperCenter, force);
					_character.LimitFalling();
					if (_character.data.isClimbing)
					{
						_character.data.sinceGrounded = 0f;
					}
					suppressZombieAI = true;
					canBeCarriedAsZombie = true;
					zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.35f);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"RPC_AssistDrag failed: {arg}");
			}
		}

		public void NotifyFedByPlayer(Character player, Item item)
		{
			lastZombieFedTime = Time.time;
			canBeCarriedAsZombie = true;
			suppressZombieAI = true;
			zombieInteractionLock = Mathf.Max(zombieInteractionLock, 8f);
		}

		public bool CanBeHelpedByPlayer()
		{
			if ((Object)(object)_character == (Object)null)
			{
				return false;
			}
			if (_character.data.dead)
			{
				return false;
			}
			if (_character.IsStuck() || _character.data.sinceUnstuck < 1f)
			{
				return true;
			}
			if ((Object)(object)_character.refs.afflictions != (Object)null && _character.refs.afflictions.isWebbed)
			{
				return true;
			}
			if (_character.data.isClimbing || _character.data.isRopeClimbing || _character.data.isVineClimbing)
			{
				return true;
			}
			if (zombieInteractionLock > 0f)
			{
				return true;
			}
			return false;
		}

		private void TickSuppressedByInteraction()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			_zombie.currentState = (State)2;
			_character.data.passedOut = false;
			ResetInput();
			SetSprint(sprinting: false);
			if (_character.data.isClimbing)
			{
				StopClimb();
			}
			if ((Object)(object)_character.data.currentClimbHandle != (Object)null)
			{
				_character.refs.climbing.CancelHandle(false);
			}
			_character.input.movementInput = Vector2.zero;
			Vector3 lookAtPos = _character.Head + _character.data.lookDirection_Flat * 2f;
			LookAt(lookAtPos);
		}

		private void BeginSegment(PathPlan segment)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			_activeSegment = ClonePlan(segment);
			_hasActiveSegment = true;
			_segmentStartPos = _character.Center;
			_segmentStartTime = Time.time;
			_segmentStartGoalDistance = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f);
		}

		private void ClearActiveSegment()
		{
			_activeSegment = new PathPlan();
			_hasActiveSegment = false;
		}

		private bool IsSegmentFinished(PathPlan segment)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			float num = HelperFunctions.FlatDistance(_character.Center, segment.Goal);
			float num2 = Mathf.Abs(segment.Goal.y - _character.Center.y);
			switch (segment.Action)
			{
			case PathActionType.Direct:
			case PathActionType.Detour:
				return num <= 1.25f && num2 <= 1.75f;
			case PathActionType.Climb:
				if (!_character.data.isClimbing)
				{
					float num3 = HelperFunctions.FlatDistance(_character.Center, GetGoalCenter());
					return num3 <= 2f || num <= 1.8f;
				}
				return false;
			case PathActionType.GapJump:
			case PathActionType.DropDown:
				return num <= 1.8f && num2 <= 2f;
			case PathActionType.Hold:
				return true;
			default:
				return false;
			}
		}

		private bool IsSegmentFailed(PathPlan segment)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.time - _segmentStartTime;
			if (num < 1.2f)
			{
				return false;
			}
			float num2 = Vector3.Distance(_character.Center, _segmentStartPos);
			if (segment.Action == PathActionType.Climb)
			{
				float num3 = _character.Center.y - _segmentStartPos.y;
				if (num >= 3f && num3 < 0.35f && num2 < 0.8f)
				{
					return true;
				}
				return false;
			}
			float num4 = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f);
			float num5 = _segmentStartGoalDistance - num4;
			if (num >= 3f && num2 < 1f && num5 < 1f)
			{
				return true;
			}
			return false;
		}

		private List<PathPlan> BuildPathSegments()
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			List<PathPlan> list = new List<PathPlan>();
			if (!HasActiveGoal())
			{
				return list;
			}
			Vector3 startPos = _character.Center;
			PathPlan a = new PathPlan();
			bool flag = false;
			for (int i = 0; i < 4; i++)
			{
				PathPlan pathPlan = BuildPathPlanFrom(startPos);
				if (i == 0 && pathPlan.Action == PathActionType.None)
				{
					pathPlan = BuildPathPlanFrom(_character.Center);
				}
				if (pathPlan.Action == PathActionType.None || pathPlan.Action == PathActionType.Hold || (flag && !IsMeaningfullyDifferentSegment(a, pathPlan)))
				{
					break;
				}
				float failedSegmentPenalty = GetFailedSegmentPenalty(pathPlan);
				if (failedSegmentPenalty >= 3f && list.Count > 0)
				{
					break;
				}
				list.Add(pathPlan);
				if (pathPlan.Action == PathActionType.GapJump)
				{
					Vector3 goal = pathPlan.Goal;
					Vector3 goalCenter = GetGoalCenter();
					if (goalCenter.y - goal.y > 1f)
					{
						PathPlan pathPlan2 = BuildPathPlanFrom(goal);
						if ((pathPlan2.Action == PathActionType.Climb || pathPlan2.Action == PathActionType.Detour || pathPlan2.Action == PathActionType.Direct) && list.Count < 4)
						{
							list.Add(pathPlan2);
						}
					}
					break;
				}
				if (pathPlan.Action == PathActionType.Detour)
				{
					float num = GetGoalCenter().y - pathPlan.Goal.y;
					if (num < -1.5f)
					{
						break;
					}
				}
				if (IsSegmentCloseToFinalGoal(pathPlan))
				{
					break;
				}
				startPos = pathPlan.Goal;
				a = pathPlan;
				flag = true;
			}
			return list;
		}

		public bool Controls(MushroomZombie zombie)
		{
			return _initialized && (Object)(object)zombie == (Object)(object)_zombie;
		}

		private bool HasActiveGoal()
		{
			return (Object)(object)_target != (Object)null && _hasGoalPoint;
		}

		private Vector3 GetRawGoalCenter()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return _goalPoint;
		}

		private Vector3 GetGoalCenter()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return _hasResolvedGoalPoint ? _resolvedGoalPoint : _goalPoint;
		}

		private Vector3 GetCurrentMoveTarget()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (_hasActiveSegment)
			{
				return _activeSegment.Goal;
			}
			return GetGoalLookPoint();
		}

		private bool IsMeaningfullyDifferentSegment(PathPlan a, PathPlan b)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (a.Action != b.Action)
			{
				return true;
			}
			float num = Vector3.Distance(a.Goal, b.Goal);
			float num2 = Vector3.Distance(a.Anchor, b.Anchor);
			if (num > 1.25f)
			{
				return true;
			}
			if (num2 > 1f)
			{
				return true;
			}
			return false;
		}

		private bool IsSegmentCloseToFinalGoal(PathPlan segment)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return true;
			}
			float num = HelperFunctions.FlatDistance(segment.Goal, GetGoalCenter());
			float num2 = Mathf.Abs(segment.Goal.y - GetGoalCenter().y);
			return num <= 1.875f && num2 <= 2.625f;
		}

		private void ResetRouteProgressWindow()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			_routeWindowStartTime = Time.time;
			_routeWindowStartGoalDistance = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f);
		}

		private bool IsRouteMakingNetProgress()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return true;
			}
			float num = Time.time - _routeWindowStartTime;
			if (num < 2.5f)
			{
				return true;
			}
			float num2 = Vector3.Distance(_character.Center, GetGoalCenter());
			float num3 = _routeWindowStartGoalDistance - num2;
			return num3 >= 0.9f;
		}

		private Vector3 GetGoalLookPoint()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return GetGoalCenter() + Vector3.up * 0.15f;
		}

		private float GetGoalFlatDistance()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return 999f;
			}
			return HelperFunctions.FlatDistance(_character.Center, GetGoalCenter());
		}

		private static PathPlan ClonePlan(PathPlan src)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			return new PathPlan
			{
				Action = src.Action,
				Goal = src.Goal,
				Anchor = src.Anchor,
				RequiredStamina = src.RequiredStamina,
				TargetAbove = src.TargetAbove,
				EstimatedClimbHeight = src.EstimatedClimbHeight,
				IsTallWall = src.IsTallWall,
				ExpectedDropHeight = src.ExpectedDropHeight,
				UsesJumpDropImmunity = src.UsesJumpDropImmunity,
				ReachableWithinRecoverableBudget = src.ReachableWithinRecoverableBudget,
				Score = src.Score,
				NeedsJumpStart = src.NeedsJumpStart,
				ClimbTopPoint = src.ClimbTopPoint,
				ClimbSurfaceNormal = src.ClimbSurfaceNormal,
				JumpGrabAimPoint = src.JumpGrabAimPoint,
				JumpGrabHorizontalDistance = src.JumpGrabHorizontalDistance
			};
		}

		private PathPlan BuildHoldPlan(Vector3 goalLook, bool targetAbove)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new PathPlan
			{
				Action = PathActionType.Hold,
				Goal = goalLook,
				Anchor = goalLook,
				TargetAbove = targetAbove
			};
		}

		private bool TryCreateImmediateDropPlan(Vector3 startPos, Vector3 dir, float flatDist, RouteProbe probe, out PathPlan plan)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			plan = new PathPlan();
			Vector3 anchor = startPos + dir * Mathf.Min(1f, flatDist);
			if (probe.SafeWalkDrop)
			{
				plan.Action = PathActionType.DropDown;
				plan.Goal = probe.DropLandingPoint;
				plan.Anchor = anchor;
				plan.TargetAbove = false;
				plan.RequiredStamina = 0.02f;
				plan.ExpectedDropHeight = probe.DropHeight;
				plan.UsesJumpDropImmunity = false;
				plan.ReachableWithinRecoverableBudget = true;
				plan.Score = 3f - probe.DropHeight * 0.04f;
				return true;
			}
			if (probe.SafeJumpDrop)
			{
				plan.Action = PathActionType.DropDown;
				plan.Goal = probe.DropLandingPoint;
				plan.Anchor = anchor;
				plan.TargetAbove = false;
				plan.RequiredStamina = 0.08f;
				plan.ExpectedDropHeight = probe.DropHeight;
				plan.UsesJumpDropImmunity = true;
				plan.ReachableWithinRecoverableBudget = true;
				plan.Score = 2.6f - probe.DropHeight * 0.03f;
				return true;
			}
			return false;
		}

		private void LockCurrentClimbPlan(PathPlan plan)
		{
			_lockedClimbPlan = ClonePlan(plan);
			_hasLockedClimbPlan = true;
		}

		private void ClearLockedClimbPlan()
		{
			_lockedClimbPlan = new PathPlan();
			_hasLockedClimbPlan = false;
		}

		private PathPlan GetActiveClimbPlan()
		{
			if (_hasLockedClimbPlan)
			{
				return _lockedClimbPlan;
			}
			if (_hasActiveSegment)
			{
				return _activeSegment;
			}
			return _plan;
		}

		private float GetGoalVerticalDistance()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return 999f;
			}
			return Mathf.Abs(GetGoalCenter().y - _character.Center.y);
		}

		private bool HasArrivedAtGoal()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return false;
			}
			Vector3 val = _character.Center;
			if (TryFindGround(_character.Center, out var hit))
			{
				val = ((RaycastHit)(ref hit)).point;
			}
			if (_rawGoalIsStandable)
			{
				float num = HelperFunctions.FlatDistance(val, _goalPoint);
				float num2 = Mathf.Abs(val.y - _goalPoint.y);
				return num <= 0.3f && num2 <= 0.3f;
			}
			if (_hasResolvedGoalPoint)
			{
				float num3 = HelperFunctions.FlatDistance(val, _resolvedGoalPoint);
				float num4 = Mathf.Abs(val.y - _resolvedGoalPoint.y);
				if (num3 <= 1.35f && num4 <= 2.25f)
				{
					return true;
				}
			}
			return false;
		}

		private float GetStamina01()
		{
			return Mathf.Clamp01(_character.GetTotalStamina());
		}

		private float GetRecoverableStaminaCeiling()
		{
			return Mathf.Clamp(_character.GetMaxStamina() + _character.data.extraStamina, 0.05f, 1f);
		}

		private float EstimateGroundChaseCost(float distance)
		{
			return Mathf.Clamp(0.03f + distance * 0.01f, 0.03f, 0.25f);
		}

		private float GetClimbStartThreshold(PathPlan plan)
		{
			if (plan.EstimatedClimbHeight <= 1.2f)
			{
				return 0.4f;
			}
			if (plan.IsTallWall)
			{
				return 0.92f;
			}
			return 0.85f;
		}

		private bool IsClimbPlan(PathPlan plan)
		{
			return plan.Action == PathActionType.Climb || plan.Action == PathActionType.JumpGrab;
		}

		private bool HasEnoughStaminaToStartClimb(PathPlan plan)
		{
			if (!IsClimbPlan(plan))
			{
				return true;
			}
			if (plan.Action == PathActionType.JumpGrab)
			{
				return GetStamina01() >= 0.92f;
			}
			return GetStamina01() >= GetClimbStartThreshold(plan);
		}

		private bool HasEnoughStaminaToResumeClimb(PathPlan plan)
		{
			if (!IsClimbPlan(plan))
			{
				return true;
			}
			return GetStamina01() >= GetClimbStartThreshold(plan) + 0.02f;
		}

		private bool TryBuildJumpGrabPlanFrom(Vector3 startPos, Vector3 toTargetDir, bool targetAbove, out PathPlan plan)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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_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_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: 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_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: 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_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			plan = new PathPlan();
			if (!HasActiveGoal())
			{
				return false;
			}
			Vector3 goalCenter = GetGoalCenter();
			float num = HelperFunctions.FlatDistance(startPos, goalCenter);
			float num2 = goalCenter.y - startPos.y;
			if (num2 < 0.45f && num < 2.2f)
			{
				return false;
			}
			float[] array = new float[11]
			{
				0f, 15f, -15f, 30f, -30f, 45f, -45f, 60f, -60f, 90f,
				-90f
			};
			float[] array2 = new float[5] { 0.55f, 0.85f, 1.2f, 1.6f, 2f };
			float[] array3 = new float[7] { 1.25f, 1.65f, 2.2f, 2.8f, 3.4f, 4f, 4.6f };
			bool flag = false;
			float num3 = float.NegativeInfinity;
			PathPlan pathPlan = new PathPlan();
			RaycastHit val2 = default(RaycastHit);
			RaycastHit val5 = default(RaycastHit);
			for (int i = 0; i < array.Length; i++)
			{
				Vector3 val = Quaternion.AngleAxis(array[i], Vector3.up) * toTargetDir;
				foreach (float num4 in array2)
				{
					Vector3 point = startPos + val * num4;
					if (!TryFindGround(point, out var hit))
					{
						continue;
					}
					float num5 = Mathf.Abs(((RaycastHit)(ref hit)).point.y - startPos.y);
					if (num5 > 1.15f)
					{
						continue;
					}
					foreach (float num6 in array3)
					{
						if (num6 < num4 + 0.25f || !Physics.SphereCast(startPos + Vector3.up * 1.15f, 0.2f, val, ref val2, num6, TerrainMask, (QueryTriggerInteraction)1))
						{
							continue;
						}
						Vector3 val3 = startPos + val * num6;
						Vector3 val4 = val3 + Vector3.up * 5.8f;
						if (!Physics.Raycast(val4, Vector3.down, ref val5, 6.8f, TerrainMask, (QueryTriggerInteraction)1))
						{
							continue;
						}
						float num7 = ((RaycastHit)(ref val5)).point.y - startPos.y;
						if (num7 < 0.75f || num7 > 4.6f || Vector3.Angle(((RaycastHit)(ref val5)).normal, Vector3.up) > 60f)
						{
							continue;
						}
						Vector3 point2 = startPos + val * Mathf.Lerp(num4, num6, 0.35f);
						Vector3 point3 = startPos + val * Mathf.Lerp(num4, num6, 0.6f);
						bool flag2 = false;
						if (!TryFindGround(point2, out var hit2))
						{
							flag2 = true;
						}
						else
						{
							float num8 = startPos.y - ((RaycastHit)(ref hit2)).point.y;
							if (num8 > 10f)
							{
								flag2 = true;
							}
						}
						if (!flag2)
						{
							if (!TryFindGround(point3, out var hit3))
							{
								flag2 = true;
							}
							else
							{
								float num9 = startPos.y - ((RaycastHit)(ref hit3)).point.y;
								if (num9 > 10f)
								{
									flag2 = true;
								}
							}
						}
						float num10 = HelperFunctions.FlatDistance(((RaycastHit)(ref val5)).point, goalCenter);
						float num11 = HelperFunctions.FlatDistance(startPos, goalCenter) - num10;
						float num12 = Mathf.Abs(((RaycastHit)(ref val5)).point.y - goalCenter.y);
						bool flag3 = num10 <= 1.45f && num12 <= 1.9f;
						if ((flag3 || !(num11 < 0.55f)) && (flag2 || targetAbove || flag3))
						{
							PathPlan obj = new PathPlan
							{
								Action = PathActionType.JumpGrab,
								Anchor = ((RaycastHit)(ref hit)).point,
								Goal = goalCenter + Vector3.up * 0.15f,
								JumpGrabAimPoint = ((RaycastHit)(ref val2)).point + Vector3.up * 0.25f,
								JumpGrabHorizontalDistance = num6,
								TargetAbove = true,
								EstimatedClimbHeight = num7,
								IsTallWall = (num7 >= 2.15f),
								RequiredStamina = EstimateRequiredClimbStamina(num7, targetAbove: true, num7 >= 2.15f),
								ReachableWithinRecoverableBudget = true,
								NeedsJumpStart = true,
								ClimbTopPoint = ((RaycastHit)(ref val5)).point
							};
							Vector3 normal = ((RaycastHit)(ref val2)).normal;
							Vector3 climbSurfaceNormal;
							if (!(((Vector3)(ref normal)).sqrMagnitude > 0.01f))
							{
								climbSurfaceNormal = -val;
							}
							else
							{
								normal = ((RaycastHit)(ref val2)).normal;
								climbSurfaceNormal = ((Vector3)(ref normal)).normalized;
							}
							obj.ClimbSurfaceNormal = climbSurfaceNormal;
							PathPlan pathPlan2 = obj;
							float num13 = (pathPlan2.Score = num11 * 2.4f + (flag3 ? 3.2f : 0f) + (flag2 ? 1.2f : 0f) - Mathf.Abs(array[i]) * 0.025f - num6 * 0.06f - GetBlockedPenalty(((RaycastHit)(ref hit)).point) - GetFailedSegmentPenalty(pathPlan2));
							if (!flag || num13 > num3)
							{
								flag = true;
								num3 = num13;
								pathPlan = pathPlan2;
							}
						}
					}
				}
			}
			if (flag)
			{
				plan = pathPlan;
				return true;
			}
			return false;
		}

		private bool IsNearClimbAnchor(PathPlan plan)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!IsClimbPlan(plan))
			{
				return false;
			}
			return Vector3.Distance(_character.Center, plan.Anchor) <= 1.35f;
		}

		public void Tick()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Invalid comparison between Unknown and I4
			if (!_initialized || (Object)(object)_zombie == (Object)null || (Object)(object)_character == (Object)null || (Object)(object)_character.data == (Object)null || (Object)(object)_view == (Object)null)
			{
				return;
			}
			UpdateInteractionState();
			if (!_view.IsMine)
			{
				TickRemoteVisualOnly();
				return;
			}
			KeepZombiePersistent();
			if (_brainState == ZombieBrainState.Dead || (int)_zombie.currentState == 6)
			{
				_brainState = ZombieBrainState.Dead;
				_zombie.currentState = (State)6;
				return;
			}
			if (suppressZombieAI)
			{
				TickSuppressedByInteraction();
				SyncVisualState();
				return;
			}
			ResetInput();
			RefreshTargetIfNeeded();
			RefreshResolvedGoalIfNeeded();
			ValidateTarget();
			DecayBlockedMemory();
			UpdateStuckDetection();
			UpdateClimbFailureDetection();
			if (!HasActiveGoal())
			{
				_brainState = ZombieBrainState.Idle;
			}
			else if (!IsFollowingRoute() && HasArrivedAtGoal())
			{
				_brainState = ZombieBrainState.Idle;
			}
			switch (_brainState)
			{
			case ZombieBrainState.Idle:
				TickIdle();
				break;
			case ZombieBrainState.Chase:
				TickChase();
				break;
			case ZombieBrainState.PrepareTallClimb:
				TickPrepareTallClimb();
				break;
			case ZombieBrainState.Reposition:
				TickReposition();
				break;
			case ZombieBrainState.Lunge:
				TickLunge();
				break;
			case ZombieBrainState.LungeRecovery:
				TickLungeRecovery();
				break;
			case ZombieBrainState.Dead:
				_zombie.currentState = (State)6;
				break;
			}
			LogBrainStateIfChanged();
			SyncVisualState();
		}

		private void TickRemoteVisualOnly()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			UpdateInteractionState();
			if (suppressZombieAI)
			{
				_zombie.currentState = (State)2;
				_character.data.passedOut = false;
			}
			if ((int)_zombie.currentState == 6 || (int)_zombie.currentState == 0)
			{
				_character.data.passedOut = true;
			}
			_zombie.SetBiteColliderProxy((int)_zombie.currentState == 4);
			_zombie.UpdateMouthProxy();
		}

		private void KeepZombiePersistent()
		{
			_zombie.isNPCZombie = false;
			_zombie.spawner = null;
			_zombie.lifetime = 999999f;
			if ((Object)(object)ZombieManager.Instance != (Object)null)
			{
				ZombieManager.Instance.DeRegisterZombie(_zombie);
			}
			if ((Object)(object)_character != (Object)null)
			{
				_character.isZombie = true;
				_character.isBot = false;
				_character.data.dead = false;
				_character.data.passedOut = false;
				_character.data.fullyPassedOut = false;
			}
		}

		private void TickIdle()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			_zombie.currentState = (State)2;
			_character.data.passedOut = false;
			SetSprint(sprinting: false);
			if (HasActiveGoal())
			{
				LookAt(GetCurrentDrivePoint());
				_brainState = ZombieBrainState.Chase;
				_timeInChase = 0f;
			}
		}

		private void TickChase()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: 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_02af: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				ClearLockedClimbPlan();
				_segmentQueue.Clear();
				ClearActiveSegment();
				_brainState = ZombieBrainState.Idle;
				_zombie.currentState = (State)2;
				return;
			}
			_zombie.currentState = (State)3;
			_character.data.passedOut = false;
			_timeInChase += Time.deltaTime;
			if (CanSeeGoal())
			{
				_lastSeenTargetTime = Time.time;
			}
			if (!IsFollowingRoute() && HasArrivedAtGoal())
			{
				_zombie.currentState = (State)2;
				_character.data.passedOut = false;
				SetSprint(sprinting: false);
				_character.input.movementInput = Vector2.zero;
				if (_resolvedGoalIsStandable && _character.data.isClimbing)
				{
					StopClimb();
				}
				ClearLockedClimbPlan();
				_brainState = ZombieBrainState.Idle;
				return;
			}
			if (_character.data.isClimbing)
			{
				if (!_hasLockedClimbPlan)
				{
					if (_hasActiveSegment && _activeSegment.Action == PathActionType.Climb)
					{
						LockCurrentClimbPlan(_activeSegment);
					}
					else if (_plan.Action == PathActionType.Climb)
					{
						LockCurrentClimbPlan(_plan);
					}
				}
				TickActiveClimb();
				return;
			}
			if (!_hasActiveSegment && _segmentQueue.Count == 0)
			{
				ReplanRoute();
			}
			AdvanceSegmentIfNeeded();
			if (!_hasActiveSegment && _segmentQueue.Count == 0)
			{
				ReplanRoute();
			}
			if (_hasActiveSegment)
			{
				ExecuteActiveSegment();
				return;
			}
			ClearLockedClimbPlan();
			PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center));
			if (IsClimbPlan(pathPlan) && !HasEnoughStaminaToStartClimb(pathPlan))
			{
				if (!IsNearClimbAnchor(pathPlan))
				{
					LookAt(pathPlan.Anchor);
					WalkTowards(pathPlan.Anchor, 0.8f, tryClimb: false, tryJump: false, sprintRequested: false);
				}
				else
				{
					EnterPrepareTallClimb();
				}
			}
			else if (_stuckCount >= 2 || _failedClimbCount >= 3)
			{
				RegisterBlockedPoint(_character.Center, 3.2f);
				EnterReposition();
			}
			else
			{
				ExecuteGroundPlan(pathPlan);
			}
		}

		private void TickPrepareTallClimb()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			_zombie.currentState = (State)2;
			_character.data.passedOut = false;
			SetSprint(sprinting: false);
			if (!HasActiveGoal())
			{
				_brainState = ZombieBrainState.Idle;
				return;
			}
			PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center));
			if (!IsClimbPlan(pathPlan))
			{
				_brainState = ZombieBrainState.Chase;
				return;
			}
			float num = Vector3.Distance(_character.Center, pathPlan.Anchor);
			bool flag = HasEnoughStaminaToResumeClimb(pathPlan);
			bool flag2 = num <= 1.35f;
			LookAt(flag2 ? pathPlan.Goal : pathPlan.Anchor);
			if (!flag2)
			{
				WalkTowards(pathPlan.Anchor, 0.7f, tryClimb: false, tryJump: false, sprintRequested: false);
			}
			else if (!flag)
			{
				_character.input.movementInput = Vector2.zero;
				SetSprint(sprinting: false);
			}
			else
			{
				WalkTowards(pathPlan.Goal, 0.95f, tryClimb: true, tryJump: false, sprintRequested: false);
				TryForceJumpGrab(pathPlan, closeToAnchor: true);
				_brainState = ZombieBrainState.Chase;
			}
		}

		private void TickReposition()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_0126: 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)
			_zombie.currentState = (State)2;
			_character.data.passedOut = false;
			if (!HasActiveGoal())
			{
				_brainState = ZombieBrainState.Idle;
				return;
			}
			PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center));
			bool flag = Time.time < _repositionUntil;
			if (pathPlan.Action == PathActionType.Detour)
			{
				LookAt(pathPlan.Goal);
				WalkTowards(pathPlan.Goal, 1f, tryClimb: false, tryJump: false, sprintRequested: false);
				TryTravelHop();
				if (!flag && Vector3.Distance(_character.Center, pathPlan.Goal) < 1.2f)
				{
					_stuckCount = 0;
					_failedClimbCount = 0;
					_brainState = ZombieBrainState.Chase;
				}
			}
			else if (!flag && (pathPlan.Action == PathActionType.Direct || pathPlan.Action == PathActionType.Climb || pathPlan.Action == PathActionType.GapJump || pathPlan.Action == PathActionType.DropDown))
			{
				_stuckCount = 0;
				_failedClimbCount = 0;
				_brainState = ZombieBrainState.Chase;
			}
			else
			{
				LookAt(GetCurrentMoveTarget());
				WalkTowards(GetGoalLookPoint(), 0.7f, tryClimb: false, tryJump: false, sprintRequested: false);
			}
		}

		private void TickLunge()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006e: Unknown result type (might be due to invalid IL or missing references)
			_zombie.currentState = (State)4;
			_character.data.passedOut = false;
			_timeInLunge += Time.deltaTime;
			if (HasActiveGoal())
			{
				Vector3 targetPos = _character.Center + (GetGoalLookPoint() - _character.Center) * 100f;
				WalkTowards(targetPos, 1.2f, tryClimb: false, tryJump: false, sprintRequested: true);
			}
			if (_timeInLunge >= _zombie.lungeTime || _character.OutOfStamina())
			{
				_timeInLunge = 0f;
				_brainState = ZombieBrainState.LungeRecovery;
				_zombie.currentState = (State)5;
				_character.Fall(3f, 0f);
				ForcePushState();
			}
		}

		private void TickLungeRecovery()
		{
			_zombie.currentState = (State)5;
			_character.data.passedOut = false;
			if (!(_character.data.fallSeconds > 0f) && !_character.data.passedOut && !_character.data.fullyPassedOut)
			{
				_timeInLunge += Time.deltaTime;
				if (_timeInLunge >= _zombie.lungeRecoveryTime)
				{
					_timeInLunge = 0f;
					_brainState = ZombieBrainState.Chase;
				}
			}
		}

		private void TickActiveClimb()
		{
			//IL_0160: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_01c8: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: 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)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				StopClimb();
				ClearLockedClimbPlan();
				_brainState = ZombieBrainState.Idle;
				return;
			}
			PathPlan activeClimbPlan = GetActiveClimbPlan();
			if (_climbTimer > 0.45f && !CanContinueClimb(activeClimbPlan))
			{
				StopClimb();
				if (activeClimbPlan.Action == PathActionType.Climb || activeClimbPlan.Action == PathActionType.JumpGrab)
				{
					EnterPrepareTallClimb();
					return;
				}
				RegisterBlockedPoint(_character.Center, 2.6f);
				EnterReposition();
				return;
			}
			if (_resolvedGoalIsStandable)
			{
				float num = HelperFunctions.FlatDistance(_character.Center, _resolvedGoalPoint);
				float num2 = _resolvedGoalPoint.y - _character.Center.y;
				if (_climbTimer > 0.8f && num <= 1.4f && num2 <= 0.9f)
				{
					StopClimb();
					ClearLockedClimbPlan();
					LookAt(_resolvedGoalPoint);
					_character.input.movementInput = new Vector2(0f, 1f);
					SetSprint(sprinting: false);
					return;
				}
			}
			Vector3 val = ((activeClimbPlan.ClimbTopPoint != Vector3.zero) ? activeClimbPlan.ClimbTopPoint : GetGoalLookPoint());
			Vector2 val2 = ComputeStrategicClimbInput(val, activeClimbPlan);
			float num3 = Mathf.Max(activeClimbPlan.EstimatedClimbHeight, 0.1f);
			float num4 = Mathf.Clamp01((_character.Center.y - _climbStartHeight) / num3);
			float stamina = GetStamina01();
			bool flag = activeClimbPlan.ClimbTopPoint != Vector3.zero && Vector3.Distance(_character.Center, activeClimbPlan.ClimbTopPoint) < 1.25f;
			bool flag2 = stamina <= 0.05f && stamina >= 0.01f && num4 >= 0.35f;
			bool flag3 = flag || num4 >= 0.55f;
			bool flag4 = (activeClimbPlan.Action == PathActionType.Climb || activeClimbPlan.Action == PathActionType.JumpGrab) && (flag3 || flag2) && stamina >= 0.01f;
			LookAt(val);
			SetSprint(sprinting: false);
			_character.input.movementInput = val2;
			if (flag4)
			{
				_character.input.sprintIsPressed = true;
				_character.input.movementInput = new Vector2(Mathf.Clamp(val2.x * 1.15f, -1f, 1f), Mathf.Clamp(val2.y * 1.12f, 0.82f, 1f));
			}
			if (GetGoalCenter().y < _character.Center.y)
			{
				RaycastHit val3 = HelperFunctions.LineCheck(_character.Center, GetGoalCenter(), (LayerType)1, 0f, (QueryTriggerInteraction)1);
				bool flag5 = (Object)(object)((RaycastHit)(ref val3)).transform == (Object)null;
				float num5 = HelperFunctions.FlatDistance(_character.Center, GetGoalCenter());
				bool flag6 = _climbTimer > 0.8f;
				if (flag5 && flag6 && num5 < 1.8f && GetGoalCenter().y - _character.Center.y < -1f)
				{
					StopClimb();
					ClearLockedClimbPlan();
					SetSprint(sprinting: false);
				}
			}
		}

		private bool TryBuildObstacleBypassPlanFrom(Vector3 startPos, Vector3 toTargetDir, float currentFlatDist, bool targetAbove, out PathPlan plan)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			plan = new PathPlan();
			if (!HasActiveGoal())
			{
				return false;
			}
			if (!TryProbeRouteFrom(startPos, toTargetDir, 2.2f, out var probe))
			{
				return false;
			}
			if ((!probe.ObstacleAhead || probe.ClimbableAhead) && !probe.UnsafeDropAhead)
			{
				return false;
			}
			bool flag = false;
			float num = float.NegativeInfinity;
			PathPlan pathPlan = new PathPlan();
			float[] array = new float[9] { 0f, 18f, -18f, 35f, -35f, 55f, -55f, 75f, -75f };
			foreach (float num2 in array)
			{
				Vector3 val = Quaternion.AngleAxis(num2, Vector3.up) * toTargetDir;
				if (!TryProbeRouteFrom(startPos, val, 2.2f, out var probe2))
				{
					continue;
				}
				float blockedPenalty = GetBlockedPenalty(startPos + val * 2.2f);
				float num3 = Mathf.Abs(num2) * 0.018f;
				if (probe2.GapJumpable)
				{
					float num4 = HelperFunctions.FlatDistance(probe2.GapLandingPoint, GetGoalCenter());
					float num5 = currentFlatDist - num4;
					if (num5 >= 0.55f)
					{
						PathPlan pathPlan2 = new PathPlan
						{
							Action = PathActionType.GapJump,
							Goal = probe2.GapLandingPoint,
							Anchor = startPos + val * Mathf.Clamp(Mathf.Max(0.9f, probe2.ObstacleAhead ? (probe2.ObstacleDistance - 0.2f) : 1f), 0.9f, 1.45f),
							TargetAbove = targetAbove,
							RequiredStamina = Mathf.Clamp(0.18f + probe2.GapLandingDrop * 0.04f, 0.18f, 0.5f),
							ReachableWithinRecoverableBudget = true
						};
						float num6 = num5 * 2.1f + 1.15f - num3 - blockedPenalty - GetFailedSegmentPenalty(pathPlan2);
						if (Mathf.Abs(num2) <= 18f)
						{
							num6 += 0.25f;
						}
						pathPlan2.Score = num6;
						if (!flag || num6 > num)
						{
							flag = true;
							num = num6;
							pathPlan = pathPlan2;
						}
					}
				}
				Vector3 point = startPos + val * 3f;
				if (!TryFindGround(point, out var hit))
				{
					continue;
				}
				float num7 = startPos.y - ((RaycastHit)(ref hit)).point.y;
				if (num7 <= 10f)
				{
					float num8 = HelperFunctions.FlatDistance(((RaycastHit)(ref hit)).point, GetGoalCenter());
					float num9 = currentFlatDist - num8;
					RaycastHit val2 = HelperFunctions.LineCheck(startPos + Vector3.up * 0.15f, ((RaycastHit)(ref hit)).point + Vector3.up * 0.15f, (LayerType)1, 0f, (QueryTriggerInteraction)1);
					bool flag2 = (Object)(object)((RaycastHit)(ref val2)).transform != (Object)null;
					float num10 = num9 + 0.75f - num3 - blockedPenalty - (flag2 ? 0.65f : 0f);
					PathPlan pathPlan3 = new PathPlan
					{
						Action = PathActionType.Detour,
						Goal = ((RaycastHit)(ref hit)).point,
						Anchor = ((RaycastHit)(ref hit)).point,
						TargetAbove = targetAbove,
						RequiredStamina = EstimateGroundChaseCost(Vector3.Distance(startPos, ((RaycastHit)(ref hit)).point)),
						ReachableWithinRecoverableBudget = true
					};
					num10 = (pathPlan3.Score = num10 - GetFailedSegmentPenalty(pathPlan3));
					if (!flag || num10 > num)
					{
						flag = true;
						num = num10;
						pathPlan = pathPlan3;
					}
				}
			}
			if (flag)
			{
				plan = pathPlan;
				return true;
			}
			return false;
		}

		private void ExecuteGroundPlan(PathPlan plan)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			switch (plan.Action)
			{
			case PathActionType.Direct:
			{
				LookAt(plan.Goal);
				float num = (HasActiveGoal() ? HelperFunctions.FlatDistance(_character.Center, GetGoalCenter()) : 999f);
				float num2 = (HasActiveGoal() ? Mathf.Abs(GetGoalCenter().y - _character.Center.y) : 999f);
				bool flag = num <= 1.65f && num2 <= 1.15f;
				bool sprintRequested = ((!flag) ? ShouldAggressiveSprint() : (num > 0.9f && GetStamina01() > 0.05f));
				bool tryJump = !flag || ShouldHopSmallObstacleTowards(plan.Goal);
				WalkTowards(plan.Goal, flag ? 0.85f : 1f, tryClimb: true, tryJump, sprintRequested);
				if (!flag)
				{
					TryTravelHop();
				}
				break;
			}
			case PathActionType.Detour:
			{
				LookAt(plan.Goal);
				bool sprintRequested2 = Vector3.Distance(_character.Center, plan.Goal) > 4f || ShouldAggressiveSprint();
				bool tryJump2 = ShouldHopSmallObstacleTowards(plan.Goal);
				WalkTowards(plan.Goal, 1f, tryClimb: false, tryJump2, sprintRequested2);
				TryTravelHop();
				break;
			}
			case PathActionType.Climb:
			{
				float num6 = Vector3.Distance(_character.Center, plan.Anchor);
				bool flag3 = num6 <= 1.35f;
				Vector3 val2 = (flag3 ? plan.Goal : plan.Anchor);
				if (!HasEnoughStaminaToStartClimb(plan))
				{
					LookAt(flag3 ? plan.Anchor : val2);
					if (!flag3)
					{
						WalkTowards(plan.Anchor, 0.75f, tryClimb: false, tryJump: false, sprintRequested: false);
						break;
					}
					_character.input.movementInput = Vector2.zero;
					SetSprint(sprinting: false);
				}
				else
				{
					LookAt(val2);
					bool flag4 = !flag3 && num6 > 1.8f && ShouldAggressiveSprint();
					WalkTowards(val2, flag3 ? 0.95f : 1f, tryClimb: true, tryJump: false, flag4 && !flag3);
					TryForceJumpGrab(plan, flag3);
				}
				break;
			}
			case PathActionType.JumpGrab:
			{
				float num5 = Vector3.Distance(_character.Center, plan.Anchor);
				bool flag2 = num5 <= 1.15f;
				Vector3 lookAtPos = ((plan.JumpGrabAimPoint != Vector3.zero) ? plan.JumpGrabAimPoint : plan.Goal);
				if (!flag2)
				{
					LookAt(plan.Anchor);
					bool sprintRequested4 = num5 > 2f && ShouldAggressiveSprint();
					bool tryClimb = num5 <= 1.85f;
					WalkTowards(plan.Anchor, 1f, tryClimb, ShouldHopSmallObstacleTowards(plan.Anchor), sprintRequested4);
					break;
				}
				if (!HasEnoughStaminaToStartClimb(plan))
				{
					LookAt(lookAtPos);
					_character.input.movementInput = Vector2.zero;
					SetSprint(sprinting: false);
					break;
				}
				LookAt(lookAtPos);
				_character.input.movementInput = new Vector2(0f, 1f);
				SetSprint(sprinting: false);
				_character.refs.climbing.TryClimb(1.6f);
				if (_character.data.isGrounded && Time.time - _lastAutoJumpTime >= 0.2f)
				{
					_character.input.jumpWasPressed = true;
					_lastAutoJumpTime = Time.time;
				}
				break;
			}
			case PathActionType.GapJump:
			{
				LookAt(plan.Goal);
				float num3 = Vector3.Distance(_character.Center, plan.Anchor);
				if (num3 > 1.15f)
				{
					WalkTowards(plan.Anchor, 1f, tryClimb: false, tryJump: false, sprintRequested: true);
					break;
				}
				SetSprint(sprinting: true);
				_character.input.movementInput = new Vector2(0f, 1f);
				LookAt(plan.Goal);
				if (_character.data.isGrounded && GetStamina01() >= plan.RequiredStamina)
				{
					_character.input.jumpWasPressed = true;
					_lastAutoJumpTime = Time.time;
				}
				break;
			}
			case PathActionType.DropDown:
			{
				LookAt(plan.Goal);
				float num4 = Vector3.Distance(_character.Center, plan.Anchor);
				if (num4 > 1.1f)
				{
					bool sprintRequested3 = ShouldAggressiveSprint();
					WalkTowards(plan.Anchor, 1f, tryClimb: false, tryJump: false, sprintRequested3);
				}
				else if (plan.UsesJumpDropImmunity)
				{
					SetSprint(sprinting: true);
					_character.input.jumpWasPressed = true;
					_lastAutoJumpTime = Time.time;
				}
				else
				{
					SetSprint(sprinting: false);
					_character.input.movementInput = new Vector2(0f, 1f);
				}
				break;
			}
			default:
			{
				Vector3 val = (HasActiveGoal() ? GetGoalLookPoint() : _character.Head);
				LookAt(val);
				WalkTowards(val, 0.7f, tryClimb: false, tryJump: false, sprintRequested: false);
				break;
			}
			}
		}

		private bool ShouldAggressiveSprint()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return false;
			}
			if (!_character.CheckSprint())
			{
				return false;
			}
			float num = Vector3.Distance(_character.Center, GetGoalCenter());
			if (_timeInChase > _zombie.chaseTimeBeforeSprint && num > 3f)
			{
				return true;
			}
			if (Time.time - _lastS