using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using HarmonyLib.Public.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using PathfindingLagFix.Patches; using PathfindingLagFix.Utilities; using PathfindingLagFix.Utilities.IL; using PathfindingLib.API; using PathfindingLib.Jobs; using PathfindingLib.Utilities; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Netcode; using Unity.Profiling; using Unity.Profiling.LowLevel; using Unity.Profiling.LowLevel.Unsafe; using UnityEngine; using UnityEngine.AI; using UnityEngine.Experimental.AI; using UnityEngine.SceneManagement; using UnityEngine.Scripting; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PathfindingLagFix")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PathfindingLagFix")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("fedb984b-16ae-458c-b2cc-19590627c578")] [assembly: AssemblyFileVersion("2.4.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.0.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] internal sealed class IsUnmanagedAttribute : Attribute { } [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 PathfindingLagFix { internal struct ConfigOptions { private enum ConfigPreset { OnlyFixes, Vanilla } private static readonly ConfigOptions OnlyFixesPreset = new ConfigOptions { DistancePathfindingFallbackNodeSelection = DistancePathfindingFallbackNodeSelectionType.BestPathable }; private static readonly ConfigOptions VanillaPreset = new ConfigOptions { DistancePathfindingFallbackNodeSelection = DistancePathfindingFallbackNodeSelectionType.Vanilla }; internal static ConfigOptions CurrentOptions = OnlyFixesPreset; private const string presetDescription = "Select a preset to use as defaults for all options that change gameplay.\n\nOnlyFixes: Options that are intended to act solely as bug fixes and should retain the intention of the original code.\nVanilla: Options that completely match vanilla as much as possible."; private static ConfigEntry presetOption; private const string distancePathfindingFallbackNodeSelectionDescription = "How nodes should be selected if the criteria for a distance based pathfinding operation (i.e. bracken evasion) fails.\n\nUsePreset: Use the option selected by the current preset.\nBestPathable: The enemy will go to the furthest/closest node that can be reached. This is the old behavior of PathfindingLagFix, and it guarantees the bracken will not get stuck when spotted.\nVanilla: The enemy will attempt to go to the furthest/closest node, regardless of whether it can be reached. This will cause brackens to sometimes stutter step towards the furthest position instead of moving smoothly.\nDontMove: The enemy will not move until it has a valid path to follow. For the bracken, this will result in it standing still and looking at the player until they look away."; private static ConfigEntry distancePathfindingFallbackNodeSelectionOption; internal DistancePathfindingFallbackNodeSelectionType DistancePathfindingFallbackNodeSelection; internal static void BindAllOptions(ConfigFile file) { presetOption = BindOption(file, "General", "Preset", ConfigPreset.OnlyFixes, "Select a preset to use as defaults for all options that change gameplay.\n\nOnlyFixes: Options that are intended to act solely as bug fixes and should retain the intention of the original code.\nVanilla: Options that completely match vanilla as much as possible."); distancePathfindingFallbackNodeSelectionOption = BindOption(file, "Behavior", "DistancePathfindingFallbackNodeSelection", DistancePathfindingFallbackNodeSelectionType.UsePreset, "How nodes should be selected if the criteria for a distance based pathfinding operation (i.e. bracken evasion) fails.\n\nUsePreset: Use the option selected by the current preset.\nBestPathable: The enemy will go to the furthest/closest node that can be reached. This is the old behavior of PathfindingLagFix, and it guarantees the bracken will not get stuck when spotted.\nVanilla: The enemy will attempt to go to the furthest/closest node, regardless of whether it can be reached. This will cause brackens to sometimes stutter step towards the furthest position instead of moving smoothly.\nDontMove: The enemy will not move until it has a valid path to follow. For the bracken, this will result in it standing still and looking at the player until they look away."); UpdateCurrentOptions(); } private static ConfigEntry BindOption(ConfigFile file, string section, string key, T defaultValue, string description) { ConfigEntry obj = file.Bind(section, key, defaultValue, description); obj.SettingChanged += delegate { UpdateCurrentOptions(); }; return obj; } private static void UpdateCurrentOptions() { CurrentOptions = presetOption.Value switch { ConfigPreset.OnlyFixes => OnlyFixesPreset, ConfigPreset.Vanilla => VanillaPreset, _ => throw new InvalidOperationException($"Unknown preset {presetOption.Value}"), }; if (distancePathfindingFallbackNodeSelectionOption.Value != 0) { CurrentOptions.DistancePathfindingFallbackNodeSelection = distancePathfindingFallbackNodeSelectionOption.Value; } Plugin.Instance.Logger.LogInfo((object)string.Format("{0} {1} is using preset {2} with options:", "Zaggy1024.PathfindingLagFix", "2.4.0", presetOption.Value)); Plugin.Instance.Logger.LogInfo((object)string.Format(" {0} = {1} ({2})", "DistancePathfindingFallbackNodeSelection", CurrentOptions.DistancePathfindingFallbackNodeSelection, distancePathfindingFallbackNodeSelectionOption.Value)); } } internal enum DistancePathfindingFallbackNodeSelectionType { UsePreset, BestPathable, Vanilla, DontMove } [BepInPlugin("Zaggy1024.PathfindingLagFix", "PathfindingLagFix", "2.4.0")] [BepInDependency("Zaggy1024.PathfindingLib", "2.3.0")] public class Plugin : BaseUnityPlugin { public const string MOD_NAME = "PathfindingLagFix"; public const string MOD_UNIQUE_NAME = "Zaggy1024.PathfindingLagFix"; public const string MOD_VERSION = "2.4.0"; private readonly Harmony harmony = new Harmony("Zaggy1024.PathfindingLagFix"); public static Plugin Instance { get; private set; } public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; public void Awake() { Instance = this; ConfigOptions.BindAllOptions(((BaseUnityPlugin)this).Config); harmony.PatchAll(typeof(PatchEnemyAI)); harmony.PatchAll(typeof(PatchFlowermanAI)); harmony.PatchAll(typeof(PatchCentipedeAI)); harmony.PatchAll(typeof(PatchPufferAI)); harmony.PatchAll(typeof(PatchDoublewingAI)); harmony.PatchAll(typeof(PatchFlowerSnakeEnemy)); harmony.PatchAll(typeof(PatchSpringManAI)); harmony.PatchAll(typeof(PatchBlobAI)); harmony.PatchAll(typeof(PatchCaveDwellerAI)); harmony.PatchAll(typeof(PatchStingrayAI)); PatchFindMainEntrance.ApplyPatches(harmony); } } } namespace PathfindingLagFix.Utilities { internal struct AssignGroundCastPointsAsDestinationsJob : IJobFor { [ReadOnly] private NativeArray Hits; [WriteOnly] private NativeArray Destinations; public void Initialize(NativeArray hits, NativeArray points) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Hits = hits; Destinations = points; } public void Execute(int index) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = Hits[index]; if (((RaycastHit)(ref val)).colliderInstanceID == 0) { Destinations[index] = FindPathsToNodesJob.INVALID_DESTINATION; return; } ref NativeArray destinations = ref Destinations; val = Hits[index]; destinations[index] = ((RaycastHit)(ref val)).point; } } internal static class AsyncDistancePathfinding { internal class EnemyDistancePathfindingStatus { public Coroutine Coroutine; public int CurrentSearchTypeID = -1; public GameObject[] AINodes; public Transform[] SortedNodes; public Vector3[] SortedPositions; public FindPathsToNodesJob Job; public JobHandle JobHandle; public Transform ChosenNode; public float MostOptimalDistance = float.PositiveInfinity; public void SortNodes(EnemyAI enemy, Vector3 target, bool furthestFirst) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) int num = enemy.allAINodes.Length; if (enemy.allAINodes != AINodes) { AINodes = enemy.allAINodes; SortedNodes = (Transform[])(object)new Transform[num]; SortedPositions = (Vector3[])(object)new Vector3[num]; for (int i = 0; i < num; i++) { Transform transform = AINodes[i].transform; SortedNodes[i] = transform; SortedPositions[i] = transform.position; } } for (int j = 1; j < num; j++) { Vector3 val = SortedPositions[j] - target; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; for (int num2 = j; num2 > 0; num2--) { val = SortedPositions[num2 - 1] - target; if ((((Vector3)(ref val)).sqrMagnitude <= sqrMagnitude) ^ furthestFirst) { break; } Swap(ref SortedNodes[num2 - 1], ref SortedNodes[num2]); Swap(ref SortedPositions[num2 - 1], ref SortedPositions[num2]); } } static void Swap(ref T a, ref T b) { T val2 = b; T val3 = a; a = val2; b = val3; } } public Transform RetrieveChosenNode(out float mostOptimalDistance) { Transform chosenNode = ChosenNode; mostOptimalDistance = MostOptimalDistance; if ((Object)(object)chosenNode == (Object)null) { return null; } ChosenNode = null; MostOptimalDistance = float.PositiveInfinity; CurrentSearchTypeID = -1; return chosenNode; } ~EnemyDistancePathfindingStatus() { Job.FreeAllResources(); } } internal delegate IEnumerator NodeSelectionCoroutine(EnemyDistancePathfindingStatus status); [CompilerGenerated] private sealed class d__10 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EnemyAI enemy; public EnemyDistancePathfindingStatus status; public Vector3 target; public bool farthestFirst; public float capDistance; public int offset; public bool avoidLineOfSight; private int 5__2; private FindPathsToNodesJob 5__3; private JobHandle 5__4; private int 5__5; private float 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Invalid comparison between Unknown and I4 //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Invalid comparison between Unknown and I4 //IL_019b: 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_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (enemy.allAINodes.Length == 0 || !enemy.agent.isOnNavMesh) { status.ChosenNode = ((Component)enemy).transform; status.MostOptimalDistance = 0f; return false; } 5__2 = enemy.allAINodes.Length; StartJobs(enemy, status, target, 5__2, farthestFirst); 5__3 = status.Job; 5__4 = status.JobHandle; 5__5 = -1; 5__6 = capDistance * capDistance; goto IL_01e4; case 1: { <>1__state = -1; bool flag = true; int num = Math.Min(offset, 5__2 - 1); Vector3 position = ((Component)enemy).transform.position; for (int i = 0; i < 5__2; i++) { if (5__6 > 0f) { Vector3 val = status.SortedPositions[i] - position; if (((Vector3)(ref val)).sqrMagnitude > 5__6) { continue; } } PathQueryStatus val2 = 5__3.Statuses[i]; if ((int)PathQueryStatusExtensions.GetResult(val2) == 536870912) { flag = false; break; } if ((int)PathQueryStatusExtensions.GetResult(val2) == 1073741824) { NativeArray path = 5__3.GetPath(i); if ((!avoidLineOfSight || !LineOfSight.PathIsBlockedByLineOfSight(path)) && num-- == 0) { 5__5 = i; break; } } } if (!flag) { goto IL_01e4; } goto IL_01f0; } case 2: { <>1__state = -1; break; } IL_01e4: if (5__5 == -1) { <>2__current = null; <>1__state = 1; return true; } goto IL_01f0; IL_01f0: 5__3.Cancel(); if (5__5 == -1) { switch (ConfigOptions.CurrentOptions.DistancePathfindingFallbackNodeSelection) { case DistancePathfindingFallbackNodeSelectionType.BestPathable: { for (int j = 0; j < 5__2; j++) { if ((int)PathQueryStatusExtensions.GetResult(5__3.Statuses[j]) == 1073741824) { 5__5 = j; break; } } break; } case DistancePathfindingFallbackNodeSelectionType.Vanilla: 5__5 = 0; break; } } if (5__5 == -1) { status.ChosenNode = ((Component)enemy).transform; status.MostOptimalDistance = 0f; } else { status.ChosenNode = status.SortedNodes[5__5]; status.MostOptimalDistance = Vector3.Distance(target, status.SortedPositions[5__5]); } break; } if (!((JobHandle)(ref 5__4)).IsCompleted) { <>2__current = null; <>1__state = 2; return true; } status.Coroutine = null; 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(); } } internal const float DEFAULT_CAP_DISTANCE = 40f; private static readonly EnemyMap Statuses = new EnemyMap(() => new EnemyDistancePathfindingStatus()); internal static void RemoveStatus(EnemyAI enemy) { Statuses.Remove(enemy); } internal static EnemyDistancePathfindingStatus StartJobs(EnemyAI enemy, EnemyDistancePathfindingStatus status, Vector3 target, int count, bool farthestFirst, bool calculateDistance = false) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) NavMeshAgent agent = enemy.agent; status.SortNodes(enemy, target, farthestFirst); ref FindPathsToNodesJob job = ref status.Job; job.Initialize(agent, status.SortedPositions, calculateDistance); status.JobHandle = IJobForExtensions.ScheduleByRef(ref job, count, default(JobHandle)); return status; } internal static EnemyDistancePathfindingStatus StartChoosingNode(EnemyAI enemy, int searchTypeID, NodeSelectionCoroutine coroutine) { EnemyDistancePathfindingStatus enemyDistancePathfindingStatus = Statuses[enemy]; if (enemyDistancePathfindingStatus.CurrentSearchTypeID == searchTypeID) { return enemyDistancePathfindingStatus; } if (enemyDistancePathfindingStatus.Coroutine != null) { enemyDistancePathfindingStatus.Job.Cancel(); return enemyDistancePathfindingStatus; } enemyDistancePathfindingStatus.RetrieveChosenNode(out var _); enemyDistancePathfindingStatus.CurrentSearchTypeID = searchTypeID; enemyDistancePathfindingStatus.Coroutine = ((MonoBehaviour)enemy).StartCoroutine(coroutine(enemyDistancePathfindingStatus)); return enemyDistancePathfindingStatus; } private static EnemyDistancePathfindingStatus StartChoosingNode(EnemyAI enemy, int searchTypeID, Vector3 target, bool farthestFirst, bool avoidLineOfSight, int offset, float capDistance) { //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) return StartChoosingNode(enemy, searchTypeID, (EnemyDistancePathfindingStatus status) => ChooseNodeCoroutine(enemy, status, target, farthestFirst, avoidLineOfSight, offset, capDistance)); } internal static EnemyDistancePathfindingStatus StartChoosingFarthestNodeFromPosition(EnemyAI enemy, int searchTypeID, Vector3 target, bool avoidLineOfSight = false, int offset = 0, float capDistance = 0f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return StartChoosingNode(enemy, searchTypeID, target, farthestFirst: true, avoidLineOfSight, offset, capDistance); } internal static EnemyDistancePathfindingStatus StartChoosingClosestNodeToPosition(EnemyAI enemy, int searchTypeID, Vector3 target, bool avoidLineOfSight = false, int offset = 0, float capDistance = 0f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return StartChoosingNode(enemy, searchTypeID, target, farthestFirst: false, avoidLineOfSight, offset, capDistance); } [IteratorStateMachine(typeof(d__10))] internal static IEnumerator ChooseNodeCoroutine(EnemyAI enemy, EnemyDistancePathfindingStatus status, Vector3 target, bool farthestFirst, bool avoidLineOfSight, int offset, float capDistance) { //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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(0) { enemy = enemy, status = status, target = target, farthestFirst = farthestFirst, avoidLineOfSight = avoidLineOfSight, offset = offset, capDistance = capDistance }; } } internal static class AsyncPlayerPathfinding { [Flags] internal enum PathOptions : byte { None = 0, GroundCast = 1, RequirePath = 2 } internal class EnemyToPlayerPathfindingStatus { internal enum JobsStatus { NotStarted, NotRetrieved, RetrievedJobsDone, RetrievedJobsIncomplete } [CompilerGenerated] private PathOptions P; internal FindPathsToNodesJob PathsToPlayersJob; private AssignGroundCastPointsAsDestinationsJob AssignDestinationsJob; internal JobHandle JobHandle; private NativeArray raycastCommands; private NativeArray raycastHits; private NativeArray playerPositions; private float inFlightJobsTime; private float currentJobsTime; private bool[] playersPathable; public EnemyToPlayerPathfindingStatus(PathOptions pathFlags) { P = pathFlags; inFlightJobsTime = float.NegativeInfinity; currentJobsTime = float.NegativeInfinity; playersPathable = Array.Empty(); base..ctor(); } private void StartJobs(EnemyAI enemy) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_026d: Unknown result type (might be due to invalid IL or missing references) //IL_026e: 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_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0266: 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_01eb: 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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) NavMeshAgent agent = enemy.agent; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; if (playerPositions.Length != allPlayerScripts.Length) { Clear(); playerPositions = new NativeArray(allPlayerScripts.Length, (Allocator)4, (NativeArrayOptions)0); if (P.HasFlag(PathOptions.GroundCast)) { raycastCommands = new NativeArray(allPlayerScripts.Length, (Allocator)4, (NativeArrayOptions)0); raycastHits = new NativeArray(allPlayerScripts.Length, (Allocator)4, (NativeArrayOptions)0); } } for (int i = 0; i < allPlayerScripts.Length; i++) { PlayerControllerB val = allPlayerScripts[i]; if (!enemy.PlayerIsTargetable(val, false, false, true)) { playerPositions[i] = FindPathsToNodesJob.INVALID_DESTINATION; if (P.HasFlag(PathOptions.GroundCast)) { raycastCommands[i] = default(RaycastCommand); raycastHits[i] = default(RaycastHit); } continue; } Vector3 position = ((Component)val).transform.position; playerPositions[i] = position; if (P.HasFlag(PathOptions.GroundCast)) { QueryParameters @default = QueryParameters.Default; @default.layerMask = StartOfRound.Instance.collidersAndRoomMaskAndDefault; @default.hitTriggers = (QueryTriggerInteraction)1; QueryParameters val2 = @default; raycastCommands[i] = new RaycastCommand(position, Vector3.down, val2, 5f); raycastHits[i] = default(RaycastHit); } } JobHandle val3 = default(JobHandle); if (P.HasFlag(PathOptions.GroundCast)) { val3 = RaycastCommand.ScheduleBatch(raycastCommands, raycastHits, 1, val3); } if (P.HasFlag(PathOptions.GroundCast) && P.HasFlag(PathOptions.RequirePath)) { AssignDestinationsJob.Initialize(raycastHits, playerPositions); val3 = IJobForExtensions.ScheduleByRef(ref AssignDestinationsJob, playerPositions.Length, val3); } if (P.HasFlag(PathOptions.RequirePath)) { PathsToPlayersJob.Initialize(agent, playerPositions.Length); PathsToPlayersJob.SetDestinations(playerPositions); val3 = IJobForExtensions.ScheduleByRef(ref PathsToPlayersJob, playerPositions.Length, val3); } JobHandle = val3; inFlightJobsTime = Time.time; } internal bool AllJobsAreDone() { return ((JobHandle)(ref JobHandle)).IsCompleted; } internal float UpdatePathsAndGetCalculationTime(EnemyAI enemy) { //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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (!AllJobsAreDone()) { return currentJobsTime; } if (playersPathable.Length != playerPositions.Length) { Array.Resize(ref playersPathable, playerPositions.Length); } if (P.HasFlag(PathOptions.RequirePath)) { for (int i = 0; i < playerPositions.Length; i++) { PathQueryStatus result = PathQueryStatusExtensions.GetResult(PathsToPlayersJob.Statuses[i]); playersPathable[i] = (int)result == 1073741824; } } else { if (!P.HasFlag(PathOptions.GroundCast)) { throw new InvalidOperationException("Bad path flags"); } for (int j = 0; j < playerPositions.Length; j++) { bool[] array = playersPathable; int num = j; RaycastHit val = raycastHits[j]; array[num] = ((RaycastHit)(ref val)).colliderInstanceID != 0; } } currentJobsTime = inFlightJobsTime; StartJobs(enemy); return currentJobsTime; } internal bool CanReachPlayer(int playerIndex) { return playersPathable[playerIndex]; } internal void Invalidate() { currentJobsTime = float.NegativeInfinity; inFlightJobsTime = float.NegativeInfinity; } internal void Clear() { raycastCommands.Dispose(); raycastHits.Dispose(); playerPositions.Dispose(); playersPathable = Array.Empty(); } ~EnemyToPlayerPathfindingStatus() { PathsToPlayersJob.FreeAllResources(disposeDestinations: false); Clear(); } } private const byte PlayerPathFlagsMax = 3; private static readonly EnemyMap[] Statuses = CreateStatusMaps(); private static EnemyMap[] CreateStatusMaps() { EnemyMap[] array = new EnemyMap[3]; for (byte b = 0; b < 3; b++) { PathOptions flags = (PathOptions)(b + 1); array[b] = new EnemyMap(() => new EnemyToPlayerPathfindingStatus(flags)); } return array; } internal static void RemoveStatus(EnemyAI enemy) { for (byte b = 0; b < 3; b++) { Statuses[b][enemy].Invalidate(); } } internal static EnemyToPlayerPathfindingStatus GetStatus(EnemyAI enemy, PathOptions flags) { return Statuses[(uint)(flags - 1)][enemy]; } } internal static class AsyncRoamingPathfinding { internal class EnemyRoamingPathfindingStatus { internal FindPathsToNodesJob PathsFromEnemyJob; internal JobHandle PathsFromEnemyJobHandle; internal FindPathsToNodesJob PathsFromSearchStartJob; internal JobHandle PathsFromSearchStartJobHandle; private Vector3[] nodePositions = Array.Empty(); private int nodeCount; internal void StartJobs(EnemyAI enemy) { //IL_005f: 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_00a3: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) AISearchRoutine currentSearch = enemy.currentSearch; NavMeshAgent agent = enemy.agent; List unsearchedNodes = currentSearch.unsearchedNodes; nodeCount = unsearchedNodes.Count; if (nodeCount > nodePositions.Length) { nodePositions = (Vector3[])(object)new Vector3[nodeCount]; } for (int i = 0; i < unsearchedNodes.Count; i++) { nodePositions[GetJobIndex(i)] = unsearchedNodes[i].transform.position; } PathsFromEnemyJob.Initialize(agent, nodePositions, nodeCount, currentSearch.startedSearchAtSelf); PathsFromEnemyJobHandle = IJobForExtensions.ScheduleByRef(ref PathsFromEnemyJob, unsearchedNodes.Count, default(JobHandle)); if (!currentSearch.startedSearchAtSelf) { PathsFromSearchStartJob.Initialize(-1, agent.areaMask, default(Span), currentSearch.currentSearchStartPosition, nodePositions, nodeCount, calculateDistance: true); PathsFromSearchStartJobHandle = IJobForExtensions.ScheduleByRef(ref PathsFromSearchStartJob, unsearchedNodes.Count, default(JobHandle)); } } internal int GetJobIndex(int index) { return nodeCount - 1 - index; } ~EnemyRoamingPathfindingStatus() { PathsFromEnemyJob.FreeAllResources(); PathsFromSearchStartJob.FreeAllResources(); } } private static readonly EnemyMap Statuses = new EnemyMap(() => new EnemyRoamingPathfindingStatus()); internal static void RemoveStatus(EnemyAI enemy) { Statuses.Remove(enemy); } internal static EnemyRoamingPathfindingStatus GetStatus(EnemyAI enemy) { return Statuses[enemy]; } } public class EnemyMap { private readonly Func constructor; private Dictionary backingDictionary; public T this[EnemyAI enemy] => GetItem(enemy); public int Count => backingDictionary.Count; public EnemyMap(Func elementConstructor) { constructor = elementConstructor; backingDictionary = new Dictionary(); base..ctor(); } public T GetItem(EnemyAI enemy) { int instanceID = ((Object)enemy).GetInstanceID(); if (backingDictionary.TryGetValue(instanceID, out var value)) { return value; } value = constructor(); backingDictionary[instanceID] = value; return value; } public void Clear() { backingDictionary = new Dictionary(); } public bool Remove(EnemyAI enemy) { return backingDictionary.Remove(((Object)enemy).GetInstanceID()); } public bool Contains(EnemyAI enemy) { return backingDictionary.ContainsKey(((Object)enemy).GetInstanceID()); } } internal struct FindPathsToNodesJob : IJobFor { public static readonly Vector3 INVALID_DESTINATION = new Vector3(float.NaN, float.NaN, float.NaN); [NativeDisableContainerSafetyRestriction] private static NativeArray StaticThreadQueries; private const float MAX_ENDPOINT_DISTANCE = 1.55f; private const float MAX_ENDPOINT_DISTANCE_SQR = 2.4025f; [ReadOnly] [NativeSetThreadIndex] internal int ThreadIndex; [ReadOnly] [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] internal NativeArray ThreadQueriesRef; [ReadOnly] private int AgentTypeID; [ReadOnly] private int AreaMask; [ReadOnly] private NativeArray Costs; [ReadOnly] private Vector3 QueryExtents; [ReadOnly] private Vector3 Origin; [ReadOnly] [NativeDisableContainerSafetyRestriction] private NativeArray Destinations; [ReadOnly] private bool CalculateDistance; [ReadOnly] [NativeDisableContainerSafetyRestriction] private NativeArray Canceled; [WriteOnly] [NativeDisableContainerSafetyRestriction] internal NativeArray Statuses; [WriteOnly] [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] internal NativeArray Paths; [WriteOnly] [NativeDisableContainerSafetyRestriction] internal NativeArray PathSizes; [WriteOnly] [NativeDisableContainerSafetyRestriction] internal NativeArray PathDistances; public unsafe void Initialize(int agentTypeID, int areaMask, Span costs, Vector3 origin, Vector3[] candidates, int count, bool calculateDistance = false) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) ThreadQueriesRef = Unsafe.Read>((void*)PathfindingJobSharedResources.GetPerThreadQueriesArray()); CreateFixedArrays(); AgentTypeID = agentTypeID; AreaMask = areaMask; if (costs == default(Span)) { Costs.SetAllElements(1f); } else { Costs.CopyFrom(costs); } QueryExtents = NavMeshQueryUtils.GetQueryExtents(agentTypeID); Origin = origin; CalculateDistance = calculateDistance; EnsureCount(count); Statuses.SetAllElements((PathQueryStatus)536870912); if (calculateDistance) { PathDistances.SetAllElements(0f); } Canceled[0] = false; if (candidates != null) { if (Destinations.IsCreated) { Destinations.Dispose(); } if (count > 0) { Destinations = new NativeArray(count, (Allocator)4, (NativeArrayOptions)1); NativeArray.Copy(candidates, Destinations, count); } } } public void Initialize(NavMeshAgent agent, Vector3[] candidates, int count, bool calculateDistance = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) int agentTypeID = default(int); int areaMask = default(int); Span costs = default(Span); AgentExtensions.GetQueryFilter(agent, ref agentTypeID, ref areaMask, ref costs); Initialize(agentTypeID, areaMask, costs, AgentExtensions.GetPathOrigin(agent), candidates, count, calculateDistance); } public void Initialize(NavMeshAgent agent, int count, bool calculateDistance = false) { Initialize(agent, null, count, calculateDistance); } public void Initialize(int agentTypeID, int areaMask, Span costs, Vector3 origin, Vector3[] candidates, bool calculateDistance = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) Initialize(agentTypeID, areaMask, costs, origin, candidates, candidates.Length, calculateDistance); } public void Initialize(NavMeshAgent agent, Vector3[] candidates, bool calculateDistance = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) int agentTypeID = default(int); int areaMask = default(int); Span costs = default(Span); AgentExtensions.GetQueryFilter(agent, ref agentTypeID, ref areaMask, ref costs); Initialize(agentTypeID, areaMask, costs, AgentExtensions.GetPathOrigin(agent), candidates, calculateDistance); } public void Initialize(int agentTypeID, int areaMask, Span costs, Vector3 origin, List candidates, bool calculateDistance = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) Initialize(agentTypeID, areaMask, costs, origin, NoAllocHelpers.ExtractArrayFromListT(candidates), candidates.Count, calculateDistance); } public void Initialize(NavMeshAgent agent, List candidates, bool calculateDistance = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) int agentTypeID = default(int); int areaMask = default(int); Span costs = default(Span); AgentExtensions.GetQueryFilter(agent, ref agentTypeID, ref areaMask, ref costs); Initialize(agentTypeID, areaMask, costs, AgentExtensions.GetPathOrigin(agent), candidates, calculateDistance); } public void SetDestinations(NativeArray destinations) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Destinations = destinations; } private void CreateFixedArrays() { //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_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) if (Canceled.Length != 1) { Costs = new NativeArray(32, (Allocator)4, (NativeArrayOptions)1); Canceled = new NativeArray(1, (Allocator)4, (NativeArrayOptions)1); } } private void DisposeFixedArrays() { Canceled.Dispose(); } private void EnsureCount(int count) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) if (Statuses.Length < count) { DisposeResizeableArrays(); if (count != 0) { Statuses = new NativeArray(count, (Allocator)4, (NativeArrayOptions)1); Paths = new NativeArray(count * 128, (Allocator)4, (NativeArrayOptions)1); PathSizes = new NativeArray(count, (Allocator)4, (NativeArrayOptions)1); PathDistances = new NativeArray(count, (Allocator)4, (NativeArrayOptions)1); } } } private void DisposeResizeableArrays() { if (Statuses.IsCreated) { Statuses.Dispose(); Paths.Dispose(); PathSizes.Dispose(); PathDistances.Dispose(); } } public void Cancel() { if (Canceled.IsCreated) { Canceled[0] = true; } } public NativeArray GetPathBuffer(int index) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Paths.GetSubArray(index * 128, 128); } public NativeArray GetPath(int index) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Paths.GetSubArray(index * 128, PathSizes[index]); } public void Execute(int index) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Invalid comparison between Unknown and I4 //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Invalid comparison between Unknown and I4 //IL_0114: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Invalid comparison between Unknown and I4 //IL_0175: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Invalid comparison between Unknown and I4 //IL_0165: 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_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) if (Canceled[0]) { Statuses[index] = (PathQueryStatus)int.MinValue; return; } NavMeshReadLocker val = default(NavMeshReadLocker); ((NavMeshReadLocker)(ref val))..ctor(); try { Vector3 val2 = Destinations[index]; if (((Vector3)(ref val2)).Equals(INVALID_DESTINATION)) { Statuses[index] = (PathQueryStatus)int.MinValue; return; } NavMeshQuery val3 = ThreadQueriesRef[ThreadIndex]; NavMeshLocation val4 = ((NavMeshQuery)(ref val3)).MapLocation(Origin, QueryExtents, AgentTypeID, AreaMask); if (!((NavMeshQuery)(ref val3)).IsValid(val4)) { Statuses[index] = (PathQueryStatus)int.MinValue; return; } NavMeshLocation val5 = ((NavMeshQuery)(ref val3)).MapLocation(val2, QueryExtents, AgentTypeID, AreaMask); if (!((NavMeshQuery)(ref val3)).IsValid(val5)) { Statuses[index] = (PathQueryStatus)int.MinValue; return; } PathQueryStatus val6 = ((NavMeshQuery)(ref val3)).BeginFindPath(val4, val5, AreaMask, Costs); if ((int)PathQueryStatusExtensions.GetResult(val6) == int.MinValue) { Statuses[index] = val6; return; } int num = default(int); while ((int)PathQueryStatusExtensions.GetResult(val6) == 536870912) { val6 = ((NavMeshQuery)(ref val3)).UpdateFindPath(NavMeshLock.RecommendedUpdateFindPathIterationCount, ref num); ((NavMeshReadLocker)(ref val)).Yield(); } int num2 = default(int); val6 = ((NavMeshQuery)(ref val3)).EndFindPath(ref num2); if ((int)PathQueryStatusExtensions.GetResult(val6) != 1073741824) { Statuses[index] = val6; return; } NativeArray val7 = new NativeArray(num2, (Allocator)2, (NativeArrayOptions)1); ((NavMeshQuery)(ref val3)).GetPathResult(NativeSlice.op_Implicit(val7)); NavMeshQuery val8 = val3; ref Vector3 origin = ref Origin; NativeSlice val9 = NativeSlice.op_Implicit(val7); int num3 = num2; NativeArray pathBuffer = GetPathBuffer(index); int num4 = default(int); val6 = (PathQueryStatus)(NavMeshQueryUtils.FindStraightPath(val8, ref origin, ref val2, ref val9, num3, ref pathBuffer, ref num4) | PathQueryStatusExtensions.GetDetail(val6)); ((NavMeshReadLocker)(ref val)).Dispose(); PathSizes[index] = num4; val7.Dispose(); if ((int)PathQueryStatusExtensions.GetResult(val6) != 1073741824) { Statuses[index] = val6; return; } NativeArray path = GetPath(index); Vector3 val10 = path[path.Length - 1] - val2; if (((Vector3)(ref val10)).sqrMagnitude > 2.4025f) { Statuses[index] = (PathQueryStatus)(int.MinValue | PathQueryStatusExtensions.GetDetail(val6)); return; } if (CalculateDistance) { float num5 = 0f; for (int i = 1; i < path.Length; i++) { num5 += Vector3.Distance(path[i - 1], path[i]); } PathDistances[index] = num5; } Statuses[index] = val6; } finally { ((IDisposable)(NavMeshReadLocker)(ref val)).Dispose(); } } internal void FreeAllResources(bool disposeDestinations = true) { DisposeResizeableArrays(); DisposeFixedArrays(); if (disposeDestinations) { Destinations.Dispose(); } } } internal static class LineOfSight { private const int LINE_OF_SIGHT_LAYER_MASK = 262144; public static bool PathIsBlockedByLineOfSight(NativeArray path, out float pathDistance, Vector3? checkLOSToPosition = null) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) pathDistance = 0f; if (path.Length == 0) { return true; } if (path.Length == 1) { return false; } Vector3 val = path[0]; for (int i = 1; i < path.Length && i < 16; i++) { Vector3 val2 = path[i - 1]; Vector3 val3 = path[i]; pathDistance += Vector3.Distance(val2, val3); if (i <= 5 || !(Vector3.Distance(val, val3) < 1.7f)) { val = val3; if (checkLOSToPosition.HasValue && !Physics.Linecast(val2, checkLOSToPosition.Value + Vector3.up * 0.3f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { return true; } if (Physics.Linecast(val2, val3, 262144)) { return true; } } } return false; } public static bool PathIsBlockedByLineOfSight(NativeArray path, Vector3? checkLOSToPosition = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float pathDistance; return PathIsBlockedByLineOfSight(path, out pathDistance, checkLOSToPosition); } } internal static class NativeArrayUtils { internal unsafe static void SetAllElements(this NativeArray array, T value) where T : unmanaged { //IL_0000: Unknown result type (might be due to invalid IL or missing references) T* buffer = (T*)array.m_Buffer; int length = array.Length; for (int i = 0; i < length; i++) { buffer[i] = value; } } internal unsafe static void CopyFrom(this NativeArray array, Span span) where T : struct { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (array.Length < span.Length) { throw new InvalidOperationException($"NativeArray size {array.Length} is smaller than span size {span.Length}."); } UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafePtr(array), UnsafeUtility.AddressOf(ref span[0]), (long)span.Length); } } [IgnoredByDeepProfiler] [UsedByNativeCode] internal struct ProfilerMarkerWithMetadata where T : unmanaged { [IgnoredByDeepProfiler] [UsedByNativeCode] public struct AutoScope : IDisposable { [NativeDisableUnsafePtrRestriction] internal readonly ProfilerMarkerWithMetadata marker; internal T value; internal bool on; [MethodImpl(MethodImplOptions.AggressiveInlining)] public AutoScope(in ProfilerMarkerWithMetadata marker, T value) { on = false; this.marker = marker; this.value = value; Resume(); } public void Resume() { if (!on) { on = true; marker.Begin(in value); } } public void Pause() { if (on) { marker.End(); on = false; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { Pause(); } } private readonly IntPtr ptr; private ProfilerMarkerData data; public ProfilerMarkerWithMetadata(string name, string metadata) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) data = default(ProfilerMarkerData); ptr = ProfilerUnsafeUtility.CreateMarker(name, (ushort)1, (MarkerFlags)0, 0); if (typeof(T) == typeof(int)) { data.Type = 2; } else if (typeof(T) == typeof(long)) { data.Type = 4; } else if (typeof(T) == typeof(uint)) { data.Type = 3; } else if (typeof(T) == typeof(ulong)) { data.Type = 5; } else if (typeof(T) == typeof(float)) { data.Type = 6; } else if (typeof(T) == typeof(double)) { data.Type = 7; } data.Size = (uint)UnsafeUtility.SizeOf(); if (ptr != IntPtr.Zero) { ProfilerUnsafeUtility.SetMarkerMetadata(ptr, 0, metadata, data.Type, (byte)3); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void Begin(in T value) { fixed (ProfilerMarkerData* ptr = &data) { void* ptr2 = ptr; fixed (T* ptr3 = &value) { void* ptr4 = ptr3; data.Ptr = ptr4; ProfilerUnsafeUtility.BeginSampleWithMetadata(this.ptr, 1, ptr2); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void End() { ProfilerUnsafeUtility.EndSample(ptr); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AutoScope Auto(T value) { return new AutoScope(in this, value); } } } namespace PathfindingLagFix.Utilities.IL { internal class ILInjector { [CompilerGenerated] private sealed class d__34 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; public ILInjector <>4__this; private int offset; public int <>3__offset; private int size; public int <>3__size; private int 5__2; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__34(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ILInjector iLInjector = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = 0; break; case 1: <>1__state = -1; 5__2++; break; } if (5__2 < size) { <>2__current = iLInjector.instructions[iLInjector.index + offset + 5__2]; <>1__state = 1; return true; } 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(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__34 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__34(0) { <>4__this = <>4__this }; } d__.offset = <>3__offset; d__.size = <>3__size; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private const string INVALID = "Injector is invalid"; private List instructions = instructions.ToList(); private ILGenerator generator; private int index; private int matchEnd; public int Index { get { return index; } set { index = value; } } public bool IsValid { get { if (instructions != null) { return IsIndexValid(index); } return false; } } public CodeInstruction Instruction { get { if (!IsIndexInRange(index)) { return null; } return instructions[index]; } set { if (!IsIndexInRange(index)) { throw new InvalidOperationException($"Current index {index} is out of range of instruction count {instructions.Count}"); } instructions[index] = value; } } public CodeInstruction LastMatchedInstruction { get { int num = matchEnd - 1; if (!IsIndexInRange(num)) { return null; } return instructions[num]; } set { int num = matchEnd - 1; if (!IsIndexInRange(num)) { throw new InvalidOperationException($"Last matched index {index} is out of range of instruction count {instructions.Count}"); } instructions[num] = value; } } public ICollection Instructions => instructions.AsReadOnly(); public ILInjector(IEnumerable instructions, ILGenerator generator = null) { this.generator = generator; matchEnd = -1; base..ctor(); } public ILInjector GoToStart() { matchEnd = index; index = 0; return this; } public ILInjector GoToEnd() { matchEnd = index; index = instructions.Count; return this; } public ILInjector Forward(int offset) { if (!IsValid) { return this; } matchEnd = index; index = Math.Clamp(index + offset, -1, instructions.Count); return this; } public ILInjector Back(int offset) { return Forward(-offset); } private void MarkInvalid() { index = -1; matchEnd = -1; } private void Search(bool forward, ILMatcher[] predicates) { if (!IsValid) { return; } int num = 1; if (!forward) { num = -1; index--; } while (forward ? (index < instructions.Count) : (index >= 0)) { if (forward && index + predicates.Length > instructions.Count) { index = instructions.Count; break; } int i; for (i = 0; i < predicates.Length && predicates[i].Matches(instructions[index + i]); i++) { } if (i == predicates.Length) { matchEnd = index + i; return; } index += num; } MarkInvalid(); } public ILInjector Find(params ILMatcher[] predicates) { Search(forward: true, predicates); return this; } public ILInjector ReverseFind(params ILMatcher[] predicates) { Search(forward: false, predicates); return this; } public ILInjector GoToPush(int popIndex) { if (!IsValid) { return this; } matchEnd = index; index--; int num = 0; while (index >= 0) { CodeInstruction instruction = instructions[index]; num += instruction.PushCount(); num -= instruction.PopCount(); if (num >= popIndex) { return this; } index--; } return this; } public ILInjector SkipBranch() { if (Instruction == null) { return this; } if (!(Instruction.operand is Label label)) { throw new InvalidOperationException($"Current instruction is not a branch: {Instruction}"); } return FindLabel(label); } public ILInjector FindLabel(Label label) { if (label == default(Label)) { return this; } matchEnd = index; for (index = 0; index < instructions.Count; index++) { if (instructions[index].labels.Contains(label)) { return this; } } MarkInvalid(); return this; } public ILInjector GoToMatchEnd() { index = matchEnd; return this; } public ILInjector GoToLastMatchedInstruction() { if (!IsIndexValid(matchEnd)) { return this; } index = matchEnd - 1; return this; } private bool IsIndexValid(int index) { return index != -1; } private bool IsIndexInRange(int index) { if (index >= 0) { return index < instructions.Count; } return false; } public CodeInstruction GetRelativeInstruction(int offset) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would read out of bounds at index {num}"); } return instructions[num]; } public ILInjector SetRelativeInstruction(int offset, CodeInstruction instruction) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would write out of bounds at index {num}"); } instructions[num] = instruction; return this; } [IteratorStateMachine(typeof(d__34))] public IEnumerable GetRelativeInstructions(int offset, int size) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__34(-2) { <>4__this = this, <>3__offset = offset, <>3__size = size }; } public IEnumerable GetRelativeInstructions(int size) { return GetRelativeInstructions(0, size); } private void GetLastMatchRangeAbsolute(out int start, out int end) { start = index; end = matchEnd; if (start > end) { int num = end; int num2 = start; start = num; end = num2; } } private void GetLastMatchRange(out int start, out int size) { GetLastMatchRangeAbsolute(out start, out var end); if (start < 0 || start >= instructions.Count) { throw new InvalidOperationException($"Last match range starts at invalid index {start}"); } if (end < 0 || end > instructions.Count) { throw new InvalidOperationException($"Last match range ends at invalid index {end}"); } size = end - start; } public List GetLastMatch() { GetLastMatchRange(out var start, out var size); return instructions.GetRange(start, size); } public ILInjector DefineLabel(out Label label) { if (generator == null) { throw new InvalidOperationException("No ILGenerator was provided"); } label = generator.DefineLabel(); return this; } public ILInjector AddLabel(out Label label) { DefineLabel(out label); return AddLabel(label); } public ILInjector AddLabel(Label label) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Instruction = new CodeInstruction(Instruction); Instruction.labels.Add(label); return this; } public ILInjector InsertInPlace(params CodeInstruction[] instructions) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } this.instructions.InsertRange(index, instructions); if (matchEnd >= index) { matchEnd += instructions.Length; } return this; } public ILInjector Insert(params CodeInstruction[] instructions) { InsertInPlace(instructions); index += instructions.Length; return this; } public ILInjector InsertInPlaceAfterBranch(params CodeInstruction[] instructions) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } List