Decompiled source of PingDrivenRobots v1.3.3

PingDrivenRobots.dll

Decompiled a week 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;
using Zorro.Settings;

[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("PingDrivenRobots")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.3.0")]
[assembly: AssemblyInformationalVersion("1.3.3")]
[assembly: AssemblyProduct("PingDrivenRobots")]
[assembly: AssemblyTitle("PingDrivenRobots")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.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 PingDrivenRobots
{
	internal sealed class NetworkRobotAgent : MonoBehaviour
	{
		internal sealed class FailedSegmentMemory
		{
			public PathActionType Action = PathActionType.None;

			public Vector3 Position = Vector3.zero;

			public Vector3 Direction = Vector3.zero;

			public float Until;
		}

		private sealed class SpatialRouteNode
		{
			public Vector3 Position;

			public readonly List<PathPlan> Segments = new List<PathPlan>();

			public float Cost;

			public float Score;

			public float DistanceToGoal;

			public float RemainingStamina;

			public int Depth;
		}

		private readonly struct SpatialRouteStateKey : IEquatable<SpatialRouteStateKey>
		{
			private readonly int _x;

			private readonly int _y;

			private readonly int _z;

			private readonly int _depth;

			private readonly int _stamina;

			public SpatialRouteStateKey(int x, int y, int z, int depth, int stamina)
			{
				_x = x;
				_y = y;
				_z = z;
				_depth = depth;
				_stamina = stamina;
			}

			public bool Equals(SpatialRouteStateKey other)
			{
				return _x == other._x && _y == other._y && _z == other._z && _depth == other._depth && _stamina == other._stamina;
			}

			public override bool Equals(object? obj)
			{
				return obj is SpatialRouteStateKey other && Equals(other);
			}

			public override int GetHashCode()
			{
				int x = _x;
				x = (x * 397) ^ _y;
				x = (x * 397) ^ _z;
				x = (x * 397) ^ _depth;
				return (x * 397) ^ _stamina;
			}
		}

		private const float ManualBiteAcquireRadius = 10f;

		private const float ManualBiteMinStamina = 0.05f;

		private const float CarryAssistAcquireRadius = 80f;

		private const float CarryAssistStartFlatDistance = 1.75f;

		private const float CarryAssistStartVerticalDistance = 2.25f;

		private const float CarryAssistRetargetInterval = 0.75f;

		private Character? _manualBiteTarget;

		private bool _manualBiteActive;

		private Character? _vanillaBiteTarget;

		private bool _vanillaBiteControlActive;

		private bool _carryAssistEnabled;

		private Character? _carryTarget;

		private float _nextCarryRetargetTime;

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

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

		private static readonly Dictionary<int, NetworkRobotAgent> AgentByZombieInstanceId = new Dictionary<int, NetworkRobotAgent>();

		private static readonly Dictionary<int, float> MissingAgentRetryByZombieInstanceId = new Dictionary<int, float>();

		private const float MissingZombieAgentRetrySeconds = 0.25f;

		private int _spawnOwnerActorNumber;

		private string _spawnOwnerUserId = string.Empty;

		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.16f;

		private const float HeavyActionLowStaminaThreshold = 0.08f;

		private const float SprintMinStamina = 0.12f;

		private const float FlatTravelHopVerticalTolerance = 0.45f;

		private const float FlatTravelHopMinDistance = 2f;

		private const float GoalExactStandFlatRadius = 1.05f;

		private const float GoalExactStandVerticalTolerance = 1.2f;

		private const float GoalStableStandSeconds = 1f;

		private const float GoalSettleFlatRadius = 1.55f;

		private const float GoalSettleVerticalTolerance = 1.25f;

		private const float GoalParkHysteresisFlat = 2.45f;

		private const float GoalParkHysteresisVertical = 2.25f;

		private const float GoalArrivalSettleFlatRadius = 2.05f;

		private const float GoalArrivalSettleVerticalTolerance = 1.6f;

		private const float RoughWalkableSlopeAngle = 68f;

		private const float RoughClimbTopSlopeAngle = 72f;

		private const float RoughSupportHeightTolerance = 1.05f;

		private const float ObstacleBypassJumpMinHeight = 0.28f;

		private const float ObstacleBypassJumpMaxHeight = 1.55f;

		private const float ObstacleBypassJumpMaxLandingDelta = 0.9f;

		private const float TerrainFallbackMaxRise = 2.15f;

		private const float TerrainFallbackMaxDrop = 6.5f;

		private const float TerrainFallbackMinProgress = -0.25f;

		public bool canBeCarriedAsRobot;

		public bool suppressRobotAI;

		public float zombieInteractionLock;

		public float lastRobotFedTime;

		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.42f;

		private const int MaxPlannedSegments = 3;

		private const int GuidePlannerMaxDepth = 2;

		private const int GuidePlannerBeamWidth = 3;

		private const int GuidePlannerMaxCandidatesPerNode = 10;

		private const float GuidePlannerMinUsefulProgress = -1.75f;

		private const float GuidePlannerCloseEnoughFlat = 2.15f;

		private const float GuidePlannerCloseEnoughVertical = 2.35f;

		private const float GuidePlannerRepeatPenaltyDistance = 2.4f;

		private const float GuidePlannerMemoryLifetime = 5.5f;

		private const float GuidePlannerCacheLifetime = 1.1f;

		private const int GuidePlannerMaxCandidateCacheEntries = 128;

		private const int GuidePlannerMaxPathCacheEntries = 32;

		private const float GuidePlannerPositionCell = 1.4f;

		private const float GuidePlannerGoalCell = 1.25f;

		private const float GuidePlannerDpCell = 1.75f;

		private const float GuidePlannerDpScoreEpsilon = 0.08f;

		private const float VerticalDropFlatEpsilon = 0.35f;

		private const float LowerGoalThreshold = -1.25f;

		private const float DropSearchMaxAnchorDistance = 7f;

		private const float DropEdgeArrivalDistance = 1.15f;

		private const float DropLandingGoalWeight = 1.45f;

		private const float ClimbProbeMinStamina = 0.1f;

		private const float ActiveClimbExhaustedStaminaThreshold = 0.018f;

		private const float ClimbContinueMinStamina = 0.018f;

		private const float ClimbNearTopContinueMinStamina = 0.018f;

		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.18f;

		private MushroomZombie _zombie = null;

		private Character _character = null;

		private PhotonView _view = null;

		private RobotBrainState _brainState = RobotBrainState.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 Vector3 _lastResolvedRawGoal;

		private bool _hasLastResolvedRawGoal;

		private float _goalStableTimer;

		private bool _goalParked;

		private Vector3 _parkedGoalPoint;

		private int _goalInstructionSerial;

		private int _parkedGoalInstructionSerial;

		private int _lastAcceptedPingSequence;

		private bool _allowGoalParking;

		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 bool _activeClimbStartedAtRetryFullStamina;

		private bool _awaitingFullStaminaClimbRetry;

		private bool _fullStaminaClimbRetryConsumed;

		private Vector3 _fullStaminaClimbRetryAnchor;

		private int _fullStaminaClimbRetryGoalSerial;

		private float _lastAutoJumpTime;

		private PathPlan _plan = new PathPlan();

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

		private readonly List<RouteChoiceMemory> _recentRouteChoices = new List<RouteChoiceMemory>();

		private readonly Dictionary<RouteCandidateCacheKey, RouteCandidateCacheEntry> _guideCandidateCache = new Dictionary<RouteCandidateCacheKey, RouteCandidateCacheEntry>();

		private readonly Dictionary<RoutePathCacheKey, RoutePathCacheEntry> _guidePathCache = new Dictionary<RoutePathCacheKey, RoutePathCacheEntry>();

		private static readonly Dictionary<RoutePathCacheKey, RoutePathCacheEntry> SharedGuidePathCache = new Dictionary<RoutePathCacheKey, RoutePathCacheEntry>();

		private static readonly Dictionary<PhysicsProbeCacheKey, GroundProbeCacheEntry> SharedGroundProbeCache = new Dictionary<PhysicsProbeCacheKey, GroundProbeCacheEntry>();

		private static readonly Dictionary<PhysicsProbeCacheKey, LineProbeCacheEntry> SharedLineProbeCache = new Dictionary<PhysicsProbeCacheKey, LineProbeCacheEntry>();

		private static int SharedPlannerBudgetFrame = -1;

		private static int SharedPlannerBudgetUsed;

		private const int SharedMaxGuidedRoutePlansPerFrame = 1;

		private const int SharedGuidePlannerMaxPathCacheEntries = 128;

		private const int SharedMaxGroundProbeCacheEntries = 512;

		private const int SharedMaxLineProbeCacheEntries = 512;

		private const float SharedGuidePlannerPathCacheLifetime = 2.5f;

		private const float SharedPhysicsProbeCacheLifetime = 0.08f;

		private const float SharedPhysicsProbeCell = 0.55f;

		private bool _initialized;

		private float _nextPersistentRefreshTime;

		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.12f;

		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.18f;

		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 FullStaminaRetryReadyEpsilon = 0.02f;

		private const float FullStaminaRetrySameSiteDistance = 2.75f;

		private const float GoalStandSearchRadius = 1.2f;

		private const float GoalStandPreferRadius = 0.95f;

		private const float NonStandableGoalAccessSearchRadius = 5.2f;

		private const float NonStandableGoalAccessProbeHeight = 7f;

		private const float NonStandableGoalAccessProbeDepth = 13.5f;

		private const float ResolvedGoalRefreshInterval = 1.5f;

		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[] GuideSearchAngles = new float[7] { 0f, 25f, -25f, 55f, -55f, 90f, -90f };

		private static readonly float[] GuideSearchDistances = new float[2] { 2f, 4.2f };

		private static readonly float[] TerrainFallbackDistances = new float[5] { 1.4f, 2.4f, 3.8f, 5.6f, 7.5f };

		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 static readonly FieldInfo? ZombieTimeSpentChasingField = AccessTools.Field(typeof(MushroomZombie), "timeSpentChasing");

		private static readonly FieldInfo? ZombieCurrentTargetField = AccessTools.Field(typeof(MushroomZombie), "_currentTarget");

		private static readonly FieldInfo? ZombieTargetForcedUntilField = AccessTools.Field(typeof(MushroomZombie), "targetForcedUntil");

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

		private const int SpatialPlannerMaxDepth = 4;

		private const int SpatialPlannerBeamWidth = 8;

		private const int SpatialPlannerMaxCandidatesPerNode = 18;

		private const float SpatialPlannerCacheLifetime = 2.2f;

		private const float SpatialPlannerCell = 1.65f;

		private const float SpatialPlannerCloseFlat = 2.05f;

		private const float SpatialPlannerCloseVertical = 1.65f;

		private const float SpatialWalkStepMaxRise = 0.78f;

		private const float SpatialWalkStepMaxDrop = 1.05f;

		private const float SpatialRampTotalRiseLimit = 2.25f;

		private const float SpatialRampTotalDropLimit = 3.25f;

		private const float SpatialCandidateMaxRise = 5.25f;

		private const float SpatialCandidateMaxDrop = 9.5f;

		private const float SpatialMinUseful3DProgress = -1.25f;

		private static readonly float[] SpatialAngles = new float[12]
		{
			0f, 20f, -20f, 45f, -45f, 70f, -70f, 105f, -105f, 145f,
			-145f, 180f
		};

		private static readonly float[] SpatialDistances = new float[5] { 1.25f, 2.35f, 3.75f, 5.6f, 7.75f };

		private static readonly float[] SpatialVerticalProbeOffsets = new float[4] { 2.4f, 4.4f, 6.8f, 9.2f };

		public Character? Character => _character;

		public PhotonView? View => _view;

		public int SpawnOwnerActorNumber => _spawnOwnerActorNumber;

		public bool IsOwnedByLocalPlayer
		{
			get
			{
				if (!_initialized || (Object)(object)_view == (Object)null)
				{
					return false;
				}
				if (_view.IsMine)
				{
					return true;
				}
				return IsSpawnedByLocalPlayer;
			}
		}

		public bool IsSpawnedByLocalPlayer => PhotonNetwork.LocalPlayer != null && _spawnOwnerActorNumber > 0 && PhotonNetwork.LocalPlayer.ActorNumber == _spawnOwnerActorNumber;

		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_021e: 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_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: 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_030d: 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_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: 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_02e0: 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_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: 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_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: 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_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: 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 || !IsRoughClimbTopNormal(((RaycastHit)(ref val5)).normal))
						{
							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 = (EstimateRequiredClimbStamina(num7, targetAbove: true, num7 >= 2.15f) <= GetRecoverableStaminaCeiling()),
								NeedsJumpStart = true,
								ProjectedEndPoint = ((RaycastHit)(ref val5)).point,
								HasProjectedEndPoint = 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;
			}
			KeepRobotPersistent();
			if (_brainState == RobotBrainState.Dead || (int)_zombie.currentState == 6)
			{
				_brainState = RobotBrainState.Dead;
				_zombie.currentState = (State)6;
				return;
			}
			if (suppressRobotAI)
			{
				TickSuppressedByInteraction();
				SyncVisualState();
				return;
			}
			ResetInput();
			UpdateCommandStateBeforePlanning();
			if (!ShouldHoldCommandTarget())
			{
				RefreshTargetIfNeeded();
			}
			RefreshResolvedGoalIfNeeded();
			ValidateTarget();
			DecayBlockedMemory();
			UpdateStuckDetection();
			UpdateClimbFailureDetection();
			if (TryUpdateGoalParkingAndMaybeHold())
			{
				LogBrainStateIfChanged();
				SyncVisualState();
				return;
			}
			if (!HasActiveGoal())
			{
				_brainState = RobotBrainState.Idle;
			}
			else if (!IsFollowingRoute() && HasArrivedAtGoal())
			{
				_brainState = RobotBrainState.Idle;
			}
			switch (_brainState)
			{
			case RobotBrainState.Idle:
				TickIdle();
				break;
			case RobotBrainState.Parked:
				TickParkedAtGoal();
				break;
			case RobotBrainState.Chase:
				TickChase();
				break;
			case RobotBrainState.PrepareTallClimb:
				TickPrepareTallClimb();
				break;
			case RobotBrainState.Reposition:
				TickReposition();
				break;
			case RobotBrainState.Lunge:
				TickLunge();
				break;
			case RobotBrainState.LungeRecovery:
				TickLungeRecovery();
				break;
			case RobotBrainState.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 (suppressRobotAI)
			{
				_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 KeepRobotPersistent()
		{
			if (Time.time >= _nextPersistentRefreshTime)
			{
				_nextPersistentRefreshTime = Time.time + 1f;
				_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 = true;
				_character.data.dead = false;
				_character.data.passedOut = false;
				_character.data.fullyPassedOut = false;
			}
		}

		private void TickIdle()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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())
			{
				if (HasArrivedAtGoal())
				{
					_character.input.movementInput = Vector2.zero;
					LookAt(GetGoalLookPoint());
				}
				else
				{
					LookAt(GetCurrentDrivePoint());
					_brainState = RobotBrainState.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_0218: 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_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				ClearLockedClimbPlan();
				_segmentQueue.Clear();
				ClearActiveSegment();
				_brainState = RobotBrainState.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 = RobotBrainState.Idle;
				return;
			}
			if (_character.data.isClimbing)
			{
				if (!_hasLockedClimbPlan)
				{
					if (_hasActiveSegment && IsClimbPlan(_activeSegment))
					{
						LockCurrentClimbPlan(_activeSegment);
					}
					else if (IsClimbPlan(_plan))
					{
						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_00c6: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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 = RobotBrainState.Idle;
				return;
			}
			PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center));
			if (!IsClimbPlan(pathPlan))
			{
				_brainState = RobotBrainState.Chase;
				return;
			}
			float num = Vector3.Distance(_character.Center, pathPlan.Anchor);
			bool flag = IsWaitingForFullStaminaClimbRetry(pathPlan);
			bool flag2 = (flag ? HasRecoveredFullStaminaForRetry() : HasEnoughStaminaToResumeClimb(pathPlan));
			bool flag3 = num <= 1.35f;
			LookAt(flag3 ? pathPlan.Goal : pathPlan.Anchor);
			if (!flag3)
			{
				WalkTowards(pathPlan.Anchor, 0.7f, tryClimb: false, tryJump: false, sprintRequested: false);
				return;
			}
			if (!flag2)
			{
				_character.input.movementInput = Vector2.zero;
				SetSprint(sprinting: false);
				return;
			}
			if (flag)
			{
				MarkFullStaminaClimbRetryAttemptStarted(pathPlan);
			}
			WalkTowards(pathPlan.Goal, 0.95f, tryClimb: true, tryJump: false, sprintRequested: false);
			TryForceJumpGrab(pathPlan, closeToAnchor: true);
			_brainState = RobotBrainState.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 = RobotBrainState.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 = RobotBrainState.Chase;
				}
			}
			else if (!flag && (pathPlan.Action == PathActionType.Direct || IsClimbPlan(pathPlan) || pathPlan.Action == PathActionType.GapJump || pathPlan.Action == PathActionType.DropDown))
			{
				_stuckCount = 0;
				_failedClimbCount = 0;
				_brainState = RobotBrainState.Chase;
			}
			else
			{
				LookAt(GetCurrentMoveTarget());
				WalkTowards(GetGoalLookPoint(), 0.7f, tryClimb: false, tryJump: false, sprintRequested: false);
			}
		}

		private void TickLunge()
		{
			//IL_005a: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			_zombie.currentState = (State)4;
			_character.data.passedOut = false;
			_timeInLunge += Time.deltaTime;
			if (_manualBiteActive && IsValidManualBiteTarget(_manualBiteTarget))
			{
				SetCommandGoal(_manualBiteTarget, _manualBiteTarget.Head);
			}
			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;
				ClearManualBite();
				_brainState = RobotBrainState.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 = (HasActiveGoal() ? RobotBrainState.Chase : RobotBrainState.Idle);
				}
			}
		}

		private void TickActiveClimb()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: 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_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				StopClimb();
				ClearLockedClimbPlan();
				_brainState = RobotBrainState.Idle;
				return;
			}
			PathPlan activeClimbPlan = GetActiveClimbPlan();
			if (IsExhaustedForActiveClimb())
			{
				TryArmFullStaminaClimbRetry(activeClimbPlan);
				StopClimb();
				ClearLockedClimbPlan();
				SetSprint(sprinting: false);
				_character.input.movementInput = Vector2.zero;
				EnterPrepareTallClimb();
				return;
			}
			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;
			if (ShouldAbortClimbForStamina(activeClimbPlan, stamina, flag, num4))
			{
				StopClimb();
				if (TryArmFullStaminaClimbRetry(activeClimbPlan))
				{
					ClearLockedClimbPlan();
					EnterPrepareTallClimb();
					return;
				}
				RegisterFailedSegment(activeClimbPlan);
				RegisterBlockedPoint(_character.Center, 3f);
				ClearLockedClimbPlan();
				EnterReposition();
				return;
			}
			bool flag2 = stamina <= 0.18f && stamina >= 0.12f && num4 >= 0.35f;
			bool flag3 = flag || num4 >= 0.55f;
			bool flag4 = (activeClimbPlan.Action == PathActionType.Climb || activeClimbPlan.Action == PathActionType.JumpGrab) && (flag3 || flag2) && stamina >= 0.12f;
			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)
			{
				bool flag5 = !IsRoughTerrainLineBlocked(_character.Center, GetGoalCenter());
				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);
				}
			}
		}

		public bool RequestManualBite(Character? preferredTarget, out string message)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Invalid comparison between Unknown and I4
			message = string.Empty;
			if (!_initialized || (Object)(object)_character == (Object)null || (Object)(object)_zombie == (Object)null || (Object)(object)_view == (Object)null)
			{
				message = "Controlled robot is not ready.";
				return false;
			}
			if (!_view.IsMine)
			{
				message = "Nearest controlled robot is not owned by this client, so it cannot be commanded to bite.";
				return false;
			}
			if (_vanillaBiteControlActive)
			{
				DisableVanillaBiteControl();
				message = "Controlled robot returned to ping-driven AI control.";
				return true;
			}
			if ((Object)(object)_character.data == (Object)null || _character.data.dead || (int)_zombie.currentState == 6)
			{
				message = "Controlled robot is dead.";
				return false;
			}
			if (_character.data.isCarried || (Object)(object)_character.data.carrier != (Object)null || (Object)(object)_character.data.grabbingPlayer != (Object)null)
			{
				message = "Controlled robot cannot bite while it is being carried or grabbed.";
				return false;
			}
			if ((Object)(object)_character.data.carriedPlayer != (Object)null)
			{
				message = "Controlled robot is carrying a player. Drop the player before biting.";
				return false;
			}
			Character val = null;
			if (IsValidManualBiteTarget(preferredTarget))
			{
				val = preferredTarget;
			}
			if (val == null)
			{
				val = FindNearestManualBiteTarget();
			}
			if ((Object)(object)val == (Object)null)
			{
				message = "No valid player found for vanilla zombie bite control.";
				return false;
			}
			EnableVanillaBiteControl(val);
			message = "Controlled robot is now using the original zombie chase/bite AI against " + val.characterName + ". Press B again to restore ping-driven control.";
			return true;
		}

		public bool ShouldUseVanillaBiteControl(MushroomZombie zombie)
		{
			if (!_vanillaBiteControlActive)
			{
				return false;
			}
			if (!_initialized || (Object)(object)zombie != (Object)(object)_zombie || (Object)(object)_character == (Object)null || (Object)(object)_zombie == (Object)null)
			{
				_vanillaBiteControlActive = false;
				return false;
			}
			if (!_view.IsMine)
			{
				return true;
			}
			if (!IsValidManualBiteTarget(_vanillaBiteTarget))
			{
				DisableVanillaBiteControl();
				return false;
			}
			PrepareOriginalZombieBiteTick(_vanillaBiteTarget);
			return true;
		}

		private void EnableVanillaBiteControl(Character target)
		{
			_vanillaBiteTarget = target;
			_vanillaBiteControlActive = true;
			_manualBiteActive = false;
			_manualBiteTarget = null;
			_carryAssistEnabled = false;
			_carryTarget = null;
			StopClimb();
			ClearGoalParking();
			ClearLockedClimbPlan();
			_segmentQueue.Clear();
			ClearActiveSegment();
			ClearGuidePlannerCaches();
			ResetInput();
			PrepareOriginalZombieBiteTick(target);
			ForcePushState();
		}

		private void DisableVanillaBiteControl()
		{
			_vanillaBiteControlActive = false;
			_vanillaBiteTarget = null;
			_manualBiteActive = false;
			_manualBiteTarget = null;
			ResetInput();
			SetSprint(sprinting: false);
			ClearLockedClimbPlan();
			ClearActiveSegment();
			_segmentQueue.Clear();
			ClearGuidePlannerCaches();
			try
			{
				ZombieTargetForcedUntilField?.SetValue(_zombie, 0f);
				ZombieCurrentTargetField?.SetValue(_zombie, null);
			}
			catch
			{
				_zombie.currentTarget = null;
			}
			_brainState = (HasActiveGoal() ? RobotBrainState.Chase : RobotBrainState.Idle);
			_zombie.currentState = (State)((_brainState == RobotBrainState.Chase) ? 3 : 2);
			_nextReplanTime = 0f;
			ForcePushState();
		}

		private void PrepareOriginalZombieBiteTick(Character target)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Invalid comparison between Unknown and I4
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Invalid comparison between Unknown and I4
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Invalid comparison between Unknown and I4
			if ((Object)(object)_character.data == (Object)null)
			{
				return;
			}
			_character.isZombie = true;
			_character.isBot = true;
			_character.data.dead = false;
			_character.data.passedOut = false;
			_character.data.fullyPassedOut = false;
			_zombie.isNPCZombie = false;
			_zombie.spawner = null;
			_zombie.lifetime = 999999f;
			try
			{
				ZombieTargetForcedUntilField?.SetValue(_zombie, 0f);
				ZombieCurrentTargetField?.SetValue(_zombie, target);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"PrepareOriginalZombieBiteTick target set failed: {arg}");
				_zombie.currentTarget = target;
			}
			if ((int)_zombie.currentState != 4 && (int)_zombie.currentState != 5 && (int)_zombie.currentState != 6)
			{
				_zombie.currentState = (State)3;
			}
			try
			{
				float num = Mathf.Max(_zombie.chaseTimeBeforeSprint + 0.25f, 0.25f);
				ZombieTimeSpentChasingField?.SetValue(_zombie, num);
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogDebug((object)$"PrepareOriginalZombieBiteTick timeSpentChasing failed: {arg2}");
			}
		}

		public bool ToggleCarryAssist(out string message)
		{
			//IL_0162: 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)
			message = string.Empty;
			if (!_initialized || (Object)(object)_character == (Object)null || (Object)(object)_view == (Object)null)
			{
				message = "Controlled robot is not ready.";
				return false;
			}
			if (!_view.IsMine)
			{
				message = "Nearest controlled robot is not owned by this client, so it cannot be commanded to carry players.";
				return false;
			}
			if ((Object)(object)_character.data == (Object)null || _character.data.dead)
			{
				message = "Controlled robot is dead.";
				return false;
			}
			if ((Object)(object)_character.data.carriedPlayer != (Object)null)
			{
				Character carriedPlayer = _character.data.carriedPlayer;
				DropCarriedPlayer(carriedPlayer);
				DisableCarryAssist();
				message = "Controlled robot dropped " + carriedPlayer.characterName + " and disabled carry-assist.";
				return true;
			}
			if (_carryAssistEnabled)
			{
				DisableCarryAssist();
				message = "Controlled robot carry-assist disabled.";
				return true;
			}
			Character val = FindNearestCarryCandidate(80f);
			if ((Object)(object)val == (Object)null)
			{
				message = "No living player found for carry-assist.";
				return false;
			}
			_carryAssistEnabled = true;
			_carryTarget = val;
			_nextCarryRetargetTime = Time.time + 0.75f;
			ResetRouteForNewGoal(val.Center);
			SetCommandGoal(val, val.Center);
			_brainState = RobotBrainState.Chase;
			message = "Controlled robot carry-assist enabled for " + val.characterName + ".";
			return true;
		}

		public void NotifyStartedCarryingPlayer(Character target)
		{
			//IL_006c: 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_00c2: 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)
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			_carryAssistEnabled = false;
			_carryTarget = null;
			_nextCarryRetargetTime = 0f;
			_stuckCount = 0;
			_failedClimbCount = 0;
			ClearActiveSegment();
			_segmentQueue.Clear();
			ClearLockedClimbPlan();
			ResetRouteProgressWindow();
			if (PingTargetTracker.TryGetBestPingDataForRobot(_character, _spawnOwnerActorNumber, _character.Center, out var data))
			{
				SetCommandGoal(data.OwnerCharacter, data.Point, allowGoalParking: true, data.Sequence);
				_lastAcceptedPingSequence = data.Sequence;
				_brainState = RobotBrainState.Chase;
			}
			else
			{
				_ownerCharacter = null;
				_target = null;
				_goalPoint = Vector3.zero;
				_hasGoalPoint = false;
				_hasResolvedGoalPoint = false;
				_zombie.currentTarget = null;
				_brainState = RobotBrainState.Idle;
			}
			try
			{
				_character.refs.afflictions.UpdateWeight();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"NotifyStartedCarryingPlayer UpdateWeight failed: {arg}");
			}
		}

		public void NotifyStoppedCarryingPlayer(Character target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			if ((Object)(object)_carryTarget == (Object)(object)target)
			{
				DisableCarryAssist();
			}
			try
			{
				_character.refs.afflictions.UpdateWeight();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"NotifyStoppedCarryingPlayer UpdateWeight failed: {arg}");
			}
		}

		private bool ShouldHoldCommandTarget()
		{
			if (_manualBiteActive || _brainState == RobotBrainState.Lunge || _brainState == RobotBrainState.LungeRecovery)
			{
				return true;
			}
			return _carryAssistEnabled && (Object)(object)_carryTarget != (Object)null && (Object)(object)_character != (Object)null && (Object)(object)_character.data != (Object)null && (Object)(object)_character.data.carriedPlayer == (Object)null;
		}

		private void UpdateCommandStateBeforePlanning()
		{
			UpdateManualBiteGoal();
			UpdateCarryAssistGoal();
		}

		private void UpdateManualBiteGoal()
		{
			//IL_0034: 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)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (_manualBiteActive)
			{
				if (!IsValidManualBiteTarget(_manualBiteTarget))
				{
					ClearManualBite();
					return;
				}
				Vector3 head = _manualBiteTarget.Head;
				SetCommandGoal(_manualBiteTarget, head);
			}
		}

		private void StartManualBite(Character target)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_manualBiteTarget = target;
			_manualBiteActive = true;
			_timeInLunge = 0f;
			StopClimb();
			ClearLockedClimbPlan();
			_segmentQueue.Clear();
			ClearActiveSegment();
			SetCommandGoal(target, target.Head);
			LookAt(target.Head);
			_character.input.jumpWasPressed = true;
			_brainState = RobotBrainState.Lunge;
			_zombie.currentState = (State)4;
			ForcePushState();
		}

		private void ClearManualBite()
		{
			_manualBiteTarget = null;
			_manualBiteActive = false;
		}

		private Character? FindNearestManualBiteTarget()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Character result = null;
			float num = 100f;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (IsValidManualBiteTarget(allCharacter))
				{
					Vector3 val = allCharacter.Center - _character.Center;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = allCharacter;
					}
				}
			}
			return result;
		}

		private bool IsManualBiteTargetInRange(Character target)
		{
			//IL_0032: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			float num = Mathf.Min(10f, Mathf.Max(3.5f, _zombie.zombieLungeDistance));
			Vector3 val = target.Center - _character.Center;
			if (((Vector3)(ref val)).sqrMagnitude > num * num)
			{
				return false;
			}
			RaycastHit val2 = HelperFunctions.LineCheck(_character.Head, target.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1);
			return (Object)(object)((RaycastHit)(ref val2)).transform == (Object)null;
		}

		private bool IsValidManualBiteTarget(Character? candidate)
		{
			if ((Object)(object)candidate == (Object)null || (Object)(object)candidate.data == (Object)null || (Object)(object)candidate == (Object)(object)_character)
			{
				return false;
			}
			if ((Object)(object)RobotInteractionUtil.GetAgent(candidate) != (Object)null)
			{
				return false;
			}
			if (candidate.isBot || candidate.data.dead || candidate.data.fullyPassedOut)
			{
				return false;
			}
			if (candidate.data.isCarried || (Object)(object)candidate.data.carrier != (Object)null)
			{
				return false;
			}
			return true;
		}

		private void UpdateCarryAssistGoal()
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			if (!_carryAssistEnabled)
			{
				return;
			}
			if ((Object)(object)_character == (Object)null || (Object)(object)_character.data == (Object)null)
			{
				DisableCarryAssist();
				return;
			}
			if ((Object)(object)_character.data.carriedPlayer != (Object)null)
			{
				_carryAssistEnabled = false;
				_carryTarget = null;
				return;
			}
			if ((Object)(object)_carryTarget == (Object)null || !IsValidCarryCandidate(_carryTarget))
			{
				if (Time.time < _nextCarryRetargetTime)
				{
					return;
				}
				_carryTarget = FindNearestCarryCandidate(80f);
				_nextCarryRetargetTime = Time.time + 0.75f;
				if ((Object)(object)_carryTarget == (Object)null)
				{
					DisableCarryAssist();
					return;
				}
				ResetRouteForNewGoal(_carryTarget.Center);
			}
			Vector3 center = _carryTarget.Center;
			SetCommandGoal(_carryTarget, center);
			_brainState = RobotBrainState.Chase;
			if (CanStartCarrying(_carryTarget))
			{
				StartCarryingTarget(_carryTarget);
			}
		}

		private Character? FindNearestCarryCandidate(float radius)
		{
			//IL_0032: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Character result = null;
			float num = radius * radius;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (IsValidCarryCandidate(allCharacter))
				{
					Vector3 val = allCharacter.Center - _character.Center;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = allCharacter;
					}
				}
			}
			return result;
		}

		private bool IsValidCarryCandidate(Character? candidate)
		{
			if ((Object)(object)candidate == (Object)null || (Object)(object)candidate.data == (Object)null || (Object)(object)candidate == (Object)(object)_character)
			{
				return false;
			}
			if ((Object)(object)RobotInteractionUtil.GetAgent(candidate) != (Object)null)
			{
				return false;
			}
			if (candidate.isBot || candidate.data.dead)
			{
				return false;
			}
			if ((Object)(object)candidate.data.carrier != (Object)null || candidate.data.isCarried)
			{
				return false;
			}
			return true;
		}

		private bool CanStartCarrying(Character target)
		{
			//IL_0037: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || (Object)(object)target.data == (Object)null || !IsValidCarryCandidate(target))
			{
				return false;
			}
			float num = HelperFunctions.FlatDistance(_character.Center, target.Center);
			float num2 = Mathf.Abs(target.Center.y - _character.Center.y);
			if (num > 1.75f || num2 > 2.25f)
			{
				return false;
			}
			RaycastHit val = HelperFunctions.LineCheck(_character.Head, target.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1);
			return (Object)(object)((RaycastHit)(ref val)).transform == (Object)null;
		}

		private void StartCarryingTarget(Character target)
		{
			if ((Object)(object)target == (Object)null || (Object)(object)((MonoBehaviourPun)target).photonView == (Object)null)
			{
				return;
			}
			StopClimb();
			ResetInput();
			SetSprint(sprinting: false);
			try
			{
				((MonoBehaviourPun)_character).photonView.RPC("RPCA_StartCarry", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)target).photonView });
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"StartCarryingTarget failed: {arg}");
			}
		}

		private void DropCarriedPlayer(Character target)
		{
			try
			{
				if (!((Object)(object)target == (Object)null) && !((Object)(object)((MonoBehaviourPun)target).photonView == (Object)null) && !((Object)(object)_character == (Object)null) && !((Object)(object)((MonoBehaviourPun)_character).photonView == (Object)null))
				{
					((MonoBehaviourPun)_character).photonView.RPC("RPCA_Drop", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)target).photonView });
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"DropCarriedPlayer failed: {arg}");
			}
		}

		private void DisableCarryAssist()
		{
			_carryAssistEnabled = false;
			_carryTarget = null;
			_nextCarryRetargetTime = 0f;
		}

		private bool IsCarryAssistTarget(Character? target)
		{
			return _carryAssistEnabled && (Object)(object)target != (Object)null && (Object)(object)target == (Object)(object)_carryTarget;
		}

		private void SetCommandGoal(Character target, Vector3 point, bool allowGoalParking = false, int instructionSerial = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			bool flag = HasGoalPointChanged(point) || (instructionSerial > 0 && instructionSerial != _goalInstructionSerial);
			_ownerCharacter = target;
			_target = target;
			_goalPoint = point;
			_hasGoalPoint = true;
			_allowGoalParking = allowGoalParking;
			_zombie.currentTarget = target;
			if (flag)
			{
				ResetRouteForNewGoal(point, instructionSerial, allowGoalParking);
			}
		}

		public static bool TryGetForZombie(MushroomZombie? zombie, out NetworkRobotAgent? agent)
		{
			agent = null;
			if ((Object)(object)zombie == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)zombie).GetInstanceID();
			if (AgentByZombieInstanceId.TryGetValue(instanceID, out NetworkRobotAgent value))
			{
				if ((Object)(object)value != (Object)null && value._initialized && (Object)(object)value._zombie == (Object)(object)zombie)
				{
					agent = value;
					return true;
				}
				AgentByZombieInstanceId.Remove(instanceID);
			}
			float unscaledTime = Time.unscaledTime;
			if (MissingAgentRetryByZombieInstanceId.TryGetValue(instanceID, out var value2) && unscaledTime < value2)
			{
				return false;
			}
			try
			{
				agent = ((Component)zombie).GetComponent<NetworkRobotAgent>();
			}
			catch
			{
				agent = null;
			}
			if ((Object)(object)agent != (Object)null)
			{
				AgentByZombieInstanceId[instanceID] = agent;
				MissingAgentRetryByZombieInstanceId.Remove(instanceID);
				return true;
			}
			MissingAgentRetryByZombieInstanceId[instanceID] = unscaledTime + 0.25f;
			return false;
		}

		public static NetworkRobotAgent? 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			NetworkRobotAgent result = null;
			float num = float.PositiveInfinity;
			for (int num2 = All.Count - 1; num2 >= 0; num2--)
			{
				NetworkRobotAgent networkRobotAgent = All[num2];
				if ((Object)(object)networkRobotAgent == (Object)null || !networkRobotAgent._initialized || (Object)(object)networkRobotAgent._character == (Object)null)
				{
					All.RemoveAt(num2);
				}
				else
				{
					Vector3 val = point - networkRobotAgent._character.Center;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = networkRobotAgent;
					}
				}
			}
			return result;
		}

		public static NetworkRobotAgent? FindNearestOwnedByLocal(Vector3 point)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			NetworkRobotAgent result = null;
			float num = float.PositiveInfinity;
			for (int num2 = All.Count - 1; num2 >= 0; num2--)
			{
				NetworkRobotAgent networkRobotAgent = All[num2];
				if ((Object)(object)networkRobotAgent == (Object)null || !networkRobotAgent._initialized || (Object)(object)networkRobotAgent._character == (Object)null)
				{
					All.RemoveAt(num2);
				}
				else if (networkRobotAgent.IsOwnedByLocalPlayer)
				{
					Vector3 val = point - networkRobotAgent._character.Center;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = networkRobotAgent;
					}
				}
			}
			return result;
		}

		private void ReadSpawnOwnershipMetadata(PhotonView photonView)
		{
			_spawnOwnerActorNumber = (((Object)(object)photonView != (Object)null) ? photonView.OwnerActorNr : 0);
			_spawnOwnerUserId = (((Object)(object)photonView != (Object)null && photonView.Owner != null) ? (photonView.Owner.UserId ?? string.Empty) : string.Empty);
			try
			{
				object[] array = (((Object)(object)photonView != (Object)null) ? photonView.InstantiationData : null);
				if (array != null && array.Length != 0)
				{
					if (array.Length != 0 && array[0] is int num && num > 0)
					{
						_spawnOwnerActorNumber = num;
					}
					if (array.Length > 1 && array[1] is string spawnOwnerUserId)
					{
						_spawnOwnerUserId = spawnOwnerUserId;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogDebug((object)$"ReadSpawnOwnershipMetadata failed: {arg}");
			}
		}

		private void ClearPingGoalState()
		{
			//IL_0010: 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)
			_ownerCharacter = null;
			_target = null;
			_goalPoint = Vector3.zero;
			_hasGoalPoint = false;
			_hasResolvedGoalPoint = false;
			_resolvedGoalIsStandable = false;
			_rawGoalIsStandable = false;
			_hasLastResolvedRawGoal = false;
			if ((Object)(object)_zombie != (Object)null)
			{
				_zombie.currentTarget = null;
			}
			_segmentQueue.Clear();
			ClearActiveSegment();
			ClearLockedClimbPlan();
			ResetFullStaminaClimbRetry();
			ClearGuidePlannerCaches();
			ClearGoalParking();
			_goalInstructionSerial = 0;
			_lastAcceptedPingSequence = 0;
			_allowGoalParking = true;
			_hadAcceptedGoalPoint = false;
		}

		public void Initialize(MushroomZombie zombie)
		{
			//IL_00d5: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//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_0224: 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)"NetworkRobotAgent.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)"NetworkRobotAgent requires PhotonView on MushroomZombie object.");
				((Behaviour)this).enabled = false;
				return;
			}
			_zombie = zombie;
			_character = zombie.character;
			_view = component;
			ReadSpawnOwnershipMetadata(component);
			_ownerCharacter = Character.localCharacter;
			_target = _ownerCharacter;
			_goalPoint = Vector3.zero;
			_hasGoalPoint = false;
			_resolvedGoalPoint = Vector3.zero;
			_hasResolvedGoalPoint = false;
			_resolvedGoalIsStandable = false;
			_hasLastResolvedRawGoal = false;
			_nextResolvedGoalRefreshTime = 0f;
			ClearGoalParking();
			_goalInstructionSerial = 0;
			_lastAcceptedPingSequence = 0;
			_allowGoalParking = true;
			_brainState = RobotBrainState.Idle;
			_nextTargetRefreshTime = 0f;
			_lastSeenTargetTime = Time.time;
			_timeInChase = 0f;
			_timeInLunge = 0f;
			_stuckTimer = 0f;
			_stuckAnchor = _character.Center;
			_stuckCount = 0;
			_climbTimer = 0f;
			_climbStartHeight = 0f;
			_failedClimbCount = 0;
			_activeClimbStartedAtRetryFullStamina = false;
			_awaitingFullStaminaClimbRetry = false;
			_fullStaminaClimbRetryConsumed = false;
			_fullStaminaClimbRetryAnchor = Vector3.zero;
			_fullStaminaClimbRetryGoalSerial = 0;
			_lastAutoJumpTime = -999f;
			_plan = new PathPlan();
			_blockedMemory.Clear();
			_failedSegments.Clear();
			_recentRouteChoices.Clear();
			ClearGuidePlannerCaches();
			_segmentQueue.Clear();
			ClearActiveSegment();
			ClearLockedClimbPlan();
			_lastVisualZombieState = (State)(-1);
			_lastVisualBiteColliderEnabled = false;
			_lastVisualSprintState = false;
			_hasVisualStateSnapshot = false;
			canBeCarriedAsRobot = true;
			suppressRobotAI = false;
			zombieInteractionLock = 0f;
			lastRobotFedTime = -999f;
			_initialized = true;
			_nextPersistentRefreshTime = 0f;
			AgentByZombieInstanceId[((Object)_zombie).GetInstanceID()] = this;
			MissingAgentRetryByZombieInstanceId.Remove(((Object)_zombie).GetInstanceID());
			RobotInteractionUtil.RegisterAgent(_character, this);
			if (!All.Contains(this))
			{
				All.Add(this);
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
			if ((Object)(object)_zombie != (Object)null)
			{
				AgentByZombieInstanceId.Remove(((Object)_zombie).GetInstanceID());
				MissingAgentRetryByZombieInstanceId.Remove(((Object)_zombie).GetInstanceID());
			}
			RobotInteractionUtil.UnregisterAgent(_character, this);
		}

		public void DeleteRobotNetworked()
		{
			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)$"DeleteRobotNetworked RequestOwnership failed: {arg}");
						}
					}
					PhotonNetwork.Destroy(((Component)this).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogDebug((object)$"DeleteRobotNetworked failed: {arg2}");
				try
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				catch
				{
				}
			}
		}

		private void PrepareForDelete()
		{
			_initialized = false;
			suppressRobotAI = true;
			All.Remove(this);
			if ((Object)(object)_zombie != (Object)null)
			{
				AgentByZombieInstanceId.Remove(((Object)_zombie).GetInstanceID());
				MissingAgentRetryByZombieInstanceId.Remove(((Object)_zombie).GetInstanceID());
			}
			RobotInteractionUtil.UnregisterAgent(_character, this);
			try
			{
				ResetInput();
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_character != (Object)null && (Object)(object)_character.data != (Object)null)
				{
					if ((Object)(object)_character.data.carriedPlayer != (Object)null && (Object)(object)((MonoBehaviourPun)_character).photonView != (Object)null)
					{
						((MonoBehaviourPun)_character).photonView.RPC("RPCA_Drop", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)_character.data.carriedPlayer).photonView });
					}
					_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)
				{
					suppressRobotAI = true;
					canBeCarriedAsRobot = true;
					zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f);
				}
				else if (flag)
				{
					suppressRobotAI = true;
					canBeCarriedAsRobot = true;
					zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f);
				}
				else if (zombieInteractionLock <= 0f)
				{
					suppressRobotAI = false;
					canBeCarriedAsRobot = true;
				}
			}
		}

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

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

		public void NotifyCarriedByPlayer(Character player)
		{
			suppressRobotAI = true;
			canBeCarriedAsRobot = true;
			zombieInteractionLock = 999f;
		}

		public void NotifyDroppedByPlayer(Character player)
		{
			zombieInteractionLock = 1.5f;
			suppressRobotAI = false;
			canBeCarriedAsRobot = 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;
					}
					suppressRobotAI = true;
					canBeCarriedAsRobot = 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)
		{
			lastRobotFedTime = Time.time;
			canBeCarriedAsRobot = true;
			suppressRobotAI = 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_00aa: 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)
			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:
			case PathActionType.JumpGrab:
				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_0050: 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_00b0: 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 (IsClimbPlan(segment))
			{
				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 < 3; 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 ((IsClimbPlan(pathPlan2) || pathPlan2.Action == PathActionType.Detour || pathPlan2.Action == PathActionType.Direct) && list.Count < 3)
						{
							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;
			}
			if (list.Count == 0 && ShouldEscalateToGuidedPlanner())
			{
				List<PathPlan> list2 = BuildGuidedPathSegments();
				if (list2.Count > 0)
				{
					return list2;
				}
			}
			return list;
		}

		private bool ShouldEscalateToGuidedPlanner()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!HasActiveGoal())
			{
				return false;
			}
			if (_stuckCount > 0 || _failedClimbCount > 0 || _failedSegments.Count > 0)
			{
				return true;
			}
			float num = HelperFunctions.FlatDistance(_character.Center, GetGoalCenter());
			float num2 = Mathf.Abs(GetGoalCenter().y - _character.Center.y);
			return num <= 1.2f && GetGoalCenter().y - _character.Center.y < -2f && num2 > 2f;
		}

		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_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_00d4: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			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,
				ProjectedEndPoint = src.ProjectedEndPoint,
				HasProjectedEndPoint = src.HasProjectedEndPoint,
				ProjectedRemainingStamina = src.ProjectedRemainingStamina,
				PlanningDepth = src.PlanningDepth,
				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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new PathPlan
			{
				Action = PathActionType.Hold,
				Goal = goalLook,
				Anchor = goalLook,
				TargetAbove = targetAbove,
				ProjectedEndPoint = goalLook,
				HasProjectedEndPoint = true
			};
		}

		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_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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due