Decompiled source of Grid3D v1.0.5

Grid3DHooking.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using On;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: AssemblyCompany("NobodyButAlex")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Grid3DHooking")]
[assembly: AssemblyTitle("Grid3DHooking")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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]
	[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;
		}
	}
}
public static class RecursiveComponentFinder
{
	public static List<T> GetComponentsInChildrenRecursively<T>(this GameObject root) where T : Component
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		List<T> list = new List<T>();
		foreach (Transform componentInChild in root.GetComponentInChildren<Transform>())
		{
			Transform val = componentInChild;
			List<T> componentsInChildrenRecursively = ((Component)val).gameObject.GetComponentsInChildrenRecursively<T>();
			list.AddRange(componentsInChildrenRecursively);
		}
		if (list.Count == 0)
		{
			T[] components = root.GetComponents<T>();
			list.AddRange(components);
		}
		return list;
	}
}
public class GenerateGrid : MonoBehaviour
{
	public GameObject testObj;

	private LayerMask layerMask;

	public Vector3 cellSize = new Vector3(0.25f, 0.25f, 0.25f);

	private float? minX = null;

	private float? maxX = null;

	private float? minY = null;

	private float? maxY = null;

	private float? minZ = null;

	private float? maxZ = null;

	private int sizeX;

	private int sizeY;

	private int sizeZ;

	private static readonly GridPosition[] s_neighborOffsets = new GridPosition[26]
	{
		new GridPosition(0, 0, 1),
		new GridPosition(0, 1, 0),
		new GridPosition(1, 0, 0),
		new GridPosition(0, 1, 1),
		new GridPosition(1, 0, 1),
		new GridPosition(1, 1, 0),
		new GridPosition(1, 1, 1),
		new GridPosition(0, 0, -1),
		new GridPosition(0, -1, 0),
		new GridPosition(-1, 0, 0),
		new GridPosition(0, -1, -1),
		new GridPosition(-1, 0, -1),
		new GridPosition(-1, -1, 0),
		new GridPosition(-1, -1, -1),
		new GridPosition(0, 1, -1),
		new GridPosition(-1, 1, 0),
		new GridPosition(-1, 1, -1),
		new GridPosition(1, -1, 0),
		new GridPosition(1, 0, -1),
		new GridPosition(1, -1, -1),
		new GridPosition(0, -1, 1),
		new GridPosition(-1, 0, 1),
		new GridPosition(-1, -1, 1),
		new GridPosition(1, -1, 1),
		new GridPosition(-1, 1, 1),
		new GridPosition(1, 1, -1)
	};

	[SerializeField]
	public Grid3D grid;

	public HashSet<GridPosition> Generate(LayerMask layerMask)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: 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_00c6: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: 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_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: 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_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_09da: Unknown result type (might be due to invalid IL or missing references)
		//IL_09df: Unknown result type (might be due to invalid IL or missing references)
		//IL_09eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_09f0: Unknown result type (might be due to invalid IL or missing references)
		this.layerMask = layerMask;
		minX = null;
		maxX = null;
		minY = null;
		maxY = null;
		minZ = null;
		maxZ = null;
		foreach (Transform item4 in ((Component)this).gameObject.GetComponentsInChildrenRecursively<Transform>())
		{
			if (minX.HasValue)
			{
				if (item4.position.x < minX)
				{
					minX = item4.position.x;
				}
				else if (item4.position.x > maxX)
				{
					maxX = item4.position.x;
				}
			}
			else
			{
				minX = item4.position.x;
				maxX = item4.position.x;
			}
			if (minY.HasValue)
			{
				if (item4.position.y < minY)
				{
					minY = item4.position.y;
				}
				else if (item4.position.y > maxY)
				{
					maxY = item4.position.y;
				}
			}
			else
			{
				minY = item4.position.y;
				maxY = item4.position.y;
			}
			if (minZ.HasValue)
			{
				if (item4.position.z < minZ)
				{
					minZ = item4.position.z;
				}
				else if (item4.position.z > maxZ)
				{
					maxZ = item4.position.z;
				}
			}
			else
			{
				minZ = item4.position.z;
				maxZ = item4.position.z;
			}
		}
		minX -= cellSize.x;
		maxX += cellSize.x;
		sizeX = (int)Math.Round((decimal)(maxX.Value - minX.Value) / (decimal)cellSize.x);
		minY -= cellSize.y;
		maxY += cellSize.y;
		sizeY = (int)Math.Round((decimal)(maxY - minY).Value / (decimal)cellSize.y);
		minZ -= cellSize.z;
		maxZ += cellSize.z;
		sizeZ = (int)Math.Round((decimal)(maxZ - minZ).Value / (decimal)cellSize.z);
		grid.gridSize = new Vector3((float)sizeX, (float)sizeY, (float)sizeZ);
		for (int i = 0; i < sizeX; i++)
		{
			for (int j = 0; j < sizeY; j++)
			{
				for (int k = 0; k < sizeZ; k++)
				{
					bool walkable;
					NodePath nodePath = createNode(i, j, k, out walkable);
					if (!walkable)
					{
						grid.walls.Add(new GridPosition(i, j, k));
					}
				}
			}
		}
		foreach (GridPosition wall in grid.walls)
		{
			GridPosition[] array = s_neighborOffsets;
			foreach (GridPosition gridPosition in array)
			{
				GridPosition item = wall + gridPosition;
				if (item.x >= 0 && item.y >= 0 && item.z >= 0 && item.x < sizeX && item.y < sizeY && item.z < sizeZ && !grid.walls.Contains(item))
				{
					grid.veryExpensiveTiles.Add(item);
				}
			}
		}
		foreach (GridPosition veryExpensiveTile in grid.veryExpensiveTiles)
		{
			GridPosition[] array2 = s_neighborOffsets;
			foreach (GridPosition gridPosition2 in array2)
			{
				GridPosition item2 = veryExpensiveTile + gridPosition2;
				if (item2.x >= 0 && item2.y >= 0 && item2.z >= 0 && item2.x < sizeX && item2.y < sizeY && item2.z < sizeZ && !grid.walls.Contains(item2) && !grid.veryExpensiveTiles.Contains(item2))
				{
					grid.expensiveTiles.Add(item2);
				}
			}
		}
		foreach (GridPosition expensiveTile in grid.expensiveTiles)
		{
			GridPosition[] array3 = s_neighborOffsets;
			foreach (GridPosition gridPosition3 in array3)
			{
				GridPosition item3 = expensiveTile + gridPosition3;
				if (item3.x >= 0 && item3.y >= 0 && item3.z >= 0 && item3.x < sizeX && item3.y < sizeY && item3.z < sizeZ && !grid.walls.Contains(item3) && !grid.veryExpensiveTiles.Contains(item3) && !grid.expensiveTiles.Contains(item3))
				{
					grid.lightExpensiveTiles.Add(item3);
				}
			}
		}
		Debug.Log((object)$"{grid.walls.Count}, {grid.veryExpensiveTiles.Count}, {grid.expensiveTiles.Count}");
		grid.gridOffset = new Vector3(minX.Value, minY.Value, minZ.Value);
		grid.cellSize = cellSize;
		return grid.walls;
	}

	private NodePath createNode(int x_array, int y_array, int z_array, out bool walkable)
	{
		//IL_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		Collider[] array = Physics.OverlapBox(new Vector3(minX.Value + ((float)x_array + 0.5f) * cellSize.x, minY.Value + ((float)y_array + 0.5f) * cellSize.y, minZ.Value + ((float)z_array + 0.5f) * cellSize.z), cellSize / 1.8f, Quaternion.identity, LayerMask.op_Implicit(layerMask));
		walkable = true;
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			if (((Component)val).tag == "Wall")
			{
				walkable = false;
				break;
			}
		}
		return new NodePath();
	}
}
public class NodePath
{
	public int costAdd { get; set; }

	public NodePath(int costAdd = 0)
	{
		this.costAdd = costAdd;
	}

	public bool raiseCostAdd(int newCostAdd)
	{
		if (newCostAdd > costAdd)
		{
			costAdd = newCostAdd;
			return true;
		}
		return false;
	}
}
public struct GridPosition : IEquatable<GridPosition>
{
	public int x;

	public int y;

	public int z;

	public GridPosition(int x, int y, int z)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}

	public GridPosition(Vector3 pos)
	{
		//IL_0002: 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_001c: Unknown result type (might be due to invalid IL or missing references)
		x = (int)pos.x;
		y = (int)pos.y;
		z = (int)pos.z;
	}

	public Vector3 ToVector3()
	{
		//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 new Vector3((float)x, (float)y, (float)z);
	}

	public bool Equals(GridPosition other)
	{
		return x == other.x && y == other.y && z == other.z;
	}

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

	public override int GetHashCode()
	{
		return (x * 73856093) ^ (y * 19349663) ^ (z * 83492791);
	}

	public static bool operator ==(GridPosition a, GridPosition b)
	{
		return a.Equals(b);
	}

	public static bool operator !=(GridPosition a, GridPosition b)
	{
		return !a.Equals(b);
	}

	public static GridPosition operator +(GridPosition a, GridPosition b)
	{
		return new GridPosition(a.x + b.x, a.y + b.y, a.z + b.z);
	}
}
public class PathNode : IComparable<PathNode>
{
	public GridPosition position;

	public GridPosition parent;

	public int gCost;

	public int hCost;

	public int FCost => gCost + hCost;

	public int CompareTo(PathNode other)
	{
		int num = FCost.CompareTo(other.FCost);
		if (num != 0)
		{
			return num;
		}
		return hCost.CompareTo(other.hCost);
	}
}
public class Grid3D : MonoBehaviour
{
	public Vector3 gridOffset;

	public Vector3 gridSize;

	public Vector3 cellSize = new Vector3(0.25f, 0.25f, 0.25f);

	[SerializeField]
	private bool hasConstructed = false;

	private List<Grid3D> moduleGrids = new List<Grid3D>();

	public LevelGenerator levelGenerator;

	public HashSet<GridPosition> walls = new HashSet<GridPosition>();

	public HashSet<GridPosition> veryExpensiveTiles = new HashSet<GridPosition>();

	public HashSet<GridPosition> expensiveTiles = new HashSet<GridPosition>();

	public HashSet<GridPosition> lightExpensiveTiles = new HashSet<GridPosition>();

	private List<GenerateGrid> moduleGens = new List<GenerateGrid>();

	private static readonly GridPosition[] s_neighborOffsets = new GridPosition[26]
	{
		new GridPosition(0, 0, 1),
		new GridPosition(0, 1, 0),
		new GridPosition(1, 0, 0),
		new GridPosition(0, 1, 1),
		new GridPosition(1, 0, 1),
		new GridPosition(1, 1, 0),
		new GridPosition(1, 1, 1),
		new GridPosition(0, 0, -1),
		new GridPosition(0, -1, 0),
		new GridPosition(-1, 0, 0),
		new GridPosition(0, -1, -1),
		new GridPosition(-1, 0, -1),
		new GridPosition(-1, -1, 0),
		new GridPosition(-1, -1, -1),
		new GridPosition(0, 1, -1),
		new GridPosition(-1, 1, 0),
		new GridPosition(-1, 1, -1),
		new GridPosition(1, -1, 0),
		new GridPosition(1, 0, -1),
		new GridPosition(1, -1, -1),
		new GridPosition(0, -1, 1),
		new GridPosition(-1, 0, 1),
		new GridPosition(-1, -1, 1),
		new GridPosition(1, -1, 1),
		new GridPosition(-1, 1, 1),
		new GridPosition(1, 1, -1)
	};

	private Dictionary<int, int> _heuristicCache = new Dictionary<int, int>();

	public void AddRoom(GameObject gameObject)
	{
		//IL_000a: 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)
		GenerateGrid generateGrid = gameObject.AddComponent<GenerateGrid>();
		generateGrid.cellSize = cellSize;
		Grid3D item = (generateGrid.grid = gameObject.AddComponent<Grid3D>());
		moduleGens.Add(generateGrid);
		moduleGrids.Add(item);
	}

	public bool StartUp()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		if (levelGenerator.LevelParent.transform.childCount != 0 && !hasConstructed)
		{
			hasConstructed = true;
			foreach (Transform item in levelGenerator.LevelParent.transform)
			{
				Transform val = item;
				AddRoom(((Component)val).gameObject);
			}
			ConstructGrid();
			Debug.Log((object)$"Grid construction complete. {gridSize.x}, {gridSize.y}, {gridSize.z}");
			return true;
		}
		return false;
	}

	private void ConstructGrid()
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_0426: Unknown result type (might be due to invalid IL or missing references)
		if (moduleGrids.Count == 0)
		{
			return;
		}
		foreach (GenerateGrid moduleGen in moduleGens)
		{
			walls.UnionWith(moduleGen.Generate(LayerMask.op_Implicit(~LayerMask.GetMask(new string[2] { "RoomVolume", "PhysGrabObjectHinge" }))));
		}
		moduleGens.Clear();
		float num = 0f;
		float num2 = 0f;
		float num3 = 0f;
		float num4 = 0f;
		float num5 = 0f;
		float num6 = 0f;
		if (moduleGrids.Count > 0)
		{
			num = moduleGrids[0].gridOffset.x;
			num2 = moduleGrids[0].gridOffset.x;
			num3 = moduleGrids[0].gridOffset.y;
			num4 = moduleGrids[0].gridOffset.y;
			num5 = moduleGrids[0].gridOffset.z;
			num6 = moduleGrids[0].gridOffset.z;
		}
		foreach (Grid3D moduleGrid in moduleGrids)
		{
			num = Math.Min(num, moduleGrid.gridOffset.x);
			num2 = Math.Max(num2, moduleGrid.gridOffset.x + moduleGrid.gridSize.x * cellSize.x);
			num3 = Math.Min(num3, moduleGrid.gridOffset.y);
			num4 = Math.Max(num4, moduleGrid.gridOffset.y + moduleGrid.gridSize.y * cellSize.y);
			num5 = Math.Min(num5, moduleGrid.gridOffset.z);
			num6 = Math.Max(num6, moduleGrid.gridOffset.z + moduleGrid.gridSize.z * cellSize.z);
			Debug.Log((object)$"Bounds are: x({num} - {num2}) y({num3} - {num4}) z({num5} - {num6})");
		}
		foreach (Grid3D moduleGrid2 in moduleGrids)
		{
			int gridOffsetX = (int)((moduleGrid2.gridOffset.x - num) / cellSize.x);
			int gridOffsetY = (int)((moduleGrid2.gridOffset.y - num3) / cellSize.y);
			int gridOffsetZ = (int)((moduleGrid2.gridOffset.z - num5) / cellSize.z);
			walls.UnionWith(moduleGrid2.walls.Select((GridPosition grid3) => grid3 + new GridPosition(gridOffsetX, gridOffsetY, gridOffsetZ)));
			veryExpensiveTiles.UnionWith(moduleGrid2.veryExpensiveTiles.Select((GridPosition grid3) => grid3 + new GridPosition(gridOffsetX, gridOffsetY, gridOffsetZ)));
			expensiveTiles.UnionWith(moduleGrid2.expensiveTiles.Select((GridPosition grid3) => grid3 + new GridPosition(gridOffsetX, gridOffsetY, gridOffsetZ)));
			lightExpensiveTiles.UnionWith(moduleGrid2.lightExpensiveTiles.Select((GridPosition grid3) => grid3 + new GridPosition(gridOffsetX, gridOffsetY, gridOffsetZ)));
		}
		gridSize = new Vector3((num2 - num) / cellSize.x, (num4 - num3) / cellSize.y, (num6 - num5) / cellSize.z);
		gridOffset = new Vector3(num, num3, num5);
		moduleGrids.Clear();
	}

	public List<Vector3> Path(Vector3 start, Vector3 end)
	{
		//IL_0003: 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)
		GridPosition gridPosition = new GridPosition(start);
		GridPosition gridPosition2 = new GridPosition(end);
		if (gridPosition2.x < 0 || gridPosition2.y < 0 || gridPosition2.z < 0 || (float)gridPosition2.x >= gridSize.x || (float)gridPosition2.y >= gridSize.y || (float)gridPosition2.z >= gridSize.z)
		{
			Debug.Log((object)"End outside of reach");
			return null;
		}
		HashSet<GridPosition> hashSet = new HashSet<GridPosition>();
		Dictionary<GridPosition, PathNode> dictionary = new Dictionary<GridPosition, PathNode>((int)gridSize.x * (int)gridSize.y * (int)gridSize.z);
		PathNode pathNode = new PathNode
		{
			position = gridPosition,
			parent = new GridPosition(-1, -1, -1),
			gCost = 0,
			hCost = CalculateHCost(gridPosition, gridPosition2)
		};
		BinaryHeap<PathNode> binaryHeap = new BinaryHeap<PathNode>((int)(gridSize.x * gridSize.y * gridSize.z));
		binaryHeap.Add(pathNode);
		dictionary.Add(pathNode.position, pathNode);
		while (binaryHeap.Count > 0 && hashSet.Count < 40000)
		{
			PathNode pathNode2 = binaryHeap.RemoveFirst();
			GridPosition position = pathNode2.position;
			hashSet.Add(position);
			Debug.Log((object)$"{dictionary[position].FCost} - {dictionary[position].hCost}");
			if (position == gridPosition2)
			{
				return ReconstructPath(dictionary, gridPosition2);
			}
			for (int i = 0; i < s_neighborOffsets.Length; i++)
			{
				GridPosition gridPosition3 = position + s_neighborOffsets[i];
				if (gridPosition3.x < 0 || gridPosition3.y < 0 || gridPosition3.z < 0 || (float)gridPosition3.x >= gridSize.x || (float)gridPosition3.y >= gridSize.y || (float)gridPosition3.z >= gridSize.z || walls.Contains(gridPosition3))
				{
					continue;
				}
				if (!dictionary.TryGetValue(gridPosition3, out var _))
				{
					dictionary.Add(gridPosition3, new PathNode
					{
						position = gridPosition3,
						gCost = int.MaxValue,
						hCost = CalculateHCost(gridPosition3, gridPosition2)
					});
				}
				int num = GetMovementCost(position, gridPosition3);
				if (veryExpensiveTiles.Contains(gridPosition3))
				{
					num += 30;
				}
				else if (expensiveTiles.Contains(gridPosition3))
				{
					num += 20;
				}
				else if (lightExpensiveTiles.Contains(gridPosition3))
				{
					num += 10;
				}
				int num2 = pathNode2.gCost + num;
				if (num2 < dictionary[gridPosition3].gCost)
				{
					dictionary[gridPosition3].parent = position;
					dictionary[gridPosition3].gCost = num2;
					if (!binaryHeap.Contains(dictionary[gridPosition3]))
					{
						binaryHeap.Add(dictionary[gridPosition3]);
					}
					else
					{
						binaryHeap.Update(dictionary[gridPosition3]);
					}
				}
			}
		}
		Debug.Log((object)$"No path found {hashSet.Count}");
		return null;
	}

	private int GetMovementCost(GridPosition from, GridPosition to)
	{
		int num = Math.Abs(from.x - to.x);
		int num2 = Math.Abs(from.y - to.y);
		int num3 = Math.Abs(from.z - to.z);
		if (num + num2 + num3 == 1)
		{
			return 10;
		}
		if (num + num2 + num3 == 2)
		{
			return 14;
		}
		return 17;
	}

	private List<Vector3> ReconstructPath(Dictionary<GridPosition, PathNode> dict, GridPosition endPos)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		GridPosition gridPosition = endPos;
		GridPosition other = new GridPosition(-1, -1, -1);
		while (gridPosition.x != -1 || gridPosition.y != -1 || gridPosition.z != -1)
		{
			list.Insert(0, gridPosition.ToVector3());
			GridPosition parent = dict[gridPosition].parent;
			if (parent.Equals(other) || parent.Equals(gridPosition))
			{
				break;
			}
			gridPosition = parent;
		}
		return list;
	}

	public int CalculateHCost(GridPosition a, GridPosition b)
	{
		int num = Math.Abs(a.x - b.x);
		int num2 = Math.Abs(a.y - b.y);
		int num3 = Math.Abs(a.z - b.z);
		int key = (num * 73856093) ^ (num2 * 19349663) ^ (num3 * 83492791);
		if (_heuristicCache.TryGetValue(key, out var value))
		{
			return value;
		}
		int num4 = Math.Min(Math.Min(num, num2), num3);
		num -= num4;
		num2 -= num4;
		num3 -= num4;
		int num5 = 0;
		int num6 = 0;
		if (num == 0)
		{
			num5 = Math.Min(num2, num3);
			num6 = Math.Max(num2, num3) - num5;
		}
		else if (num2 == 0)
		{
			num5 = Math.Min(num, num3);
			num6 = Math.Max(num, num3) - num5;
		}
		else
		{
			num5 = Math.Min(num, num2);
			num6 = Math.Max(num, num2) - num5;
		}
		int num7 = num4 * 17 + num5 * 14 + num6 * 10;
		_heuristicCache[key] = num7;
		return num7;
	}
}
public class BinaryHeap<T> where T : IComparable<T>
{
	private List<T> _items;

	private Dictionary<T, int> _itemIndices;

	public int Count => _items.Count;

	public BinaryHeap(int capacity = 10)
	{
		_items = new List<T>(capacity);
		_itemIndices = new Dictionary<T, int>(capacity);
	}

	public void Add(T item)
	{
		_items.Add(item);
		int num = _items.Count - 1;
		_itemIndices[item] = num;
		while (num > 0)
		{
			int num2 = (num - 1) / 2;
			if (_items[num].CompareTo(_items[num2]) >= 0)
			{
				break;
			}
			T value = _items[num];
			_items[num] = _items[num2];
			_items[num2] = value;
			_itemIndices[_items[num]] = num;
			_itemIndices[_items[num2]] = num2;
			num = num2;
		}
	}

	public T RemoveFirst()
	{
		if (_items.Count == 0)
		{
			throw new InvalidOperationException("The heap is empty");
		}
		T val = _items[0];
		_itemIndices.Remove(val);
		if (_items.Count == 1)
		{
			_items.RemoveAt(0);
			return val;
		}
		_items[0] = _items[_items.Count - 1];
		_itemIndices[_items[0]] = 0;
		_items.RemoveAt(_items.Count - 1);
		int num = 0;
		while (true)
		{
			int num2 = 2 * num + 1;
			int num3 = 2 * num + 2;
			if (num2 >= _items.Count)
			{
				break;
			}
			int num4 = num;
			if (_items[num2].CompareTo(_items[num4]) < 0)
			{
				num4 = num2;
			}
			if (num3 < _items.Count && _items[num3].CompareTo(_items[num4]) < 0)
			{
				num4 = num3;
			}
			if (num4 == num)
			{
				break;
			}
			T value = _items[num];
			_items[num] = _items[num4];
			_items[num4] = value;
			_itemIndices[_items[num]] = num;
			_itemIndices[_items[num4]] = num4;
			num = num4;
		}
		return val;
	}

	public bool Contains(T item)
	{
		return _itemIndices.ContainsKey(item);
	}

	public void Update(T item)
	{
		if (!_itemIndices.TryGetValue(item, out var value))
		{
			return;
		}
		int num = value;
		while (num > 0)
		{
			int num2 = (num - 1) / 2;
			if (_items[num].CompareTo(_items[num2]) >= 0)
			{
				break;
			}
			T value2 = _items[num];
			_items[num] = _items[num2];
			_items[num2] = value2;
			_itemIndices[_items[num]] = num;
			_itemIndices[_items[num2]] = num2;
			num = num2;
		}
	}
}
namespace Grid3DHooking
{
	[BepInPlugin("NobodyButAlex.Grid3DHooking", "Grid3DHooking", "1.0")]
	public class Grid3DHooking : BaseUnityPlugin
	{
		private Grid3D grid;

		internal static Grid3DHooking Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			LevelGenerator.Generate += new hook_Generate(LevelGenerator_Generate);
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		public static T CopyComponent<T>(T original, GameObject destination) where T : Component
		{
			Type type = ((object)original).GetType();
			Component val = destination.AddComponent(type);
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				fieldInfo.SetValue(val, fieldInfo.GetValue(original));
			}
			return (T)(object)((val is T) ? val : null);
		}

		private IEnumerator LevelGenerator_Generate(orig_Generate orig, LevelGenerator self)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			IEnumerator result = orig.Invoke(self);
			grid = new GameObject("Grid3D").AddComponent<Grid3D>();
			grid.cellSize.x = 0.5f;
			grid.cellSize.y = 0.5f;
			grid.cellSize.z = 0.5f;
			grid.levelGenerator = self;
			return result;
		}

		private void Update()
		{
		}
	}
}