Decompiled source of ZombieJoiner v1.0.1
ZombieJoiner.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ZombieJoiner")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("ZombieJoiner")] [assembly: AssemblyTitle("ZombieJoiner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Zombiejoin { [BepInPlugin("ZombieJoiner", "ZombieJoiner", "1.0.1")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <SpawnZombieRoutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Plugin <>4__this; private Character <localCharacter>5__1; private Vector3 <spawnPos>5__2; private Quaternion <spawnRot>5__3; private Bodypart <torso>5__4; private GameObject <zombieObj>5__5; private MushroomZombie <zombie>5__6; private ZombiePlayerAgent <agent>5__7; private Vector3 <forward>5__8; private Exception <ex>5__9; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnZombieRoutine>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <localCharacter>5__1 = null; <torso>5__4 = null; <zombieObj>5__5 = null; <zombie>5__6 = null; <agent>5__7 = null; <ex>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._isSpawning = true; <localCharacter>5__1 = Character.localCharacter; if ((Object)(object)<localCharacter>5__1 == (Object)null) { <>4__this._isSpawning = false; return false; } <spawnPos>5__2 = <localCharacter>5__1.Center; <spawnRot>5__3 = Quaternion.identity; <torso>5__4 = <localCharacter>5__1.GetBodypart((BodypartType)2); if ((Object)(object)<torso>5__4 != (Object)null) { <spawnPos>5__2 = ((Component)<torso>5__4).transform.position; <spawnRot>5__3 = ((Component)<torso>5__4).transform.rotation; } if (<>4__this._spawnNearPlayer.Value) { <forward>5__8 = <localCharacter>5__1.data.lookDirection; if (<forward>5__8 == Vector3.zero) { <forward>5__8 = ((Component)<localCharacter>5__1).transform.forward; } <forward>5__8.y = 0f; if (((Vector3)(ref <forward>5__8)).sqrMagnitude < 0.001f) { <forward>5__8 = Vector3.forward; } ((Vector3)(ref <forward>5__8)).Normalize(); <spawnPos>5__2 += <forward>5__8 * <>4__this._spawnForwardOffset.Value; } try { <zombieObj>5__5 = PhotonNetwork.Instantiate(<>4__this._zombiePrefabName.Value, <spawnPos>5__2, <spawnRot>5__3, (byte)0, (object[])null); } catch (Exception ex) { <ex>5__9 = ex; Log.LogError((object)$"Failed to instantiate zombie prefab '{<>4__this._zombiePrefabName.Value}': {<ex>5__9}"); <>4__this._isSpawning = false; return false; } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; if ((Object)(object)<zombieObj>5__5 == (Object)null) { Log.LogError((object)"Zombie instantiate returned null."); <>4__this._isSpawning = false; return false; } <zombie>5__6 = <zombieObj>5__5.GetComponent<MushroomZombie>(); if ((Object)(object)<zombie>5__6 == (Object)null) { Log.LogError((object)"Spawned object does not contain MushroomZombie component."); <>4__this._isSpawning = false; return false; } <zombie>5__6.isNPCZombie = false; <zombie>5__6.spawner = null; <zombie>5__6.lifetime = 999999f; if ((Object)(object)ZombieManager.Instance != (Object)null) { ZombieManager.Instance.DeRegisterZombie(<zombie>5__6); } if ((Object)(object)<zombie>5__6.character == (Object)null || (Object)(object)<zombie>5__6.character.data == (Object)null) { Log.LogError((object)"Spawned zombie has no Character or CharacterData."); SafeDestroySpawnedObject(<zombieObj>5__5); <>4__this._isSpawning = false; return false; } <zombie>5__6.character.isZombie = true; <zombie>5__6.character.data.passedOut = false; <zombie>5__6.character.data.fullyPassedOut = false; <zombie>5__6.character.data.dead = false; <zombie>5__6.character.data.fallSeconds = 0f; <zombie>5__6.character.data.currentRagdollControll = 1f; <zombie>5__6.currentState = (State)2; if (!<zombie>5__6.visible) { ((MonoBehaviour)<zombie>5__6).StartCoroutine(<zombie>5__6.RevealZombie()); } <agent>5__7 = ((Component)<zombie>5__6).gameObject.GetComponent<ZombiePlayerAgent>(); if ((Object)(object)<agent>5__7 == (Object)null) { <agent>5__7 = ((Component)<zombie>5__6).gameObject.AddComponent<ZombiePlayerAgent>(); } <agent>5__7.Initialize(<zombie>5__6); Log.LogInfo((object)"Spawned one controlled zombie player."); <>4__this._isSpawning = false; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string ModGuid = "ZombieJoiner"; public const string ModName = "ZombieJoiner"; public const string ModVersion = "1.0.1"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony _harmony = null; private ConfigEntry<KeyCode> _spawnKey = null; private ConfigEntry<KeyCode> _deleteKey = null; private ConfigEntry<string> _zombiePrefabName = null; private ConfigEntry<float> _spawnForwardOffset = null; private ConfigEntry<bool> _spawnNearPlayer = null; private bool _isSpawning; private void Awake() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _spawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "SpawnZombieKey", (KeyCode)106, "Press this key to spawn one controlled zombie player."); _deleteKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "DeleteZombieKey", (KeyCode)107, "Press this key to delete the nearest controlled zombie player."); _zombiePrefabName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ZombiePrefabName", "MushroomZombie", "Photon prefab name of the zombie to spawn."); _spawnForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnForwardOffset", 2.5f, "How far in front of the player to spawn the zombie."); _spawnNearPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SpawnNearPlayer", true, "Spawn zombie near the player."); _harmony = new Harmony("ZombieJoiner"); _harmony.PatchAll(); Log.LogInfo((object)"ZombieJoiner loaded."); } private void OnDestroy() { try { _harmony.UnpatchSelf(); } catch (Exception arg) { Log.LogDebug((object)$"UnpatchSelf failed: {arg}"); } } private void Update() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) try { if (Input.GetKeyDown(_deleteKey.Value)) { DeleteNearestZombie(); } else if (Input.GetKeyDown(_spawnKey.Value) && !_isSpawning) { if (!PhotonNetwork.InRoom) { Log.LogWarning((object)"Not in a room."); } else if ((Object)(object)Character.localCharacter == (Object)null) { Log.LogWarning((object)"Local character not found."); } else { ((MonoBehaviour)this).StartCoroutine(SpawnZombieRoutine()); } } } catch (Exception arg) { Log.LogDebug((object)$"Plugin.Update failed: {arg}"); } } private void DeleteNearestZombie() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) try { if (!PhotonNetwork.InRoom) { Log.LogWarning((object)"Not in a room."); return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { Log.LogWarning((object)"Local character not found."); return; } ZombiePlayerAgent zombiePlayerAgent = ZombiePlayerAgent.FindNearest(localCharacter.Center); if ((Object)(object)zombiePlayerAgent == (Object)null || (Object)(object)zombiePlayerAgent.Character == (Object)null) { Log.LogInfo((object)"No controlled zombie found to delete."); return; } int num = (((Object)(object)zombiePlayerAgent.View != (Object)null) ? zombiePlayerAgent.View.ViewID : (-1)); zombiePlayerAgent.DeleteZombieNetworked(); Log.LogInfo((object)$"Deleted controlled zombie [{num}]."); } catch (Exception arg) { Log.LogDebug((object)$"DeleteNearestZombie failed: {arg}"); } } [IteratorStateMachine(typeof(<SpawnZombieRoutine>d__16))] private IEnumerator SpawnZombieRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnZombieRoutine>d__16(0) { <>4__this = this }; } private static void SafeDestroySpawnedObject(GameObject obj) { try { if (!((Object)(object)obj == (Object)null)) { PhotonView component = obj.GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null && PhotonNetwork.InRoom) { PhotonNetwork.Destroy(obj); } else { Object.Destroy((Object)(object)obj); } } } catch (Exception arg) { Log.LogDebug((object)$"SafeDestroySpawnedObject failed: {arg}"); try { Object.Destroy((Object)(object)obj); } catch { } } } } internal enum ZombieBrainState { Idle, Chase, PrepareTallClimb, Reposition, Lunge, LungeRecovery, Dead } internal enum PathActionType { None, Direct, Detour, Climb, JumpGrab, GapJump, DropDown, Hold } internal sealed class PathPlan { public PathActionType Action = PathActionType.None; public Vector3 Goal; public Vector3 Anchor; public float RequiredStamina; public bool TargetAbove; public float EstimatedClimbHeight; public bool IsTallWall; public float ExpectedDropHeight; public bool UsesJumpDropImmunity; public bool ReachableWithinRecoverableBudget; public float Score; public bool NeedsJumpStart; public Vector3 ClimbTopPoint; public Vector3 ClimbSurfaceNormal; public Vector3 JumpGrabAimPoint; public float JumpGrabHorizontalDistance; } internal struct RouteProbe { public bool ObstacleAhead; public float ObstacleDistance; public Vector3 ObstaclePoint; public bool ClimbableAhead; public float ClimbHeightDelta; public Vector3 ClimbBasePoint; public bool NeedsJumpStart; public Vector3 ClimbTopPoint; public Vector3 ClimbSurfaceNormal; public bool UnsafeDropAhead; public float DropHeight; public bool SafeWalkDrop; public bool SafeJumpDrop; public Vector3 DropLandingPoint; public bool GapJumpable; public Vector3 GapLandingPoint; public float GapLandingDrop; } internal sealed class BlockedMemory { public Vector3 Point = Vector3.zero; public float Until; } internal struct PingTargetData { public Vector3 Point; public float Time; public int Sequence; } internal static class ZombiePingTracker { private static readonly Dictionary<int, PingTargetData> LastPingByCharacter = new Dictionary<int, PingTargetData>(); private static int _sequence; public const float PingLifetime = 30f; private static int GetKey(Character character) { return ((Object)(object)character != (Object)null) ? ((Object)character).GetInstanceID() : 0; } public static void SetPing(Character character, Vector3 point) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)character == (Object)null)) { LastPingByCharacter[GetKey(character)] = new PingTargetData { Point = point, Time = Time.time, Sequence = ++_sequence }; } } public static bool TryGetLatestPingForZombie(Vector3 zombiePos, out Character? owner, out Vector3 point) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) owner = null; point = Vector3.zero; int num = int.MinValue; bool flag = false; foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.isBot && !allCharacter.data.dead && !allCharacter.data.fullyPassedOut && TryGetPingData(allCharacter, out var data) && (!flag || data.Sequence > num)) { flag = true; num = data.Sequence; owner = allCharacter; point = data.Point; } } return flag; } public static bool TryGetBestPingForZombie(Vector3 zombiePos, out Character? owner, out Vector3 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryGetLatestPingForZombie(zombiePos, out owner, out point); } public static bool TryGetPing(Character character, out Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; if (!TryGetPingData(character, out var data)) { return false; } point = data.Point; return true; } private static bool TryGetPingData(Character character, out PingTargetData data) { data = default(PingTargetData); if ((Object)(object)character == (Object)null) { return false; } int key = GetKey(character); if (!LastPingByCharacter.TryGetValue(key, out data)) { return false; } if (Time.time - data.Time > 30f) { LastPingByCharacter.Remove(key); return false; } return true; } public static void ClearPing(Character character) { if (!((Object)(object)character == (Object)null)) { LastPingByCharacter.Remove(GetKey(character)); } } } [HarmonyPatch(typeof(PointPinger), "ReceivePoint_Rpc")] internal static class PointPingerReceivePatch { [HarmonyPostfix] private static void Postfix(PointPinger __instance, Vector3 point) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.character == (Object)null)) { ZombiePingTracker.SetPing(__instance.character, point); } } catch (Exception arg) { Plugin.Log.LogDebug((object)$"PointPingerReceivePatch failed: {arg}"); } } } internal sealed class ZombiePlayerAgent : MonoBehaviour { internal sealed class FailedSegmentMemory { public PathActionType Action = PathActionType.None; public Vector3 Position = Vector3.zero; public Vector3 Direction = Vector3.zero; public float Until; } private readonly List<FailedSegmentMemory> _failedSegments = new List<FailedSegmentMemory>(); public static readonly List<ZombiePlayerAgent> All = new List<ZombiePlayerAgent>(); private bool _rawGoalIsStandable; private const float ImmediateDirectClimbFlatDistance = 2.35f; private const float ImmediateDirectClimbVerticalSlack = 0.55f; private const float SmallObstacleHopCooldown = 0.12f; private const float SmallObstacleHopMinStamina = 0.02f; private const float GoalExactStandFlatRadius = 0.3f; private const float GoalExactStandVerticalTolerance = 0.3f; private const float ObstacleBypassJumpMinHeight = 0.28f; private const float ObstacleBypassJumpMaxHeight = 1.55f; private const float ObstacleBypassJumpMaxLandingDelta = 0.9f; public bool canBeCarriedAsZombie; public bool suppressZombieAI; public float zombieInteractionLock; public float lastZombieFedTime; private const float EdgeGoalSupportProbeRadius = 0.45f; private const float EdgeGoalSupportProbeHeight = 0.65f; private const float EdgeGoalSupportDropTolerance = 1.4f; private const float EdgeGoalResolvedReuseDistance = 0.9f; private const float EdgeGoalRawOffsetThreshold = 0.55f; private const float EdgeGoalArriveFlat = 1.85f; private const float EdgeGoalArriveVertical = 2.6f; private const float EdgeGoalNearPlanDistance = 2.2f; private PathPlan _lockedClimbPlan = new PathPlan(); private bool _hasLockedClimbPlan; private readonly Queue<PathPlan> _segmentQueue = new Queue<PathPlan>(); private PathPlan _activeSegment = new PathPlan(); private bool _hasActiveSegment; private float _routeWindowStartTime; private float _routeWindowStartGoalDistance; private Vector3 _segmentStartPos; private float _segmentStartTime; private float _segmentStartGoalDistance; private Vector3 _lastAcceptedGoalPoint = Vector3.zero; private bool _hadAcceptedGoalPoint; private float _nextReplanTime; private const float ImmediateJumpGrabMaxFlatDistance = 3.2f; private const float ImmediateJumpGrabMinHeightDelta = 1f; private const float ImmediateJumpGrabMaxHeightDelta = 4.8f; private const float ImmediateJumpGrabAnchorRadius = 1.6f; private const float SegmentMinProgressTime = 1.2f; private const float SegmentProgressTimeout = 3f; private const float SegmentMinGoalProgress = 1f; private const float SegmentArriveDistance = 1.25f; private const float SegmentArriveVertical = 1.75f; private const float RouteNetProgressWindow = 2.5f; private const float RouteNetProgressMin = 0.9f; private const float ReplanCooldown = 0.25f; private const int MaxPlannedSegments = 4; private float _repositionUntil; private const float ClimbStartGraceTime = 0.45f; private const float RepositionMinDuration = 1.1f; private const float DirectBlockedPenaltyThreshold = 1.1f; private const float ClimbLastStaminaBurstThreshold = 0.05f; private MushroomZombie _zombie = null; private Character _character = null; private PhotonView _view = null; private ZombieBrainState _brainState = ZombieBrainState.Idle; private Character? _ownerCharacter; private Character? _target; private Vector3 _goalPoint; private bool _hasGoalPoint; private Vector3 _resolvedGoalPoint; private bool _hasResolvedGoalPoint; private bool _resolvedGoalIsStandable; private float _nextResolvedGoalRefreshTime; private float _nextTargetRefreshTime; private float _lastSeenTargetTime; private float _timeInChase; private float _timeInLunge; private float _stuckTimer; private Vector3 _stuckAnchor; private int _stuckCount; private float _climbTimer; private float _climbStartHeight; private int _failedClimbCount; private float _lastAutoJumpTime; private PathPlan _plan = new PathPlan(); private readonly List<BlockedMemory> _blockedMemory = new List<BlockedMemory>(); private bool _initialized; private State _lastVisualZombieState = (State)(-1); private bool _lastVisualBiteColliderEnabled; private bool _lastVisualSprintState; private bool _hasVisualStateSnapshot; private const float ProbeDistance = 2.2f; private const float GroundProbeHeight = 2.2f; private const float GroundProbeDepth = 16f; private const float ObstacleProbeRadius = 0.38f; private const float MaxSafeWalkDrop = 10f; private const float MaxSafeJumpDrop = 20f; private const float GapJumpNear = 1.8f; private const float GapJumpFar = 4.8f; private const float MaxClimbHeight = 4.2f; private const float TargetAboveThreshold = 1.4f; private const float OverheadSearchRadius = 3.5f; private const float TravelHopInterval = 0.2f; private const float ChainJumpStaminaThreshold = 0.35f; private const float StickyClimbMinTime = 0.8f; private const float StickyClimbTopReleaseFlat = 1.8f; private const float StickyClimbTopReleaseVertical = -1f; private const float TallWallHeightThreshold = 2.15f; private const float SmallWallFastClimbThreshold = 1.2f; private const float ClimbBurstStartProgress = 0.55f; private const float ClimbBurstMinStamina = 0.01f; private const float ClosePressureFlat = 1.65f; private const float ClosePressureVertical = 1.15f; private const float CloseStopFlat = 0.55f; private const float JumpGrabMinVertical = 1f; private const float JumpGrabMaxVertical = 4.6f; private const float JumpGrabPressInterval = 0.2f; private const float JumpGrabMinStamina = 0.04f; private const float ClimbTraverseStrongX = 0.95f; private const float ClimbTraverseWeakX = 0.6f; private const float ClimbDiagonalUp = 0.95f; private const float ClimbVerticalUp = 1f; private const float ClimbBurstSprintXBoost = 1.15f; private const float ClimbBurstSprintYBoost = 1.12f; private const float ClimbTopAssistDistance = 1.25f; private const float GoalArriveFlatDistance = 1.35f; private const float GoalArriveVerticalDistance = 2.25f; private const float ClimbWaitAnchorDistance = 1.35f; private const float ClimbResumeHysteresis = 0.02f; private const float GoalStandSearchRadius = 1.2f; private const float GoalStandPreferRadius = 0.95f; private const float ResolvedGoalRefreshInterval = 0.2f; private const float SmallObstacleHeightMax = 1.1f; private const float SmallObstacleForwardCheck = 1f; private static readonly float[] SearchAngles = new float[11] { 0f, 20f, -20f, 40f, -40f, 60f, -60f, 90f, -90f, 120f, -120f }; private static readonly float[] OverheadAngles = new float[14] { 0f, 20f, -20f, 40f, -40f, 60f, -60f, 90f, -90f, 120f, -120f, 150f, -150f, 180f }; private static readonly float[] LateralTraverseSamples = new float[4] { 0.7f, 1.1f, 1.5f, 2f }; private static readonly int TerrainMask = LayerMask.GetMask(new string[2] { "Terrain", "Map" }); private static readonly MethodInfo? PushStateMethod = AccessTools.Method(typeof(MushroomZombie), "PushState", (Type[])null, (Type[])null); private ZombieBrainState _lastLoggedBrainState = (ZombieBrainState)(-1); public Character? Character => _character; public PhotonView? View => _view; public static ZombiePlayerAgent? FindNearest(Vector3 point) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) ZombiePlayerAgent result = null; float num = float.PositiveInfinity; for (int num2 = All.Count - 1; num2 >= 0; num2--) { ZombiePlayerAgent zombiePlayerAgent = All[num2]; if ((Object)(object)zombiePlayerAgent == (Object)null || !zombiePlayerAgent._initialized || (Object)(object)zombiePlayerAgent._character == (Object)null) { All.RemoveAt(num2); } else { float num3 = Vector3.Distance(point, zombiePlayerAgent._character.Center); if (num3 < num) { num = num3; result = zombiePlayerAgent; } } } return result; } public void Initialize(MushroomZombie zombie) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)zombie == (Object)null || (Object)(object)zombie.character == (Object)null || (Object)(object)zombie.character.data == (Object)null) { Plugin.Log.LogError((object)"ZombiePlayerAgent.Initialize failed: invalid zombie or character data."); ((Behaviour)this).enabled = false; return; } _lockedClimbPlan = new PathPlan(); _hasLockedClimbPlan = false; _repositionUntil = 0f; PhotonView component = ((Component)zombie).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)"ZombiePlayerAgent requires PhotonView on MushroomZombie object."); ((Behaviour)this).enabled = false; return; } _zombie = zombie; _character = zombie.character; _view = component; _ownerCharacter = Character.localCharacter; _target = _ownerCharacter; _goalPoint = Vector3.zero; _hasGoalPoint = false; _resolvedGoalPoint = Vector3.zero; _hasResolvedGoalPoint = false; _resolvedGoalIsStandable = false; _nextResolvedGoalRefreshTime = 0f; _brainState = ZombieBrainState.Idle; _nextTargetRefreshTime = 0f; _lastSeenTargetTime = Time.time; _timeInChase = 0f; _timeInLunge = 0f; _stuckTimer = 0f; _stuckAnchor = _character.Center; _stuckCount = 0; _climbTimer = 0f; _climbStartHeight = 0f; _failedClimbCount = 0; _lastAutoJumpTime = -999f; _plan = new PathPlan(); _blockedMemory.Clear(); _failedSegments.Clear(); _segmentQueue.Clear(); ClearActiveSegment(); ClearLockedClimbPlan(); _lastVisualZombieState = (State)(-1); _lastVisualBiteColliderEnabled = false; _lastVisualSprintState = false; _hasVisualStateSnapshot = false; canBeCarriedAsZombie = true; suppressZombieAI = false; zombieInteractionLock = 0f; lastZombieFedTime = -999f; _initialized = true; if (!All.Contains(this)) { All.Add(this); } } private void OnDestroy() { All.Remove(this); } public void DeleteZombieNetworked() { try { PrepareForDelete(); if ((Object)(object)_view != (Object)null && PhotonNetwork.InRoom) { if (!_view.IsMine && !PhotonNetwork.IsMasterClient) { try { _view.RequestOwnership(); } catch (Exception arg) { Plugin.Log.LogDebug((object)$"DeleteZombieNetworked RequestOwnership failed: {arg}"); } } PhotonNetwork.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } catch (Exception arg2) { Plugin.Log.LogDebug((object)$"DeleteZombieNetworked failed: {arg2}"); try { Object.Destroy((Object)(object)((Component)this).gameObject); } catch { } } } private void PrepareForDelete() { _initialized = false; suppressZombieAI = true; All.Remove(this); try { ResetInput(); } catch { } try { if ((Object)(object)_character != (Object)null && (Object)(object)_character.data != (Object)null) { _character.data.grabbingPlayer = null; _character.data.grabbedPlayer = null; _character.data.carriedPlayer = null; _character.data.carrier = null; _character.data.isCarried = false; _character.data.currentItem = null; } } catch { } } private void UpdateInteractionState() { if (zombieInteractionLock > 0f) { zombieInteractionLock -= Time.deltaTime; if (zombieInteractionLock < 0f) { zombieInteractionLock = 0f; } } if (!((Object)(object)_character == (Object)null)) { bool flag = (Object)(object)_character.data.grabbingPlayer != (Object)null; if (_character.data.isCarried || (Object)(object)_character.data.carrier != (Object)null) { suppressZombieAI = true; canBeCarriedAsZombie = true; zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f); } else if (flag) { suppressZombieAI = true; canBeCarriedAsZombie = true; zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.5f); } else if (zombieInteractionLock <= 0f) { suppressZombieAI = false; canBeCarriedAsZombie = true; } } } public void NotifyGrabbedByPlayer(Character player) { suppressZombieAI = true; canBeCarriedAsZombie = true; zombieInteractionLock = Mathf.Max(zombieInteractionLock, 2f); } public void NotifyReleasedByPlayer(Character player) { zombieInteractionLock = Mathf.Max(zombieInteractionLock, 1.25f); if (!_character.data.isCarried) { suppressZombieAI = false; } } public void NotifyCarriedByPlayer(Character player) { suppressZombieAI = true; canBeCarriedAsZombie = true; zombieInteractionLock = 999f; } public void NotifyDroppedByPlayer(Character player) { zombieInteractionLock = 1.5f; suppressZombieAI = false; canBeCarriedAsZombie = true; } [PunRPC] public void RPC_AssistDrag(Vector3 helperCenter, float force) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null) && (!((Object)(object)_view != (Object)null) || _view.IsMine || PhotonNetwork.IsMasterClient)) { _character.DragTowards(helperCenter, force); _character.LimitFalling(); if (_character.data.isClimbing) { _character.data.sinceGrounded = 0f; } suppressZombieAI = true; canBeCarriedAsZombie = true; zombieInteractionLock = Mathf.Max(zombieInteractionLock, 0.35f); } } catch (Exception arg) { Plugin.Log.LogDebug((object)$"RPC_AssistDrag failed: {arg}"); } } public void NotifyFedByPlayer(Character player, Item item) { lastZombieFedTime = Time.time; canBeCarriedAsZombie = true; suppressZombieAI = true; zombieInteractionLock = Mathf.Max(zombieInteractionLock, 8f); } public bool CanBeHelpedByPlayer() { if ((Object)(object)_character == (Object)null) { return false; } if (_character.data.dead) { return false; } if (_character.IsStuck() || _character.data.sinceUnstuck < 1f) { return true; } if ((Object)(object)_character.refs.afflictions != (Object)null && _character.refs.afflictions.isWebbed) { return true; } if (_character.data.isClimbing || _character.data.isRopeClimbing || _character.data.isVineClimbing) { return true; } if (zombieInteractionLock > 0f) { return true; } return false; } private void TickSuppressedByInteraction() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) _zombie.currentState = (State)2; _character.data.passedOut = false; ResetInput(); SetSprint(sprinting: false); if (_character.data.isClimbing) { StopClimb(); } if ((Object)(object)_character.data.currentClimbHandle != (Object)null) { _character.refs.climbing.CancelHandle(false); } _character.input.movementInput = Vector2.zero; Vector3 lookAtPos = _character.Head + _character.data.lookDirection_Flat * 2f; LookAt(lookAtPos); } private void BeginSegment(PathPlan segment) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) _activeSegment = ClonePlan(segment); _hasActiveSegment = true; _segmentStartPos = _character.Center; _segmentStartTime = Time.time; _segmentStartGoalDistance = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f); } private void ClearActiveSegment() { _activeSegment = new PathPlan(); _hasActiveSegment = false; } private bool IsSegmentFinished(PathPlan segment) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) float num = HelperFunctions.FlatDistance(_character.Center, segment.Goal); float num2 = Mathf.Abs(segment.Goal.y - _character.Center.y); switch (segment.Action) { case PathActionType.Direct: case PathActionType.Detour: return num <= 1.25f && num2 <= 1.75f; case PathActionType.Climb: if (!_character.data.isClimbing) { float num3 = HelperFunctions.FlatDistance(_character.Center, GetGoalCenter()); return num3 <= 2f || num <= 1.8f; } return false; case PathActionType.GapJump: case PathActionType.DropDown: return num <= 1.8f && num2 <= 2f; case PathActionType.Hold: return true; default: return false; } } private bool IsSegmentFailed(PathPlan segment) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) float num = Time.time - _segmentStartTime; if (num < 1.2f) { return false; } float num2 = Vector3.Distance(_character.Center, _segmentStartPos); if (segment.Action == PathActionType.Climb) { float num3 = _character.Center.y - _segmentStartPos.y; if (num >= 3f && num3 < 0.35f && num2 < 0.8f) { return true; } return false; } float num4 = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f); float num5 = _segmentStartGoalDistance - num4; if (num >= 3f && num2 < 1f && num5 < 1f) { return true; } return false; } private List<PathPlan> BuildPathSegments() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) List<PathPlan> list = new List<PathPlan>(); if (!HasActiveGoal()) { return list; } Vector3 startPos = _character.Center; PathPlan a = new PathPlan(); bool flag = false; for (int i = 0; i < 4; i++) { PathPlan pathPlan = BuildPathPlanFrom(startPos); if (i == 0 && pathPlan.Action == PathActionType.None) { pathPlan = BuildPathPlanFrom(_character.Center); } if (pathPlan.Action == PathActionType.None || pathPlan.Action == PathActionType.Hold || (flag && !IsMeaningfullyDifferentSegment(a, pathPlan))) { break; } float failedSegmentPenalty = GetFailedSegmentPenalty(pathPlan); if (failedSegmentPenalty >= 3f && list.Count > 0) { break; } list.Add(pathPlan); if (pathPlan.Action == PathActionType.GapJump) { Vector3 goal = pathPlan.Goal; Vector3 goalCenter = GetGoalCenter(); if (goalCenter.y - goal.y > 1f) { PathPlan pathPlan2 = BuildPathPlanFrom(goal); if ((pathPlan2.Action == PathActionType.Climb || pathPlan2.Action == PathActionType.Detour || pathPlan2.Action == PathActionType.Direct) && list.Count < 4) { list.Add(pathPlan2); } } break; } if (pathPlan.Action == PathActionType.Detour) { float num = GetGoalCenter().y - pathPlan.Goal.y; if (num < -1.5f) { break; } } if (IsSegmentCloseToFinalGoal(pathPlan)) { break; } startPos = pathPlan.Goal; a = pathPlan; flag = true; } return list; } public bool Controls(MushroomZombie zombie) { return _initialized && (Object)(object)zombie == (Object)(object)_zombie; } private bool HasActiveGoal() { return (Object)(object)_target != (Object)null && _hasGoalPoint; } private Vector3 GetRawGoalCenter() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return _goalPoint; } private Vector3 GetGoalCenter() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return _hasResolvedGoalPoint ? _resolvedGoalPoint : _goalPoint; } private Vector3 GetCurrentMoveTarget() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (_hasActiveSegment) { return _activeSegment.Goal; } return GetGoalLookPoint(); } private bool IsMeaningfullyDifferentSegment(PathPlan a, PathPlan b) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (a.Action != b.Action) { return true; } float num = Vector3.Distance(a.Goal, b.Goal); float num2 = Vector3.Distance(a.Anchor, b.Anchor); if (num > 1.25f) { return true; } if (num2 > 1f) { return true; } return false; } private bool IsSegmentCloseToFinalGoal(PathPlan segment) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return true; } float num = HelperFunctions.FlatDistance(segment.Goal, GetGoalCenter()); float num2 = Mathf.Abs(segment.Goal.y - GetGoalCenter().y); return num <= 1.875f && num2 <= 2.625f; } private void ResetRouteProgressWindow() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) _routeWindowStartTime = Time.time; _routeWindowStartGoalDistance = (HasActiveGoal() ? Vector3.Distance(_character.Center, GetGoalCenter()) : 999f); } private bool IsRouteMakingNetProgress() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return true; } float num = Time.time - _routeWindowStartTime; if (num < 2.5f) { return true; } float num2 = Vector3.Distance(_character.Center, GetGoalCenter()); float num3 = _routeWindowStartGoalDistance - num2; return num3 >= 0.9f; } private Vector3 GetGoalLookPoint() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return GetGoalCenter() + Vector3.up * 0.15f; } private float GetGoalFlatDistance() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return 999f; } return HelperFunctions.FlatDistance(_character.Center, GetGoalCenter()); } private static PathPlan ClonePlan(PathPlan src) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) return new PathPlan { Action = src.Action, Goal = src.Goal, Anchor = src.Anchor, RequiredStamina = src.RequiredStamina, TargetAbove = src.TargetAbove, EstimatedClimbHeight = src.EstimatedClimbHeight, IsTallWall = src.IsTallWall, ExpectedDropHeight = src.ExpectedDropHeight, UsesJumpDropImmunity = src.UsesJumpDropImmunity, ReachableWithinRecoverableBudget = src.ReachableWithinRecoverableBudget, Score = src.Score, NeedsJumpStart = src.NeedsJumpStart, ClimbTopPoint = src.ClimbTopPoint, ClimbSurfaceNormal = src.ClimbSurfaceNormal, JumpGrabAimPoint = src.JumpGrabAimPoint, JumpGrabHorizontalDistance = src.JumpGrabHorizontalDistance }; } private PathPlan BuildHoldPlan(Vector3 goalLook, bool targetAbove) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return new PathPlan { Action = PathActionType.Hold, Goal = goalLook, Anchor = goalLook, TargetAbove = targetAbove }; } private bool TryCreateImmediateDropPlan(Vector3 startPos, Vector3 dir, float flatDist, RouteProbe probe, out PathPlan plan) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) plan = new PathPlan(); Vector3 anchor = startPos + dir * Mathf.Min(1f, flatDist); if (probe.SafeWalkDrop) { plan.Action = PathActionType.DropDown; plan.Goal = probe.DropLandingPoint; plan.Anchor = anchor; plan.TargetAbove = false; plan.RequiredStamina = 0.02f; plan.ExpectedDropHeight = probe.DropHeight; plan.UsesJumpDropImmunity = false; plan.ReachableWithinRecoverableBudget = true; plan.Score = 3f - probe.DropHeight * 0.04f; return true; } if (probe.SafeJumpDrop) { plan.Action = PathActionType.DropDown; plan.Goal = probe.DropLandingPoint; plan.Anchor = anchor; plan.TargetAbove = false; plan.RequiredStamina = 0.08f; plan.ExpectedDropHeight = probe.DropHeight; plan.UsesJumpDropImmunity = true; plan.ReachableWithinRecoverableBudget = true; plan.Score = 2.6f - probe.DropHeight * 0.03f; return true; } return false; } private void LockCurrentClimbPlan(PathPlan plan) { _lockedClimbPlan = ClonePlan(plan); _hasLockedClimbPlan = true; } private void ClearLockedClimbPlan() { _lockedClimbPlan = new PathPlan(); _hasLockedClimbPlan = false; } private PathPlan GetActiveClimbPlan() { if (_hasLockedClimbPlan) { return _lockedClimbPlan; } if (_hasActiveSegment) { return _activeSegment; } return _plan; } private float GetGoalVerticalDistance() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return 999f; } return Mathf.Abs(GetGoalCenter().y - _character.Center.y); } private bool HasArrivedAtGoal() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return false; } Vector3 val = _character.Center; if (TryFindGround(_character.Center, out var hit)) { val = ((RaycastHit)(ref hit)).point; } if (_rawGoalIsStandable) { float num = HelperFunctions.FlatDistance(val, _goalPoint); float num2 = Mathf.Abs(val.y - _goalPoint.y); return num <= 0.3f && num2 <= 0.3f; } if (_hasResolvedGoalPoint) { float num3 = HelperFunctions.FlatDistance(val, _resolvedGoalPoint); float num4 = Mathf.Abs(val.y - _resolvedGoalPoint.y); if (num3 <= 1.35f && num4 <= 2.25f) { return true; } } return false; } private float GetStamina01() { return Mathf.Clamp01(_character.GetTotalStamina()); } private float GetRecoverableStaminaCeiling() { return Mathf.Clamp(_character.GetMaxStamina() + _character.data.extraStamina, 0.05f, 1f); } private float EstimateGroundChaseCost(float distance) { return Mathf.Clamp(0.03f + distance * 0.01f, 0.03f, 0.25f); } private float GetClimbStartThreshold(PathPlan plan) { if (plan.EstimatedClimbHeight <= 1.2f) { return 0.4f; } if (plan.IsTallWall) { return 0.92f; } return 0.85f; } private bool IsClimbPlan(PathPlan plan) { return plan.Action == PathActionType.Climb || plan.Action == PathActionType.JumpGrab; } private bool HasEnoughStaminaToStartClimb(PathPlan plan) { if (!IsClimbPlan(plan)) { return true; } if (plan.Action == PathActionType.JumpGrab) { return GetStamina01() >= 0.92f; } return GetStamina01() >= GetClimbStartThreshold(plan); } private bool HasEnoughStaminaToResumeClimb(PathPlan plan) { if (!IsClimbPlan(plan)) { return true; } return GetStamina01() >= GetClimbStartThreshold(plan) + 0.02f; } private bool TryBuildJumpGrabPlanFrom(Vector3 startPos, Vector3 toTargetDir, bool targetAbove, out PathPlan plan) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) plan = new PathPlan(); if (!HasActiveGoal()) { return false; } Vector3 goalCenter = GetGoalCenter(); float num = HelperFunctions.FlatDistance(startPos, goalCenter); float num2 = goalCenter.y - startPos.y; if (num2 < 0.45f && num < 2.2f) { return false; } float[] array = new float[11] { 0f, 15f, -15f, 30f, -30f, 45f, -45f, 60f, -60f, 90f, -90f }; float[] array2 = new float[5] { 0.55f, 0.85f, 1.2f, 1.6f, 2f }; float[] array3 = new float[7] { 1.25f, 1.65f, 2.2f, 2.8f, 3.4f, 4f, 4.6f }; bool flag = false; float num3 = float.NegativeInfinity; PathPlan pathPlan = new PathPlan(); RaycastHit val2 = default(RaycastHit); RaycastHit val5 = default(RaycastHit); for (int i = 0; i < array.Length; i++) { Vector3 val = Quaternion.AngleAxis(array[i], Vector3.up) * toTargetDir; foreach (float num4 in array2) { Vector3 point = startPos + val * num4; if (!TryFindGround(point, out var hit)) { continue; } float num5 = Mathf.Abs(((RaycastHit)(ref hit)).point.y - startPos.y); if (num5 > 1.15f) { continue; } foreach (float num6 in array3) { if (num6 < num4 + 0.25f || !Physics.SphereCast(startPos + Vector3.up * 1.15f, 0.2f, val, ref val2, num6, TerrainMask, (QueryTriggerInteraction)1)) { continue; } Vector3 val3 = startPos + val * num6; Vector3 val4 = val3 + Vector3.up * 5.8f; if (!Physics.Raycast(val4, Vector3.down, ref val5, 6.8f, TerrainMask, (QueryTriggerInteraction)1)) { continue; } float num7 = ((RaycastHit)(ref val5)).point.y - startPos.y; if (num7 < 0.75f || num7 > 4.6f || Vector3.Angle(((RaycastHit)(ref val5)).normal, Vector3.up) > 60f) { continue; } Vector3 point2 = startPos + val * Mathf.Lerp(num4, num6, 0.35f); Vector3 point3 = startPos + val * Mathf.Lerp(num4, num6, 0.6f); bool flag2 = false; if (!TryFindGround(point2, out var hit2)) { flag2 = true; } else { float num8 = startPos.y - ((RaycastHit)(ref hit2)).point.y; if (num8 > 10f) { flag2 = true; } } if (!flag2) { if (!TryFindGround(point3, out var hit3)) { flag2 = true; } else { float num9 = startPos.y - ((RaycastHit)(ref hit3)).point.y; if (num9 > 10f) { flag2 = true; } } } float num10 = HelperFunctions.FlatDistance(((RaycastHit)(ref val5)).point, goalCenter); float num11 = HelperFunctions.FlatDistance(startPos, goalCenter) - num10; float num12 = Mathf.Abs(((RaycastHit)(ref val5)).point.y - goalCenter.y); bool flag3 = num10 <= 1.45f && num12 <= 1.9f; if ((flag3 || !(num11 < 0.55f)) && (flag2 || targetAbove || flag3)) { PathPlan obj = new PathPlan { Action = PathActionType.JumpGrab, Anchor = ((RaycastHit)(ref hit)).point, Goal = goalCenter + Vector3.up * 0.15f, JumpGrabAimPoint = ((RaycastHit)(ref val2)).point + Vector3.up * 0.25f, JumpGrabHorizontalDistance = num6, TargetAbove = true, EstimatedClimbHeight = num7, IsTallWall = (num7 >= 2.15f), RequiredStamina = EstimateRequiredClimbStamina(num7, targetAbove: true, num7 >= 2.15f), ReachableWithinRecoverableBudget = true, NeedsJumpStart = true, ClimbTopPoint = ((RaycastHit)(ref val5)).point }; Vector3 normal = ((RaycastHit)(ref val2)).normal; Vector3 climbSurfaceNormal; if (!(((Vector3)(ref normal)).sqrMagnitude > 0.01f)) { climbSurfaceNormal = -val; } else { normal = ((RaycastHit)(ref val2)).normal; climbSurfaceNormal = ((Vector3)(ref normal)).normalized; } obj.ClimbSurfaceNormal = climbSurfaceNormal; PathPlan pathPlan2 = obj; float num13 = (pathPlan2.Score = num11 * 2.4f + (flag3 ? 3.2f : 0f) + (flag2 ? 1.2f : 0f) - Mathf.Abs(array[i]) * 0.025f - num6 * 0.06f - GetBlockedPenalty(((RaycastHit)(ref hit)).point) - GetFailedSegmentPenalty(pathPlan2)); if (!flag || num13 > num3) { flag = true; num3 = num13; pathPlan = pathPlan2; } } } } } if (flag) { plan = pathPlan; return true; } return false; } private bool IsNearClimbAnchor(PathPlan plan) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!IsClimbPlan(plan)) { return false; } return Vector3.Distance(_character.Center, plan.Anchor) <= 1.35f; } public void Tick() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Invalid comparison between Unknown and I4 if (!_initialized || (Object)(object)_zombie == (Object)null || (Object)(object)_character == (Object)null || (Object)(object)_character.data == (Object)null || (Object)(object)_view == (Object)null) { return; } UpdateInteractionState(); if (!_view.IsMine) { TickRemoteVisualOnly(); return; } KeepZombiePersistent(); if (_brainState == ZombieBrainState.Dead || (int)_zombie.currentState == 6) { _brainState = ZombieBrainState.Dead; _zombie.currentState = (State)6; return; } if (suppressZombieAI) { TickSuppressedByInteraction(); SyncVisualState(); return; } ResetInput(); RefreshTargetIfNeeded(); RefreshResolvedGoalIfNeeded(); ValidateTarget(); DecayBlockedMemory(); UpdateStuckDetection(); UpdateClimbFailureDetection(); if (!HasActiveGoal()) { _brainState = ZombieBrainState.Idle; } else if (!IsFollowingRoute() && HasArrivedAtGoal()) { _brainState = ZombieBrainState.Idle; } switch (_brainState) { case ZombieBrainState.Idle: TickIdle(); break; case ZombieBrainState.Chase: TickChase(); break; case ZombieBrainState.PrepareTallClimb: TickPrepareTallClimb(); break; case ZombieBrainState.Reposition: TickReposition(); break; case ZombieBrainState.Lunge: TickLunge(); break; case ZombieBrainState.LungeRecovery: TickLungeRecovery(); break; case ZombieBrainState.Dead: _zombie.currentState = (State)6; break; } LogBrainStateIfChanged(); SyncVisualState(); } private void TickRemoteVisualOnly() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 UpdateInteractionState(); if (suppressZombieAI) { _zombie.currentState = (State)2; _character.data.passedOut = false; } if ((int)_zombie.currentState == 6 || (int)_zombie.currentState == 0) { _character.data.passedOut = true; } _zombie.SetBiteColliderProxy((int)_zombie.currentState == 4); _zombie.UpdateMouthProxy(); } private void KeepZombiePersistent() { _zombie.isNPCZombie = false; _zombie.spawner = null; _zombie.lifetime = 999999f; if ((Object)(object)ZombieManager.Instance != (Object)null) { ZombieManager.Instance.DeRegisterZombie(_zombie); } if ((Object)(object)_character != (Object)null) { _character.isZombie = true; _character.isBot = false; _character.data.dead = false; _character.data.passedOut = false; _character.data.fullyPassedOut = false; } } private void TickIdle() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) _zombie.currentState = (State)2; _character.data.passedOut = false; SetSprint(sprinting: false); if (HasActiveGoal()) { LookAt(GetCurrentDrivePoint()); _brainState = ZombieBrainState.Chase; _timeInChase = 0f; } } private void TickChase() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { ClearLockedClimbPlan(); _segmentQueue.Clear(); ClearActiveSegment(); _brainState = ZombieBrainState.Idle; _zombie.currentState = (State)2; return; } _zombie.currentState = (State)3; _character.data.passedOut = false; _timeInChase += Time.deltaTime; if (CanSeeGoal()) { _lastSeenTargetTime = Time.time; } if (!IsFollowingRoute() && HasArrivedAtGoal()) { _zombie.currentState = (State)2; _character.data.passedOut = false; SetSprint(sprinting: false); _character.input.movementInput = Vector2.zero; if (_resolvedGoalIsStandable && _character.data.isClimbing) { StopClimb(); } ClearLockedClimbPlan(); _brainState = ZombieBrainState.Idle; return; } if (_character.data.isClimbing) { if (!_hasLockedClimbPlan) { if (_hasActiveSegment && _activeSegment.Action == PathActionType.Climb) { LockCurrentClimbPlan(_activeSegment); } else if (_plan.Action == PathActionType.Climb) { LockCurrentClimbPlan(_plan); } } TickActiveClimb(); return; } if (!_hasActiveSegment && _segmentQueue.Count == 0) { ReplanRoute(); } AdvanceSegmentIfNeeded(); if (!_hasActiveSegment && _segmentQueue.Count == 0) { ReplanRoute(); } if (_hasActiveSegment) { ExecuteActiveSegment(); return; } ClearLockedClimbPlan(); PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center)); if (IsClimbPlan(pathPlan) && !HasEnoughStaminaToStartClimb(pathPlan)) { if (!IsNearClimbAnchor(pathPlan)) { LookAt(pathPlan.Anchor); WalkTowards(pathPlan.Anchor, 0.8f, tryClimb: false, tryJump: false, sprintRequested: false); } else { EnterPrepareTallClimb(); } } else if (_stuckCount >= 2 || _failedClimbCount >= 3) { RegisterBlockedPoint(_character.Center, 3.2f); EnterReposition(); } else { ExecuteGroundPlan(pathPlan); } } private void TickPrepareTallClimb() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) _zombie.currentState = (State)2; _character.data.passedOut = false; SetSprint(sprinting: false); if (!HasActiveGoal()) { _brainState = ZombieBrainState.Idle; return; } PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center)); if (!IsClimbPlan(pathPlan)) { _brainState = ZombieBrainState.Chase; return; } float num = Vector3.Distance(_character.Center, pathPlan.Anchor); bool flag = HasEnoughStaminaToResumeClimb(pathPlan); bool flag2 = num <= 1.35f; LookAt(flag2 ? pathPlan.Goal : pathPlan.Anchor); if (!flag2) { WalkTowards(pathPlan.Anchor, 0.7f, tryClimb: false, tryJump: false, sprintRequested: false); } else if (!flag) { _character.input.movementInput = Vector2.zero; SetSprint(sprinting: false); } else { WalkTowards(pathPlan.Goal, 0.95f, tryClimb: true, tryJump: false, sprintRequested: false); TryForceJumpGrab(pathPlan, closeToAnchor: true); _brainState = ZombieBrainState.Chase; } } private void TickReposition() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) _zombie.currentState = (State)2; _character.data.passedOut = false; if (!HasActiveGoal()) { _brainState = ZombieBrainState.Idle; return; } PathPlan pathPlan = (_plan = BuildPathPlanFrom(_character.Center)); bool flag = Time.time < _repositionUntil; if (pathPlan.Action == PathActionType.Detour) { LookAt(pathPlan.Goal); WalkTowards(pathPlan.Goal, 1f, tryClimb: false, tryJump: false, sprintRequested: false); TryTravelHop(); if (!flag && Vector3.Distance(_character.Center, pathPlan.Goal) < 1.2f) { _stuckCount = 0; _failedClimbCount = 0; _brainState = ZombieBrainState.Chase; } } else if (!flag && (pathPlan.Action == PathActionType.Direct || pathPlan.Action == PathActionType.Climb || pathPlan.Action == PathActionType.GapJump || pathPlan.Action == PathActionType.DropDown)) { _stuckCount = 0; _failedClimbCount = 0; _brainState = ZombieBrainState.Chase; } else { LookAt(GetCurrentMoveTarget()); WalkTowards(GetGoalLookPoint(), 0.7f, tryClimb: false, tryJump: false, sprintRequested: false); } } private void TickLunge() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) _zombie.currentState = (State)4; _character.data.passedOut = false; _timeInLunge += Time.deltaTime; if (HasActiveGoal()) { Vector3 targetPos = _character.Center + (GetGoalLookPoint() - _character.Center) * 100f; WalkTowards(targetPos, 1.2f, tryClimb: false, tryJump: false, sprintRequested: true); } if (_timeInLunge >= _zombie.lungeTime || _character.OutOfStamina()) { _timeInLunge = 0f; _brainState = ZombieBrainState.LungeRecovery; _zombie.currentState = (State)5; _character.Fall(3f, 0f); ForcePushState(); } } private void TickLungeRecovery() { _zombie.currentState = (State)5; _character.data.passedOut = false; if (!(_character.data.fallSeconds > 0f) && !_character.data.passedOut && !_character.data.fullyPassedOut) { _timeInLunge += Time.deltaTime; if (_timeInLunge >= _zombie.lungeRecoveryTime) { _timeInLunge = 0f; _brainState = ZombieBrainState.Chase; } } } private void TickActiveClimb() { //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { StopClimb(); ClearLockedClimbPlan(); _brainState = ZombieBrainState.Idle; return; } PathPlan activeClimbPlan = GetActiveClimbPlan(); if (_climbTimer > 0.45f && !CanContinueClimb(activeClimbPlan)) { StopClimb(); if (activeClimbPlan.Action == PathActionType.Climb || activeClimbPlan.Action == PathActionType.JumpGrab) { EnterPrepareTallClimb(); return; } RegisterBlockedPoint(_character.Center, 2.6f); EnterReposition(); return; } if (_resolvedGoalIsStandable) { float num = HelperFunctions.FlatDistance(_character.Center, _resolvedGoalPoint); float num2 = _resolvedGoalPoint.y - _character.Center.y; if (_climbTimer > 0.8f && num <= 1.4f && num2 <= 0.9f) { StopClimb(); ClearLockedClimbPlan(); LookAt(_resolvedGoalPoint); _character.input.movementInput = new Vector2(0f, 1f); SetSprint(sprinting: false); return; } } Vector3 val = ((activeClimbPlan.ClimbTopPoint != Vector3.zero) ? activeClimbPlan.ClimbTopPoint : GetGoalLookPoint()); Vector2 val2 = ComputeStrategicClimbInput(val, activeClimbPlan); float num3 = Mathf.Max(activeClimbPlan.EstimatedClimbHeight, 0.1f); float num4 = Mathf.Clamp01((_character.Center.y - _climbStartHeight) / num3); float stamina = GetStamina01(); bool flag = activeClimbPlan.ClimbTopPoint != Vector3.zero && Vector3.Distance(_character.Center, activeClimbPlan.ClimbTopPoint) < 1.25f; bool flag2 = stamina <= 0.05f && stamina >= 0.01f && num4 >= 0.35f; bool flag3 = flag || num4 >= 0.55f; bool flag4 = (activeClimbPlan.Action == PathActionType.Climb || activeClimbPlan.Action == PathActionType.JumpGrab) && (flag3 || flag2) && stamina >= 0.01f; LookAt(val); SetSprint(sprinting: false); _character.input.movementInput = val2; if (flag4) { _character.input.sprintIsPressed = true; _character.input.movementInput = new Vector2(Mathf.Clamp(val2.x * 1.15f, -1f, 1f), Mathf.Clamp(val2.y * 1.12f, 0.82f, 1f)); } if (GetGoalCenter().y < _character.Center.y) { RaycastHit val3 = HelperFunctions.LineCheck(_character.Center, GetGoalCenter(), (LayerType)1, 0f, (QueryTriggerInteraction)1); bool flag5 = (Object)(object)((RaycastHit)(ref val3)).transform == (Object)null; float num5 = HelperFunctions.FlatDistance(_character.Center, GetGoalCenter()); bool flag6 = _climbTimer > 0.8f; if (flag5 && flag6 && num5 < 1.8f && GetGoalCenter().y - _character.Center.y < -1f) { StopClimb(); ClearLockedClimbPlan(); SetSprint(sprinting: false); } } } private bool TryBuildObstacleBypassPlanFrom(Vector3 startPos, Vector3 toTargetDir, float currentFlatDist, bool targetAbove, out PathPlan plan) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) plan = new PathPlan(); if (!HasActiveGoal()) { return false; } if (!TryProbeRouteFrom(startPos, toTargetDir, 2.2f, out var probe)) { return false; } if ((!probe.ObstacleAhead || probe.ClimbableAhead) && !probe.UnsafeDropAhead) { return false; } bool flag = false; float num = float.NegativeInfinity; PathPlan pathPlan = new PathPlan(); float[] array = new float[9] { 0f, 18f, -18f, 35f, -35f, 55f, -55f, 75f, -75f }; foreach (float num2 in array) { Vector3 val = Quaternion.AngleAxis(num2, Vector3.up) * toTargetDir; if (!TryProbeRouteFrom(startPos, val, 2.2f, out var probe2)) { continue; } float blockedPenalty = GetBlockedPenalty(startPos + val * 2.2f); float num3 = Mathf.Abs(num2) * 0.018f; if (probe2.GapJumpable) { float num4 = HelperFunctions.FlatDistance(probe2.GapLandingPoint, GetGoalCenter()); float num5 = currentFlatDist - num4; if (num5 >= 0.55f) { PathPlan pathPlan2 = new PathPlan { Action = PathActionType.GapJump, Goal = probe2.GapLandingPoint, Anchor = startPos + val * Mathf.Clamp(Mathf.Max(0.9f, probe2.ObstacleAhead ? (probe2.ObstacleDistance - 0.2f) : 1f), 0.9f, 1.45f), TargetAbove = targetAbove, RequiredStamina = Mathf.Clamp(0.18f + probe2.GapLandingDrop * 0.04f, 0.18f, 0.5f), ReachableWithinRecoverableBudget = true }; float num6 = num5 * 2.1f + 1.15f - num3 - blockedPenalty - GetFailedSegmentPenalty(pathPlan2); if (Mathf.Abs(num2) <= 18f) { num6 += 0.25f; } pathPlan2.Score = num6; if (!flag || num6 > num) { flag = true; num = num6; pathPlan = pathPlan2; } } } Vector3 point = startPos + val * 3f; if (!TryFindGround(point, out var hit)) { continue; } float num7 = startPos.y - ((RaycastHit)(ref hit)).point.y; if (num7 <= 10f) { float num8 = HelperFunctions.FlatDistance(((RaycastHit)(ref hit)).point, GetGoalCenter()); float num9 = currentFlatDist - num8; RaycastHit val2 = HelperFunctions.LineCheck(startPos + Vector3.up * 0.15f, ((RaycastHit)(ref hit)).point + Vector3.up * 0.15f, (LayerType)1, 0f, (QueryTriggerInteraction)1); bool flag2 = (Object)(object)((RaycastHit)(ref val2)).transform != (Object)null; float num10 = num9 + 0.75f - num3 - blockedPenalty - (flag2 ? 0.65f : 0f); PathPlan pathPlan3 = new PathPlan { Action = PathActionType.Detour, Goal = ((RaycastHit)(ref hit)).point, Anchor = ((RaycastHit)(ref hit)).point, TargetAbove = targetAbove, RequiredStamina = EstimateGroundChaseCost(Vector3.Distance(startPos, ((RaycastHit)(ref hit)).point)), ReachableWithinRecoverableBudget = true }; num10 = (pathPlan3.Score = num10 - GetFailedSegmentPenalty(pathPlan3)); if (!flag || num10 > num) { flag = true; num = num10; pathPlan = pathPlan3; } } } if (flag) { plan = pathPlan; return true; } return false; } private void ExecuteGroundPlan(PathPlan plan) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Unknown result type (might be due to invalid IL or missing references) //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) switch (plan.Action) { case PathActionType.Direct: { LookAt(plan.Goal); float num = (HasActiveGoal() ? HelperFunctions.FlatDistance(_character.Center, GetGoalCenter()) : 999f); float num2 = (HasActiveGoal() ? Mathf.Abs(GetGoalCenter().y - _character.Center.y) : 999f); bool flag = num <= 1.65f && num2 <= 1.15f; bool sprintRequested = ((!flag) ? ShouldAggressiveSprint() : (num > 0.9f && GetStamina01() > 0.05f)); bool tryJump = !flag || ShouldHopSmallObstacleTowards(plan.Goal); WalkTowards(plan.Goal, flag ? 0.85f : 1f, tryClimb: true, tryJump, sprintRequested); if (!flag) { TryTravelHop(); } break; } case PathActionType.Detour: { LookAt(plan.Goal); bool sprintRequested2 = Vector3.Distance(_character.Center, plan.Goal) > 4f || ShouldAggressiveSprint(); bool tryJump2 = ShouldHopSmallObstacleTowards(plan.Goal); WalkTowards(plan.Goal, 1f, tryClimb: false, tryJump2, sprintRequested2); TryTravelHop(); break; } case PathActionType.Climb: { float num6 = Vector3.Distance(_character.Center, plan.Anchor); bool flag3 = num6 <= 1.35f; Vector3 val2 = (flag3 ? plan.Goal : plan.Anchor); if (!HasEnoughStaminaToStartClimb(plan)) { LookAt(flag3 ? plan.Anchor : val2); if (!flag3) { WalkTowards(plan.Anchor, 0.75f, tryClimb: false, tryJump: false, sprintRequested: false); break; } _character.input.movementInput = Vector2.zero; SetSprint(sprinting: false); } else { LookAt(val2); bool flag4 = !flag3 && num6 > 1.8f && ShouldAggressiveSprint(); WalkTowards(val2, flag3 ? 0.95f : 1f, tryClimb: true, tryJump: false, flag4 && !flag3); TryForceJumpGrab(plan, flag3); } break; } case PathActionType.JumpGrab: { float num5 = Vector3.Distance(_character.Center, plan.Anchor); bool flag2 = num5 <= 1.15f; Vector3 lookAtPos = ((plan.JumpGrabAimPoint != Vector3.zero) ? plan.JumpGrabAimPoint : plan.Goal); if (!flag2) { LookAt(plan.Anchor); bool sprintRequested4 = num5 > 2f && ShouldAggressiveSprint(); bool tryClimb = num5 <= 1.85f; WalkTowards(plan.Anchor, 1f, tryClimb, ShouldHopSmallObstacleTowards(plan.Anchor), sprintRequested4); break; } if (!HasEnoughStaminaToStartClimb(plan)) { LookAt(lookAtPos); _character.input.movementInput = Vector2.zero; SetSprint(sprinting: false); break; } LookAt(lookAtPos); _character.input.movementInput = new Vector2(0f, 1f); SetSprint(sprinting: false); _character.refs.climbing.TryClimb(1.6f); if (_character.data.isGrounded && Time.time - _lastAutoJumpTime >= 0.2f) { _character.input.jumpWasPressed = true; _lastAutoJumpTime = Time.time; } break; } case PathActionType.GapJump: { LookAt(plan.Goal); float num3 = Vector3.Distance(_character.Center, plan.Anchor); if (num3 > 1.15f) { WalkTowards(plan.Anchor, 1f, tryClimb: false, tryJump: false, sprintRequested: true); break; } SetSprint(sprinting: true); _character.input.movementInput = new Vector2(0f, 1f); LookAt(plan.Goal); if (_character.data.isGrounded && GetStamina01() >= plan.RequiredStamina) { _character.input.jumpWasPressed = true; _lastAutoJumpTime = Time.time; } break; } case PathActionType.DropDown: { LookAt(plan.Goal); float num4 = Vector3.Distance(_character.Center, plan.Anchor); if (num4 > 1.1f) { bool sprintRequested3 = ShouldAggressiveSprint(); WalkTowards(plan.Anchor, 1f, tryClimb: false, tryJump: false, sprintRequested3); } else if (plan.UsesJumpDropImmunity) { SetSprint(sprinting: true); _character.input.jumpWasPressed = true; _lastAutoJumpTime = Time.time; } else { SetSprint(sprinting: false); _character.input.movementInput = new Vector2(0f, 1f); } break; } default: { Vector3 val = (HasActiveGoal() ? GetGoalLookPoint() : _character.Head); LookAt(val); WalkTowards(val, 0.7f, tryClimb: false, tryJump: false, sprintRequested: false); break; } } } private bool ShouldAggressiveSprint() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveGoal()) { return false; } if (!_character.CheckSprint()) { return false; } float num = Vector3.Distance(_character.Center, GetGoalCenter()); if (_timeInChase > _zombie.chaseTimeBeforeSprint && num > 3f) { return true; } if (Time.time - _lastS