GTFR.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BoosterImplants;
using CellMenu;
using ChainedPuzzles;
using CullingSystem;
using Enemies;
using Expedition;
using GTFO.API;
using GTFO.API.Utilities;
using GTFR.Patches;
using GTFR.Randomizers;
using GTFR.Structs;
using GameData;
using GameEvent;
using Gear;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LGTuner.Configs;
using LGTuner.Manager;
using LGTuner.Utils;
using LevelGeneration;
using LevelGeneration.Core;
using LogUtils;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using StateMachines;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
using XXHashing;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GTFR")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GTFR")]
[assembly: AssemblyTitle("GTFR")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace LGTuner
{
	public static class BuilderInfo
	{
		private static readonly List<Complex> _extraComplexResourceToLoad = new List<Complex>();

		public static IEnumerable<Complex> ExtraComplexResourceToLoad => _extraComplexResourceToLoad;

		public static ComplexResourceSetDataBlock ComplexResourceSet { get; private set; }

		public static int GridSize { get; private set; }

		public static int GridCenter { get; private set; }

		public static int GridZeroOffset { get; private set; }

		public static float AltitudeOffset { get; private set; }

		public static LayoutConfig MainLayer { get; private set; }

		public static LayoutConfig SecondaryLayer { get; private set; }

		public static LayoutConfig ThirdLayer { get; private set; }

		public static LayoutConfig[] DimensionLayer { get; private set; } = Array.Empty<LayoutConfig>();


		internal static void OnResourceSetSelected()
		{
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			ComplexResourceSet = Builder.ComplexResourceSetBlock;
			GridSize = ComplexResourceSet.LevelGenConfig.GridSize;
			GridCenter = GridSize / 2;
			GridZeroOffset = -GridCenter;
			AltitudeOffset = ComplexResourceSet.LevelGenConfig.AltitudeOffset;
			MainLayer = null;
			SecondaryLayer = null;
			ThirdLayer = null;
			DimensionLayer = new LayoutConfig[Enum.GetValues(typeof(eDimensionIndex)).Length];
			_extraComplexResourceToLoad.Clear();
			ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
			if (ConfigManager.TryGetConfig(activeExpedition.LevelLayoutData, out LayoutConfig config))
			{
				MainLayer = config;
			}
			if (activeExpedition.SecondaryLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.SecondaryLayout, out LayoutConfig config2))
			{
				SecondaryLayer = config2;
			}
			if (activeExpedition.ThirdLayerEnabled && ConfigManager.TryGetConfig(activeExpedition.ThirdLayout, out LayoutConfig config3))
			{
				ThirdLayer = config3;
			}
			Enumerator<Dimension> enumerator = Builder.CurrentFloor.m_dimensions.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Dimension current = enumerator.Current;
				if (!current.IsMainDimension && !current.DimensionData.IsStaticDimension)
				{
					LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(current.DimensionData.LevelLayoutData);
					if (block != null && ConfigManager.TryGetConfig(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID, out LayoutConfig config4))
					{
						Logger.Info("loysimme dimension ja levellayoutin");
						config4.Reset(((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)current.Grid).m_sizeX);
						DimensionLayer[current.DimensionIndex] = config4;
					}
				}
			}
			MainLayer?.Reset(GridSize);
			SecondaryLayer?.Reset(GridSize);
			ThirdLayer?.Reset(GridSize);
			AddExtraShard(MainLayer);
			AddExtraShard(SecondaryLayer);
			AddExtraShard(ThirdLayer);
			Array.ForEach(DimensionLayer, delegate(LayoutConfig x)
			{
				AddExtraShard(x);
			});
		}

		private static void AddExtraShard(LayoutConfig layerConfig)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (layerConfig == null)
			{
				return;
			}
			Complex[] extraComplexResourceToLoad = layerConfig.ExtraComplexResourceToLoad;
			foreach (Complex item in extraComplexResourceToLoad)
			{
				if (!_extraComplexResourceToLoad.Contains(item))
				{
					_extraComplexResourceToLoad.Add(item);
				}
			}
		}

		public static bool TryGetConfig(LG_Zone zone, out LayoutConfig config)
		{
			//IL_0001: 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_0031: 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_0044: Expected I4, but got Unknown
			//IL_0116: 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)
			Dimension val = default(Dimension);
			if (!Dimension.GetDimension(zone.DimensionIndex, ref val))
			{
				Logger.Info("dimension getter failed");
				config = null;
				return false;
			}
			if (val.IsMainDimension)
			{
				LG_LayerType type = zone.Layer.m_type;
				switch ((int)type)
				{
				case 0:
					config = MainLayer;
					return MainLayer != null;
				case 1:
					config = SecondaryLayer;
					return SecondaryLayer != null;
				case 2:
					config = ThirdLayer;
					return ThirdLayer != null;
				}
			}
			else if (!val.DimensionData.IsStaticDimension)
			{
				Enumerator<Dimension> enumerator = Builder.CurrentFloor.m_dimensions.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Dimension current = enumerator.Current;
					if (!current.IsMainDimension && !current.DimensionData.IsStaticDimension)
					{
						LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(current.DimensionData.LevelLayoutData);
						if (block != null && ConfigManager.TryGetConfig(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID, out LayoutConfig config2))
						{
							Logger.Info("found a dimension + levellayout");
							config2.Reset(((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)current.Grid).m_sizeX);
							DimensionLayer[current.DimensionIndex] = config2;
						}
					}
				}
				config = DimensionLayer[zone.DimensionIndex];
				return config != null;
			}
			config = null;
			return false;
		}

		public static GameObject GetRandomPlug(uint seed, int plugHeight, SubComplex subcomplex, bool withGate)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ComplexResourceSetDataBlock complexResourceSet = ComplexResourceSet;
			return (GameObject)(plugHeight switch
			{
				0 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_straightPlugsWithGates : complexResourceSet.m_straightPlugsNoGates, subcomplex), 
				1 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_singleDropPlugsWithGates : complexResourceSet.m_singleDropPlugsNoGates, subcomplex), 
				2 => complexResourceSet.GetRandomPrefab(seed, withGate ? complexResourceSet.m_doubleDropPlugsWithGates : complexResourceSet.m_doubleDropPlugsNoGates, subcomplex), 
				_ => null, 
			});
		}

		public static uint GetLayoutIdOfZone(LG_Zone zone)
		{
			//IL_0018: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected I4, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Dimension dimension = zone.Dimension;
			if (dimension.IsMainDimension)
			{
				LG_LayerType type = zone.Layer.m_type;
				ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
				return (int)type switch
				{
					0 => activeExpedition.LevelLayoutData, 
					1 => activeExpedition.SecondaryLayout, 
					2 => activeExpedition.ThirdLayout, 
					_ => throw new NotSupportedException($"LayerType: {type} is not supported!"), 
				};
			}
			return dimension.DimensionData.LevelLayoutData;
		}
	}
	[BepInPlugin("LGTuner", "LGTuner", "1.0.7")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntryPoint : BasePlugin
	{
		public Harmony HarmonyInstance { get; private set; }

		public override void Load()
		{
			ConfigManager.Init();
		}
	}
	public static class LGExtensions
	{
		public static bool IsSame(this LG_GridPosition position, LG_GridPosition other)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (position.x == other.x)
			{
				return position.z == other.z;
			}
			return false;
		}

		public static LG_GridPosition ToNormalGrid(this LG_Tile tile, int gridSize)
		{
			//IL_0006: 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)
			return tile.m_shape.m_gridPosition.GetNormal(gridSize);
		}

		public static LG_GridPosition GetNormal(this LG_GridPosition position, int gridSize)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			LG_GridPosition result;
			if (gridSize < 0)
			{
				result = default(LG_GridPosition);
				result.x = position.x + BuilderInfo.GridZeroOffset;
				result.z = position.z + BuilderInfo.GridZeroOffset;
				return result;
			}
			int num = gridSize / 2;
			result = default(LG_GridPosition);
			result.x = position.x - num;
			result.z = position.z - num;
			return result;
		}

		public static Vector3 GetPositionNormal(this LG_Grid grid, int x, int z, int gridSize)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (gridSize < 0)
			{
				return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x - BuilderInfo.GridZeroOffset, z - BuilderInfo.GridZeroOffset);
			}
			int num = gridSize / 2;
			return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetPosition(x + num, z + num);
		}

		public static int GetGridSize(this Dimension dimension)
		{
			return ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)dimension.Grid).m_sizeX;
		}

		public static bool TryGetDimension(this LG_Floor floor, int dimensionIndex, out Dimension dimension)
		{
			if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex))
			{
				return floor.GetDimension((eDimensionIndex)dimensionIndex, ref dimension);
			}
			dimension = null;
			return false;
		}

		public static bool TryGetDimension(this LG_Floor floor, eDimensionIndex dimensionIndex, out Dimension dimension)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(eDimensionIndex), dimensionIndex))
			{
				return floor.GetDimension(dimensionIndex, ref dimension);
			}
			dimension = null;
			return false;
		}
	}
	public static class RandomExtensions
	{
		public static uint NextUint(this Random random)
		{
			int num = random.Next(1073741824);
			uint num2 = (uint)random.Next(4);
			return (uint)(num << 2) | num2;
		}

		public static float NextFloat(this Random random)
		{
			return Mathf.Clamp01((float)random.NextDouble());
		}

		public static int ToSeed(this uint seed)
		{
			return (int)seed;
		}
	}
	public enum DirectionType
	{
		Unknown,
		Forward,
		Backward,
		Left,
		Right
	}
	public enum RotateType
	{
		None,
		Flip,
		MoveTo_Left,
		MoveTo_Right,
		Towards_Random,
		Towards_Forward,
		Towards_Backward,
		Towards_Left,
		Towards_Right
	}
	public struct LG_PlugInfo
	{
		public static readonly Quaternion NoRotation = Quaternion.AngleAxis(0f, Vector3.up);

		public static readonly Quaternion RightRotation = Quaternion.AngleAxis(90f, Vector3.up);

		public static readonly Quaternion BackwardRotation = Quaternion.AngleAxis(180f, Vector3.up);

		public static readonly Quaternion LeftRotation = Quaternion.AngleAxis(270f, Vector3.up);

		public static readonly Vector3 FrontPlugPosition = Vector3.forward * 32f;

		public static readonly Vector3 BackPlugPosition = Vector3.back * 32f;

		public static readonly Vector3 LeftPlugPosition = Vector3.left * 32f;

		public static readonly Vector3 RightPlugPosition = Vector3.right * 32f;

		public bool IsValid { get; private set; }

		public DirectionType StartDirection { get; private set; }

		public int Count { get; private set; }

		public bool HasFront { get; private set; }

		public bool HasBack { get; private set; }

		public bool HasLeft { get; private set; }

		public bool HasRight { get; private set; }

		public bool TryGetNewRotation(uint seed, RotateType rotate, out Quaternion rotation)
		{
			//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_0019: 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)
			DirectionType newDirection = GetNewDirection(seed, StartDirection, rotate);
			if (Count >= 4)
			{
				rotation = GetRotationOfDirection(newDirection);
				return true;
			}
			Logger.Info($"You are rotating {Count} side Geomorph, this could lead to level gen crash!");
			rotation = GetRotationOfDirection(newDirection);
			return true;
		}

		public bool HasPlug(DirectionType direction)
		{
			if (!IsValid)
			{
				return false;
			}
			if (Count >= 4)
			{
				return true;
			}
			return direction switch
			{
				DirectionType.Forward => HasFront, 
				DirectionType.Backward => HasBack, 
				DirectionType.Left => HasLeft, 
				DirectionType.Right => HasRight, 
				_ => false, 
			};
		}

		public static LG_PlugInfo BuildPlugInfo(GameObject geoObject, Quaternion rotation)
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected I4, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)geoObject.GetComponent<LG_Geomorph>() == (Object)null)
			{
				return default(LG_PlugInfo);
			}
			Il2CppArrayBase<LG_Plug> componentsInChildren = geoObject.GetComponentsInChildren<LG_Plug>();
			if (componentsInChildren == null)
			{
				return default(LG_PlugInfo);
			}
			if (componentsInChildren.Length < 1)
			{
				return default(LG_PlugInfo);
			}
			LG_PlugInfo result = default(LG_PlugInfo);
			foreach (LG_Plug item in componentsInChildren)
			{
				LG_PlugDir dir = item.m_dir;
				switch (dir - 2)
				{
				case 0:
					result.HasBack = true;
					result.Count++;
					break;
				case 2:
					result.HasFront = true;
					result.Count++;
					break;
				case 3:
					result.HasLeft = true;
					result.Count++;
					break;
				case 1:
					result.HasRight = true;
					result.Count++;
					break;
				}
			}
			result.IsValid = result.Count > 0;
			float num = Mathf.Round(((Quaternion)(ref rotation)).eulerAngles.y);
			Logger.Verbose($"angle: {num}");
			num = Mathf.Repeat(num, 360f);
			result.StartDirection = Mathf.RoundToInt(num / 90f) switch
			{
				0 => DirectionType.Forward, 
				1 => DirectionType.Right, 
				2 => DirectionType.Backward, 
				3 => DirectionType.Left, 
				_ => DirectionType.Unknown, 
			};
			return result;
		}

		public static DirectionType GetNewDirection(uint seed, DirectionType direction, RotateType rotate)
		{
			if (direction == DirectionType.Unknown)
			{
				return DirectionType.Unknown;
			}
			if (rotate == RotateType.Towards_Random)
			{
				rotate = new Random(seed.ToSeed()).Next(4) switch
				{
					0 => RotateType.Towards_Forward, 
					1 => RotateType.Towards_Backward, 
					2 => RotateType.Towards_Left, 
					3 => RotateType.Towards_Right, 
					_ => throw new IndexOutOfRangeException("Towards_Random: nextIndex was out of range?!"), 
				};
			}
			return rotate switch
			{
				RotateType.None => direction, 
				RotateType.Flip => direction switch
				{
					DirectionType.Forward => DirectionType.Backward, 
					DirectionType.Backward => DirectionType.Forward, 
					DirectionType.Left => DirectionType.Right, 
					DirectionType.Right => DirectionType.Left, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.MoveTo_Left => direction switch
				{
					DirectionType.Forward => DirectionType.Left, 
					DirectionType.Backward => DirectionType.Right, 
					DirectionType.Left => DirectionType.Backward, 
					DirectionType.Right => DirectionType.Forward, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.MoveTo_Right => direction switch
				{
					DirectionType.Forward => DirectionType.Right, 
					DirectionType.Backward => DirectionType.Left, 
					DirectionType.Left => DirectionType.Forward, 
					DirectionType.Right => DirectionType.Backward, 
					_ => throw new ArgumentOutOfRangeException("direction"), 
				}, 
				RotateType.Towards_Forward => DirectionType.Forward, 
				RotateType.Towards_Backward => DirectionType.Backward, 
				RotateType.Towards_Left => DirectionType.Left, 
				RotateType.Towards_Right => DirectionType.Right, 
				_ => throw new ArgumentOutOfRangeException("direction"), 
			};
		}

		public static Quaternion GetRotationOfDirection(DirectionType direction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0037: 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)
			return (Quaternion)(direction switch
			{
				DirectionType.Forward => NoRotation, 
				DirectionType.Backward => BackwardRotation, 
				DirectionType.Left => LeftRotation, 
				DirectionType.Right => RightRotation, 
				_ => throw new ArgumentOutOfRangeException("direction"), 
			});
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource _logger;

		static Logger()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_logger = new ManualLogSource("LGTuner");
			Logger.Sources.Add((ILogSource)(object)_logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

		public static void Info(object data)
		{
			_logger.LogMessage((object)Format(data));
		}

		public static void Verbose(object data)
		{
		}

		public static void Debug(object data)
		{
			_logger.LogDebug((object)Format(data));
		}

		public static void Error(object data)
		{
			_logger.LogError((object)Format(data));
		}
	}
}
namespace LGTuner.Utils
{
	internal static class JSON
	{
		private static readonly JsonSerializerOptions _setting;

		static JSON()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				Logger.Info("PartialData Support Found!");
			}
		}

		public static T Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _setting);
		}

		public static object Deserialize(Type type, string json)
		{
			return JsonSerializer.Deserialize(json, type, _setting);
		}

		public static string Serialize(object value, Type type)
		{
			return JsonSerializer.Serialize(value, type, _setting);
		}
	}
	public static class MTFOPartialDataUtil
	{
		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

		static MTFOPartialDataUtil()
		{
			PersistentIDConverter = null;
			IsLoaded = false;
			Initialized = false;
			PartialDataPath = string.Empty;
			ConfigPath = string.Empty;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = obj.GetTypes();
				Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find PersistentIDConverter Class");
				}
				Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class");
				PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: Initialized");
				}
				if ((object)property2 == null)
				{
					throw new Exception("Unable to Find Property: PartialDataPath");
				}
				if ((object)property3 == null)
				{
					throw new Exception("Unable to Find Field: ConfigPath");
				}
				Initialized = (bool)property.GetValue(null);
				PartialDataPath = (string)property2.GetValue(null);
				ConfigPath = (string)property3.GetValue(null);
				PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
			}
		}
	}
	public static class MTFOUtil
	{
		public const string PLUGIN_GUID = "com.dak.MTFO";

		public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		static MTFOUtil()
		{
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			try
			{
				Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)obj == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
				FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
			}
		}
	}
}
namespace LGTuner.Manager
{
	public static class ConfigManager
	{
		public static List<LayoutConfig> _layouts = new List<LayoutConfig>();

		public static Dictionary<uint, LayoutConfig> _lookup = new Dictionary<uint, LayoutConfig>();

		public static Dictionary<string, LayoutConfig> _fileNameLookup = new Dictionary<string, LayoutConfig>();

		public static IEnumerable<LayoutConfig> Layouts => _layouts;

		public static void Init()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			if (!MTFOUtil.HasCustomContent)
			{
				return;
			}
			string text = Path.Combine(MTFOUtil.CustomPath, "LGTuner");
			FileInfo[] files = Directory.CreateDirectory(text).GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				string extension = fileInfo.Extension;
				bool flag = extension.Equals(".json", StringComparison.InvariantCultureIgnoreCase);
				bool flag2 = extension.Equals(".jsonc", StringComparison.InvariantCultureIgnoreCase);
				if (flag || flag2)
				{
					LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(File.ReadAllText(fileInfo.FullName));
					if (_lookup.ContainsKey(layoutConfig.LevelLayoutID))
					{
						Logger.Error($"Duplicated ID found!: {fileInfo.Name}, {layoutConfig.LevelLayoutID}");
					}
					else
					{
						_layouts.Add(layoutConfig);
						_lookup.Add(layoutConfig.LevelLayoutID, layoutConfig);
						_fileNameLookup.Add(fileInfo.Name.ToLowerInvariant(), layoutConfig);
					}
				}
			}
			LiveEditListener obj = LiveEdit.CreateListener(text, "*.*", true);
			obj.FileChanged += new LiveEditEventHandler(LiveEdit_FileChanged);
			obj.StartListen();
		}

		private static void LiveEdit_FileChanged(LiveEditEventArgs e)
		{
			string key = Path.GetFileName(e.FullPath).ToLowerInvariant();
			string extension = Path.GetExtension(e.FullPath);
			if (!extension.Equals(".json", StringComparison.InvariantCulture) && !extension.Equals(".jsonc", StringComparison.InvariantCulture))
			{
				return;
			}
			Logger.Error($"File Edited: '{key}' '{e.FullPath}'");
			try
			{
				LayoutConfig data = _fileNameLookup[key];
				uint oldID = data.LevelLayoutID;
				LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string json)
				{
					try
					{
						LayoutConfig layoutConfig = JSON.Deserialize<LayoutConfig>(json);
						layoutConfig.LevelLayoutID = oldID;
						_fileNameLookup.Remove(key);
						_lookup.Remove(oldID);
						_layouts.Remove(data);
						_layouts.Add(layoutConfig);
						_lookup.Add(oldID, layoutConfig);
						_fileNameLookup.Add(key, layoutConfig);
					}
					catch (Exception value2)
					{
						Logger.Error($"Error while reading LGTuner Config: {value2}");
					}
				});
			}
			catch (Exception value)
			{
				Logger.Error($"Error while reading LGTuner Config: {value}");
			}
		}

		private static void DumpLevel()
		{
		}

		private static void DumpLayerToConfig()
		{
		}

		public static bool TryGetConfig(uint layoutID, out LayoutConfig config)
		{
			return _lookup.TryGetValue(layoutID, out config);
		}
	}
}
namespace LGTuner.Inject
{
	[HarmonyPatch(typeof(LG_LevelBuilder), "PlaceRoot")]
	internal static class Inject_BuildGeomorph
	{
		private static LayoutConfig _configContext;

		private static RotateType _nextRotateType;

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("BuildFloor")]
		private static void Post_BuildFloor()
		{
			BuilderInfo.OnResourceSetSelected();
		}

		[HarmonyPrefix]
		[HarmonyWrapSafe]
		[HarmonyPatch("PlaceRoot")]
		private static void Pre_PlaceRoot(LG_Tile tile, ref GameObject tilePrefab, ref bool forceAlignToVector, ref Vector3 alignVector, LG_Zone zone)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_004b: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			_configContext = null;
			_nextRotateType = RotateType.None;
			forceAlignToVector = alignVector != Vector3.zero;
			int gridSize = zone.Dimension.GetGridSize();
			LG_GridPosition val = tile.ToNormalGrid(gridSize);
			Logger.Info($"tile info: {val.x} {val.z} {((Object)tilePrefab).name} for {zone.LocalIndex} : {zone.DimensionIndex}");
			if (!BuilderInfo.TryGetConfig(zone, out _configContext))
			{
				return;
			}
			if (!_configContext.TryGetTileData(val, out TileOverrideData overrideData))
			{
				overrideData = _configContext.PopulateTileOverrideForZone(zone, val);
				if (overrideData == null)
				{
					return;
				}
			}
			if (!string.IsNullOrEmpty(overrideData.Geomorph))
			{
				Object loadedAsset = AssetAPI.GetLoadedAsset(overrideData.Geomorph);
				GameObject val2 = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).Cast<GameObject>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Logger.Info(" - tile overriden! " + ((Object)val2).name);
					tilePrefab = val2;
				}
			}
			if (overrideData.Rotation != 0)
			{
				_nextRotateType = overrideData.Rotation;
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("GetTilePosition")]
		private static void Post_GetTilePosition(LG_Tile tile, LG_Floor floor, int dimensionIndex, ref Vector3 __result)
		{
			//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_002c: 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_004b: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (_configContext != null && floor.TryGetDimension(dimensionIndex, out Dimension dimension))
			{
				int gridSize = _configContext.GridSize;
				LG_GridPosition val = tile.ToNormalGrid(gridSize);
				if (_configContext.TryGetTileData(val, out TileOverrideData overrideData) && overrideData.OverrideAltitude)
				{
					Vector3 positionNormal = dimension.Grid.GetPositionNormal(val.x, val.z, gridSize);
					positionNormal += new Vector3(0f, (float)overrideData.Altitude * BuilderInfo.AltitudeOffset, 0f);
					__result = positionNormal;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyWrapSafe]
		[HarmonyPatch("PlaceRoot")]
		private static void Post_PlaceRoot(LG_Tile tile, LG_Zone zone, LG_Geomorph __result)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (_configContext == null)
			{
				return;
			}
			if (_nextRotateType != 0)
			{
				GameObject gameObject = ((Component)__result).gameObject;
				LG_PlugInfo lG_PlugInfo = LG_PlugInfo.BuildPlugInfo(gameObject, gameObject.transform.rotation);
				Logger.Info($" - TRYING ROTATION! PLUG COUNT: {lG_PlugInfo.Count}");
				if (lG_PlugInfo.TryGetNewRotation(zone.m_subSeed, _nextRotateType, out var rotation))
				{
					Logger.Info(" - Done!");
					gameObject.transform.rotation = rotation;
				}
				__result.SetPlaced();
			}
			int gridSize = _configContext.GridSize;
			LG_GridPosition normalGridPosition = tile.ToNormalGrid(gridSize);
			if (!_configContext.TryGetTileData(normalGridPosition, out TileOverrideData overrideData) || !overrideData.OverrideAreaSeeds)
			{
				return;
			}
			if (overrideData.AreaSeeds.Length == ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length)
			{
				int length = ((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length;
				for (int i = 0; i < length; i++)
				{
					uint num = overrideData.AreaSeeds[i];
					if (num != 0)
					{
						((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].AreaSeed = num;
						Logger.Info($" - new area seed: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas)[i].m_navInfo}, {num}");
					}
				}
			}
			else
			{
				Logger.Error($" - Area count and AreaSeeds item count mismatched! (CFG: {overrideData.AreaSeeds.Length} != AREA: {((Il2CppArrayBase<LG_Area>)(object)__result.m_areas).Length}) Area seed will not be applied!");
			}
		}
	}
	[HarmonyPatch(typeof(LG_BuildPlugBaseJob), "SpawnPlug")]
	internal static class Inject_BuildPlug
	{
		private static void Prefix(LG_Plug plug, ref GameObject prefab)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected I4, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			Logger.Info($"found plug for zone: {((LG_ZoneExpander)plug).m_linksFrom.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksFrom).name}->{((LG_ZoneExpander)plug).m_linksTo.m_zone.LocalIndex}{((Object)((LG_ZoneExpander)plug).m_linksTo).name}");
			if (!BuilderInfo.TryGetConfig(((LG_ZoneExpander)plug).m_linksFrom.m_zone, out LayoutConfig config))
			{
				return;
			}
			LG_GridPosition normal = ((LG_ZoneExpander)plug).m_linksFrom.m_geomorph.m_tile.m_shape.m_gridPosition.GetNormal(config.GridSize);
			if (!config.TryGetTileData(normal, out TileOverrideData overrideData))
			{
				return;
			}
			ZoneOverrideData zoneData = overrideData.ZoneData;
			if (zoneData != null && zoneData.OverridePlugs && TryGetPlugPrefab(overrideData.ZoneData.GetNextPlug(), out GameObject prefab2))
			{
				Logger.Info(" - Prefab Replaced by Zone OverridePlugs! " + ((Object)prefab2).name);
				prefab = prefab2;
			}
			LG_PlugDir dir = plug.m_dir;
			GameObject prefab3;
			switch (dir - 2)
			{
			case 0:
				if (TryGetPlugPrefab(overrideData.BackwardPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by BackwardPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 2:
				if (TryGetPlugPrefab(overrideData.ForwardPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by ForwardPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 3:
				if (TryGetPlugPrefab(overrideData.LeftPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by LeftPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			case 1:
				if (TryGetPlugPrefab(overrideData.RightPlug, out prefab3))
				{
					Logger.Info(" - Prefab Replaced by RightPlug setting! " + ((Object)prefab3).name);
					prefab = prefab3;
					return;
				}
				break;
			}
			if (overrideData.OverridePlugWithNoGateChance)
			{
				Random random = new Random(((LG_ZoneExpander)plug).m_linksFrom.AreaSeed.ToSeed());
				bool withGate = ((LG_ZoneExpander)plug).m_isZoneSource || (!(overrideData.PlugWithNoGateChance >= 1f) && (overrideData.PlugWithNoGateChance <= 0f || random.NextFloat() >= overrideData.PlugWithNoGateChance));
				int dropHeight = GetDropHeight(plug);
				GameObject randomPlug = BuilderInfo.GetRandomPlug(random.NextUint(), dropHeight, GetSubComplexOfPlug(plug), withGate);
				if ((Object)(object)randomPlug == (Object)null)
				{
					Logger.Error($"Plug was null! - Height: {dropHeight}");
				}
				else
				{
					prefab = randomPlug;
				}
			}
		}

		private static SubComplex GetSubComplexOfPlug(LG_Plug plug)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0013: 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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			SubComplex result = ((LG_ZoneExpander)plug).m_subComplex;
			if (((LG_ZoneExpander)plug).m_subComplex != ((LG_ZoneExpander)plug.m_pariedWith).m_subComplex)
			{
				result = (SubComplex)8;
			}
			return result;
		}

		private static bool TryGetPlugPrefab(string prefabPath, out GameObject prefab)
		{
			if (string.IsNullOrEmpty(prefabPath))
			{
				prefab = null;
				return false;
			}
			prefab = ((Il2CppObjectBase)AssetAPI.GetLoadedAsset(prefabPath)).Cast<GameObject>();
			return (Object)(object)prefab != (Object)null;
		}

		private static int GetDropHeight(LG_Plug plug)
		{
			//IL_0006: 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)
			return Mathf.RoundToInt(Mathf.Abs(((Component)plug).transform.position.y - ((Component)plug.m_pariedWith).transform.position.y) / BuilderInfo.AltitudeOffset);
		}
	}
	[HarmonyPatch(typeof(LG_BuildPlugJob), "Build")]
	internal class Inject_BuildPlugJob
	{
		[HarmonyWrapSafe]
		private static bool Prefix(LG_BuildPlugJob __instance)
		{
			//IL_0022: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected I4, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			LG_Plug plug = __instance.m_plug;
			Logger.Info($"buildplugjob plug in complex {((LG_ZoneExpander)plug).m_subComplex} plug status {((LG_ZoneExpander)plug).ExpanderStatus} plug direction {plug.m_dir} ..");
			if ((int)((LG_ZoneExpander)plug).ExpanderStatus == 1)
			{
				return true;
			}
			if (((LG_ZoneExpander)plug).m_isZoneSource)
			{
				return true;
			}
			if (!BuilderInfo.TryGetConfig(((LG_ZoneExpander)plug).m_linksFrom.m_zone, out LayoutConfig config))
			{
				return true;
			}
			LG_GridPosition normal = ((LG_ZoneExpander)plug).m_linksFrom.m_geomorph.m_tile.m_shape.m_gridPosition.GetNormal(config.GridSize);
			if (!config.TryGetTileData(normal, out TileOverrideData overrideData))
			{
				return true;
			}
			LG_PlugDir dir = plug.m_dir;
			GameObject prefab;
			switch (dir - 2)
			{
			case 0:
				if (TryGetPlugPrefab(overrideData.BackwardPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by BackwardPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 2:
				if (TryGetPlugPrefab(overrideData.ForwardPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by ForwardPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 3:
				if (TryGetPlugPrefab(overrideData.LeftPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by LeftPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			case 1:
				if (TryGetPlugPrefab(overrideData.RightPlug, out prefab))
				{
					Logger.Info(" - Prefab Replaced by RightPlug setting! " + ((Object)prefab).name);
					val = prefab;
				}
				break;
			}
			if ((Object)(object)val != (Object)null)
			{
				Logger.Info($"we shall replace a cap going {plug.m_dir}");
				Vector3 position = ((Component)plug).transform.position;
				Quaternion rotation = ((Component)plug).transform.rotation;
				GameObject val2 = Object.Instantiate<GameObject>(val, position, rotation);
				val2.transform.SetParent(((Component)plug).transform, true);
				LG_Factory.FindAndBuildSelectorsAndSpawners(val2, RandomExtensions.NextSubSeed(__instance.m_rnd.Random), false);
				__instance.ProcessDivider(plug, val2, false, RandomExtensions.NextSubSeed(__instance.m_rnd.Random));
				((LG_ZoneExpander)plug).m_wasProcessed = true;
			}
			return true;
		}

		private static bool TryGetPlugPrefab(string prefabPath, out GameObject prefab)
		{
			if (string.IsNullOrEmpty(prefabPath))
			{
				prefab = null;
				return false;
			}
			prefab = ((Il2CppObjectBase)AssetAPI.GetLoadedAsset(prefabPath)).Cast<GameObject>();
			return (Object)(object)prefab != (Object)null;
		}
	}
	[HarmonyPatch(typeof(LG_Floor), "CreateDimension")]
	internal static class Inject_CreateDimension
	{
		[HarmonyPrefix]
		private static bool Prefix(LG_Floor __instance, uint seed, eDimensionIndex dimensionIndex, bool arenaDimension, DimensionData dimensionData, Vector3 position, ref int __result, int gridSize = 10, float cellSize = 64f)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: 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_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			if (dimensionData.IsStaticDimension)
			{
				return true;
			}
			LayoutConfig config = null;
			LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(dimensionData.LevelLayoutData);
			ConfigManager.TryGetConfig(((GameDataBlockBase<LevelLayoutDataBlock>)(object)block).persistentID, out config);
			if (config == null)
			{
				return true;
			}
			if (config.TileOverrides.Length == 0)
			{
				return true;
			}
			gridSize = 10;
			cellSize = 64f;
			GameObject val = null;
			XXHashSequence val2 = default(XXHashSequence);
			((XXHashSequence)(ref val2))..ctor(seed, true);
			Vector3 val3 = position - new Vector3(cellSize, 0f, cellSize) * (float)gridSize * 0.5f;
			LG_TileShape val4 = __instance.CreateTileShape((LG_TileShapeType)1, cellSize, ref val3);
			LG_Grid val5 = CellGridBase<LG_Grid, LG_Tile, LG_Cell>.Create(cellSize, val3);
			((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)val5).SetupCells(gridSize, gridSize);
			((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)val5).InititalizeCells();
			int count = __instance.m_dimensions.Count;
			Dimension val6 = new Dimension(val5, dimensionIndex, count, dimensionData, position, arenaDimension);
			DebugLog.LogPrefix((Object)(object)__instance, $"Created Dimension (Index: {dimensionIndex}, gridSize: {gridSize}, cellSize: {cellSize}).");
			val = val6.ResourceData.GetCustomGeomorph(dimensionData.DimensionGeomorph);
			if (block != null && config.TileOverrides[0].X == 0 && config.TileOverrides[0].Z == 0 && !string.IsNullOrEmpty(config.TileOverrides[0].Geomorph))
			{
				Object loadedAsset = AssetAPI.GetLoadedAsset(config.TileOverrides[0].Geomorph);
				val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).Cast<GameObject>() : null);
				Logger.Info($" - dim {dimensionIndex} elevator overriden! {((Object)val).name}");
			}
			if ((Object)(object)val == (Object)null)
			{
				DebugLog.LogPrefixError((Object)(object)__instance, $"<b><color=red>NULL ERROR</color></b> Could not get the Dimension Geomorph prefab for dimension {dimensionIndex}, are you using a resource set in the DimensionDataBlock that contains the Dimension Geomorph prefab under the \"Custom Geomorphs_Objective_1x1\" header?");
				__result = count;
				return false;
			}
			LG_FloorTransition val7 = __instance.CreateFloorTransition(((XXHashSequence)(ref val2)).NextSubSeed(), val6, position, Quaternion.identity, val, val6.DimensionData.IsStaticDimension);
			if ((Object)(object)val7 == (Object)null)
			{
				DebugLog.LogPrefixError((Object)(object)__instance, $"<b><color=red>NULL ERROR</color></b> The LG_FloorTransition of dimension {dimensionIndex} was null! Does the dimension prefab have a LG_FloorTransition component on its root?");
				__result = count;
				return false;
			}
			LG_Dimension val8 = ((Component)val7).GetComponent<LG_Dimension>();
			if ((Object)(object)val8 == (Object)null)
			{
				val8 = ((Component)val7).gameObject.AddComponent<LG_Dimension>();
				DebugLog.LogPrefixError((Object)(object)__instance, $"<b><color=red>NULL ERROR</color></b> The dimension {dimensionIndex} had no {typeof(LG_Dimension).Name} component, so added one automatically!");
			}
			val6.DimensionLevel = val8;
			if (val7.m_spawnPoints != null && ((Il2CppArrayBase<Transform>)(object)val7.m_spawnPoints).Length != 0)
			{
				val8.AddSpawnPoints(val7.m_spawnPoints);
			}
			val4.m_gridPosition = new LG_GridPosition(gridSize / 2, gridSize / 2);
			val4.m_type = val7.m_shapeType;
			AIG_GeomorphNodeVolume component = ((Component)val7).GetComponent<AIG_GeomorphNodeVolume>();
			if ((Object)(object)component == (Object)null)
			{
				DebugLog.LogPrefixError((Object)(object)__instance, $"<b><color=red>NULL ERROR</color></b> The Dimension Geomorph for {dimensionIndex} did not have a {typeof(AIG_GeomorphNodeVolume).Name} component on it!");
				__result = count;
				return false;
			}
			((LG_Geomorph)val7).m_nodeVolume = (AIG_NodeVolume)(object)component;
			((AIG_NodeVolume)component).ConstructVoxelNodeVolume();
			((LG_Geomorph)val7).ScanChildrenAreas();
			val6.m_startTile = LG_Tile.Create(val5, val4);
			val6.m_startTile.m_geoRoot = (LG_Geomorph)(object)val7;
			val6.m_startTile.m_geoRoot.m_tile = val6.m_startTile;
			((Component)val7).transform.SetParent(((Component)val6.DimensionRootTemp).transform);
			((LG_Geomorph)val7).m_tile = val6.m_startTile;
			val6.m_startTransition = val7;
			val6.Tiles.Add(val6.m_startTile);
			__instance.m_dimensions.Add(val6);
			__instance.m_indexToDimensionMap[dimensionIndex] = val6;
			__result = count;
			return false;
		}
	}
	[HarmonyPatch(typeof(LG_LoadComplexDataSetResourcesJob), "Build")]
	internal static class Inject_LoadComplexShard
	{
		private static int _waitingShared;

		private static void Prefix(LG_LoadComplexDataSetResourcesJob __instance)
		{
			//IL_0017: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0032: 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_003a: 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_0040: 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_003e: 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)
			if (__instance.m_loadingStarted)
			{
				return;
			}
			foreach (Complex item in BuilderInfo.ExtraComplexResourceToLoad)
			{
				AssetBundleName val = (AssetBundleName)((int)item switch
				{
					0 => 2, 
					1 => 4, 
					2 => 3, 
					_ => 0, 
				});
				if ((int)val != 0)
				{
					AssetShardManager.LoadAllShardsForBundleAsync(val, Action.op_Implicit((Action)Loaded), 1, (LoadSceneMode)1);
					_waitingShared++;
				}
			}
		}

		private static void Loaded()
		{
			_waitingShared--;
		}

		[HarmonyWrapSafe]
		private static void Postfix(LG_LoadComplexDataSetResourcesJob __instance, ref bool __result)
		{
			if (_waitingShared >= 1)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(LG_SetupFloor), "Build")]
	internal static class Inject_SetupFloor
	{
		private static LayoutConfig _configContext;

		[HarmonyPrefix]
		private static bool Prefix(LG_SetupFloor __instance, ref bool __result)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			LayoutConfig config = null;
			Debug.Log(Object.op_Implicit(Deb.LG("LG_SetupFloor.Build", 0f)));
			GameObject val = null;
			uint num = 0u;
			if (Builder.LayerBuildDatas[0].m_zoneBuildDatas != null && Builder.LayerBuildDatas[0].m_zoneBuildDatas.Count > 0)
			{
				_ = Builder.LayerBuildDatas[0].m_zoneBuildDatas[0].SubComplex;
				num = (uint)Builder.LayerBuildDatas[0].m_zoneBuildDatas[0].SubSeed;
			}
			XXHashSeed seed = __instance.m_rnd.Seed;
			XXHashSequence val2 = default(XXHashSequence);
			((XXHashSequence)(ref val2))..ctor(((XXHashSeed)(ref seed)).SubSeed(num), true);
			ConfigManager.TryGetConfig(RundownManager.ActiveExpedition.LevelLayoutData, out config);
			if (config == null)
			{
				return true;
			}
			LG_GridPosition val3 = default(LG_GridPosition);
			val3.x = 0;
			val3.z = 0;
			if (config.TileOverrides.Length == 0)
			{
				return true;
			}
			if (config.TileOverrides[0].X != 0 || config.TileOverrides[0].Z != 0)
			{
				return true;
			}
			if (!string.IsNullOrEmpty(config.TileOverrides[0].Geomorph))
			{
				Object loadedAsset = AssetAPI.GetLoadedAsset(config.TileOverrides[0].Geomorph);
				val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).Cast<GameObject>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Logger.Info("LGTuner failed to override elevator!");
					return true;
				}
				Logger.Info(" - elevator overriden! " + ((Object)val).name);
				LG_FloorTransition val4 = GOUtil.SpawnChildAndGetComp<LG_FloorTransition>(val, __instance.m_position, __instance.m_rotation);
				((LG_Geomorph)val4).m_geoPrefab = val;
				((LG_Geomorph)val4).SetupAreas(((XXHashSequence)(ref val2)).NextSubSeed());
				((LG_Geomorph)val4).SetPlaced();
				__instance.m_floor.Setup(((XXHashSequence)(ref val2)).NextSubSeed(), (LG_FloorType)0, Builder.ComplexResourceSetBlock.LevelGenConfig.TransitionDirection, val4);
				for (int i = 0; i < __instance.m_floor.m_dimensions.Count; i++)
				{
					__instance.m_floor.InjectJobs(__instance.m_floor.m_dimensions[i].DimensionIndex);
				}
				LG_Factory.InjectJob((LG_FactoryJob)new LG_BuildFloorJob(__instance.m_floor), (BatchName)7);
				__result = true;
				return false;
			}
			return true;
		}
	}
}
namespace LGTuner.Configs
{
	public sealed class LayoutConfig
	{
		private TileOverrideData[,] _builtTileOverrides = new TileOverrideData[0, 0];

		public uint LevelLayoutID { get; set; }

		public Complex[] ExtraComplexResourceToLoad { get; set; } = Array.Empty<Complex>();


		public ZoneOverrideData[] ZoneOverrides { get; set; } = Array.Empty<ZoneOverrideData>();


		public TileOverrideData[] TileOverrides { get; set; } = Array.Empty<TileOverrideData>();


		[JsonIgnore]
		public int GridSize { get; private set; }

		[JsonIgnore]
		public int GridSizeHalf { get; private set; }

		public void Reset(int gridSize)
		{
			Array.ForEach(ZoneOverrides, delegate(ZoneOverrideData item)
			{
				item.Clear();
			});
			Array.Clear(_builtTileOverrides, 0, _builtTileOverrides.Length);
			GridSize = gridSize;
			GridSizeHalf = gridSize / 2;
			_builtTileOverrides = new TileOverrideData[GridSize, GridSize];
			TileOverrideData[] tileOverrides = TileOverrides;
			foreach (TileOverrideData tileOverrideData in tileOverrides)
			{
				if (_builtTileOverrides[tileOverrideData.X + GridSizeHalf, tileOverrideData.Z + GridSizeHalf] == null)
				{
					PutOverrideData(tileOverrideData);
					continue;
				}
				Logger.Error($"Duplicate tile data in layout: {LevelLayoutID}, ({tileOverrideData.X}, {tileOverrideData.Z})!");
			}
		}

		public bool TryGetTileData(LG_GridPosition normalGridPosition, out TileOverrideData overrideData)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int num = normalGridPosition.x + GridSizeHalf;
			if (num >= GridSize)
			{
				Logger.Error($"TryGetTileData grid x was out of range! {num}:{GridSize}");
				overrideData = null;
				return false;
			}
			int num2 = normalGridPosition.z + GridSizeHalf;
			if (num2 >= GridSize)
			{
				Logger.Error($"TryGetTileData grid Z was out of range! {num2}:{GridSize}");
				overrideData = null;
				return false;
			}
			overrideData = _builtTileOverrides[num, num2];
			return overrideData != null;
		}

		public void PutOverrideData(TileOverrideData data)
		{
			_builtTileOverrides[data.X + GridSizeHalf, data.Z + GridSizeHalf] = data;
		}

		public TileOverrideData PopulateTileOverrideForZone(LG_Zone zone, LG_GridPosition normalGridPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetZoneOverride(zone.LocalIndex, out ZoneOverrideData data))
			{
				return null;
			}
			if (TryGetTileData(normalGridPosition, out TileOverrideData overrideData))
			{
				overrideData.ZoneData = data;
				TryApplyOverrides(data, overrideData);
				return overrideData;
			}
			TileOverrideData tileOverrideData = new TileOverrideData
			{
				ZoneData = data,
				X = normalGridPosition.x,
				Z = normalGridPosition.z,
				OverridePlugWithNoGateChance = data.OverridePlugWithNoGateChance,
				PlugWithNoGateChance = data.PlugWithNoGateChance
			};
			TryApplyOverrides(data, tileOverrideData);
			PutOverrideData(tileOverrideData);
			return tileOverrideData;
		}

		private void TryApplyOverrides(ZoneOverrideData zoneOverrideData, TileOverrideData tileOverrideData)
		{
			if (zoneOverrideData.OverrideGeomorphs && string.IsNullOrEmpty(tileOverrideData.Geomorph))
			{
				ZoneOverrideData.GeomorphData? nextGeo = zoneOverrideData.GetNextGeo();
				if (nextGeo.HasValue)
				{
					tileOverrideData.Geomorph = nextGeo.Value.Geomorph;
					if (tileOverrideData.Rotation == RotateType.None)
					{
						tileOverrideData.Rotation = ZoneOverrideData.DirectionToRotate(nextGeo.Value.Direction);
					}
				}
			}
			if (zoneOverrideData.OverrideAltitudes && !tileOverrideData.OverrideAltitude)
			{
				int? nextAltitude = zoneOverrideData.GetNextAltitude();
				if (nextAltitude.HasValue)
				{
					tileOverrideData.OverrideAltitude = true;
					tileOverrideData.Altitude = nextAltitude.Value;
				}
			}
		}

		public bool TryGetZoneOverride(eLocalZoneIndex localIndex, out ZoneOverrideData data)
		{
			//IL_0007: 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)
			data = ZoneOverrides.SingleOrDefault((ZoneOverrideData z) => z.LocalIndex == localIndex);
			return data != null;
		}
	}
	public sealed class TileOverrideData
	{
		public int X { get; set; }

		public int Z { get; set; }

		public bool OverrideAreaSeeds { get; set; }

		public uint[] AreaSeeds { get; set; } = Array.Empty<uint>();


		public RotateType Rotation { get; set; }

		public string Geomorph { get; set; } = string.Empty;


		public bool OverrideAltitude { get; set; }

		public int Altitude { get; set; }

		public string ForwardPlug { get; set; } = string.Empty;


		public string BackwardPlug { get; set; } = string.Empty;


		public string LeftPlug { get; set; } = string.Empty;


		public string RightPlug { get; set; } = string.Empty;


		public bool OverridePlugWithNoGateChance { get; set; }

		public float PlugWithNoGateChance { get; set; } = 0.5f;


		[JsonIgnore]
		public ZoneOverrideData ZoneData { get; set; }
	}
	public sealed class ZoneOverrideData
	{
		public enum Direction
		{
			Unchanged,
			Random,
			Forward,
			Backward,
			Left,
			Right
		}

		public struct GeomorphData
		{
			public string Geomorph { get; set; }

			public Direction Direction { get; set; }
		}

		private int _curGeomorphIndex;

		private int _curAltitudeIndex;

		private int _curPlugIndex;

		public eLocalZoneIndex LocalIndex { get; set; }

		public bool OverrideGeomorphs { get; set; }

		public GeomorphData[] Geomorphs { get; set; } = Array.Empty<GeomorphData>();


		public bool OverrideAltitudes { get; set; }

		public int[] Altitudes { get; set; } = Array.Empty<int>();


		public bool OverridePlugs { get; set; }

		public string[] Plugs { get; set; } = Array.Empty<string>();


		public bool OverridePlugWithNoGateChance { get; set; }

		public float PlugWithNoGateChance { get; set; } = 0.5f;


		public void Clear()
		{
			_curGeomorphIndex = 0;
			_curAltitudeIndex = 0;
			_curPlugIndex = 0;
		}

		public GeomorphData? GetNextGeo()
		{
			if (Geomorphs == null || Geomorphs.Length == 0)
			{
				return null;
			}
			return Geomorphs[_curGeomorphIndex++ % Geomorphs.Length];
		}

		public int? GetNextAltitude()
		{
			if (Altitudes == null || Altitudes.Length == 0)
			{
				return null;
			}
			return Altitudes[_curAltitudeIndex++ % Altitudes.Length];
		}

		public string GetNextPlug()
		{
			if (Plugs == null || Plugs.Length == 0)
			{
				return string.Empty;
			}
			return Plugs[_curPlugIndex++ % Plugs.Length];
		}

		public static RotateType DirectionToRotate(Direction direction)
		{
			return direction switch
			{
				Direction.Unchanged => RotateType.None, 
				Direction.Random => RotateType.Towards_Random, 
				Direction.Forward => RotateType.Towards_Forward, 
				Direction.Backward => RotateType.Towards_Backward, 
				Direction.Left => RotateType.Towards_Left, 
				Direction.Right => RotateType.Towards_Right, 
				_ => throw new NotImplementedException($"DirectionType: {direction} is not supported"), 
			};
		}
	}
}
namespace GTFR
{
	public class Datablock : MonoBehaviour
	{
		public static LevelLayoutDataBlock[] data = (LevelLayoutDataBlock[])(object)new LevelLayoutDataBlock[3];

		public static Datablock current;

		public static LevelLayoutDataBlock[] originalData;

		public static LevelLayoutDataBlock[] refData;

		public static string playerName;

		public static ComplexResourceSetDataBlock newComplexResource;

		public static Dictionary<string, Resource>[] complexDicts;

		public static float originalEnemyTotalCost;

		private Layout layOutRandomizer = new Layout();

		public Datablock()
		{
			current = this;
			originalEnemyTotalCost = EnemyCostManager.AllowedTotalCost;
			refData = Il2CppArrayBase<LevelLayoutDataBlock>.op_Implicit(GameDataBlockBase<LevelLayoutDataBlock>.GetAllBlocks());
			originalData = (LevelLayoutDataBlock[])(object)new LevelLayoutDataBlock[refData.Length];
			for (int i = 0; i < originalData.Length; i++)
			{
				try
				{
					originalData[i] = GameDataBlockBase<LevelLayoutDataBlock>.CreateNewCopy(refData[i]);
					LevelLayoutDataBlock obj = originalData[i];
					string name = ((GameDataBlockBase<LevelLayoutDataBlock>)(object)originalData[i]).name;
					((GameDataBlockBase<LevelLayoutDataBlock>)(object)obj).name = name.Substring(0, name.Length - 5);
				}
				catch
				{
					EntryPoint.LogIt("An original Datablock was Null so we're skipping");
				}
			}
			WeaponSwap();
			List<float> resourcePackSizes;
			List<float> obj3 = (resourcePackSizes = GameDataBlockBase<ExpeditionBalanceDataBlock>.GetBlock(1u).ResourcePackSizes);
			resourcePackSizes[0] = resourcePackSizes[0] * 2f;
			resourcePackSizes = obj3;
			resourcePackSizes[1] = resourcePackSizes[1] * 2f;
			resourcePackSizes = obj3;
			resourcePackSizes[2] = resourcePackSizes[2] * 2f;
			obj3.Add(2.4f);
			obj3.Add(3f);
			obj3.Add(3.2f);
			obj3.Add(4f);
		}

		public void Build()
		{
			layOutRandomizer.GetBlockAndBuild();
		}

		public static T[] Blocks<T>() where T : GameDataBlockBase<T>
		{
			return Il2CppArrayBase<T>.op_Implicit(GameDataBlockBase<T>.GetAllBlocks());
		}

		public static T Block<T>(uint id) where T : GameDataBlockBase<T>
		{
			return GameDataBlockBase<T>.GetBlock(id);
		}

		public static T Block<T>(string name) where T : GameDataBlockBase<T>
		{
			return GameDataBlockBase<T>.GetBlock(name);
		}

		public static T Copy<T>(T block) where T : GameDataBlockBase<T>
		{
			return GameDataBlockBase<T>.CreateNewCopy(block);
		}

		public static LevelLayoutDataBlock GetOrignalLevelLayout(string name)
		{
			for (int i = 0; i < originalData.Length; i++)
			{
				if (originalData[i] != null && ((GameDataBlockBase<LevelLayoutDataBlock>)(object)originalData[i]).name.Contains(name))
				{
					return originalData[i];
				}
			}
			return null;
		}

		public static void WeaponSwap()
		{
			Dictionary<string, WeaponCate> dictionary = new Dictionary<string, WeaponCate>();
			foreach (GearCategoryDataBlock allBlock in GameDataBlockBase<GearCategoryDataBlock>.GetAllBlocks())
			{
				uint baseItem = allBlock.BaseItem;
				if ((baseItem - 108 <= 2 || baseItem == 156) ? true : false)
				{
					GearCategoryDataBlock val2 = GameDataBlockBase<GearCategoryDataBlock>.CreateNewCopy(allBlock);
					switch (val2.BaseItem)
					{
					case 108u:
						val2.BaseItem = 109u;
						break;
					case 109u:
						val2.BaseItem = 108u;
						break;
					case 110u:
						val2.BaseItem = 156u;
						break;
					case 156u:
						val2.BaseItem = 110u;
						break;
					}
					dictionary[((GameDataBlockBase<GearCategoryDataBlock>)(object)allBlock).persistentID.ToString()] = new WeaponCate
					{
						id = ((GameDataBlockBase<GearCategoryDataBlock>)(object)val2).persistentID.ToString(),
						baseItem = val2.BaseItem.ToString(),
						toReplace = allBlock.BaseItem.ToString()
					};
				}
			}
			foreach (PlayerOfflineGearDataBlock allBlock2 in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks())
			{
				string[] array = allBlock2.GearJSON.Split(':');
				int num = -1;
				string text = "0";
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i].Contains("108") || array[i].Contains("109") || array[i].Contains("110") || array[i].Contains("156"))
					{
						num = i;
						break;
					}
				}
				if (num != -1)
				{
					PlayerOfflineGearDataBlock obj = GameDataBlockBase<PlayerOfflineGearDataBlock>.CreateNewCopy(allBlock2);
					string text2 = array[num - 3];
					WeaponCate weaponCate = dictionary[text2.Substring(0, text2.Length - 5)];
					int num2 = num - 3;
					string obj2 = array[num - 3];
					text2 = array[num - 3];
					array[num2] = obj2.Replace(text2.Substring(0, text2.Length - 5), weaponCate.id);
					array[num] = array[num].Replace(weaponCate.toReplace, weaponCate.baseItem);
					if (num == 14)
					{
						text2 = array[num - 6];
						text = text2.Substring(0, text2.Length - 5);
					}
					obj.GearJSON = string.Join(':', array);
					GearCategoryDataBlock block = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(uint.Parse(weaponCate.id));
					ArchetypeDataBlock val4 = GameDataBlockBase<ArchetypeDataBlock>.CreateNewCopy(GameDataBlockBase<ArchetypeDataBlock>.GetBlock(text switch
					{
						"0" => block.SemiArchetype, 
						"1" => block.BurstArchetype, 
						"2" => block.AutoArchetype, 
						_ => block.SemiBurstArchetype, 
					}));
					if (weaponCate.toReplace.Equals("108") || weaponCate.toReplace.Equals("156"))
					{
						val4.CostOfBullet *= 0.5f;
					}
					else if (weaponCate.toReplace.Equals("109") || weaponCate.toReplace.Equals("110"))
					{
						val4.CostOfBullet *= 1.5f;
					}
					switch (text)
					{
					case "0":
						block.SemiArchetype = ((GameDataBlockBase<ArchetypeDataBlock>)(object)val4).persistentID;
						break;
					case "1":
						block.BurstArchetype = ((GameDataBlockBase<ArchetypeDataBlock>)(object)val4).persistentID;
						break;
					case "2":
						block.AutoArchetype = ((GameDataBlockBase<ArchetypeDataBlock>)(object)val4).persistentID;
						break;
					default:
						block.SemiBurstArchetype = ((GameDataBlockBase<ArchetypeDataBlock>)(object)val4).persistentID;
						break;
					}
				}
			}
		}

		public static void ComplexResource()
		{
			newComplexResource = Datablock.Copy<ComplexResourceSetDataBlock>(Datablock.Block<ComplexResourceSetDataBlock>(92u));
			ComplexResourceSetDataBlock[] array = Datablock.Blocks<ComplexResourceSetDataBlock>();
			complexDicts = new Dictionary<string, Resource>[50];
			for (int i = 0; i < 50; i++)
			{
				complexDicts[i] = new Dictionary<string, Resource>();
			}
			int num = 0;
			ComplexResourceSetDataBlock[] array2 = array;
			foreach (ComplexResourceSetDataBlock obj in array2)
			{
				num = 0;
				PopulateComplexDate(obj.GeomorphTiles_1x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.GeomorphTiles_2x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.GeomorphTiles_2x2, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallWeakGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallSecurityGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallApexGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallMainPathBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallWallCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.SmallWallAndDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumWeakGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumSecurityGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumApexGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumMainPathBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumWallCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.MediumWallAndDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeWeakGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeSecurityGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeApexGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeMainPathBulkheadGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeWallCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.LargeWallAndDestroyedCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.StraightPlugsNoGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.StraightPlugsWithGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SingleDropPlugsNoGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.SingleDropPlugsWithGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.DoubleDropPlugsNoGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.DoubleDropPlugsWithGates, ref complexDicts, ref num);
				PopulateComplexDate(obj.PlugCaps, ref complexDicts, ref num);
				PopulateComplexDate(obj.ElevatorShafts_1x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.CustomGeomorphs_Exit_1x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.CustomGeomorphs_Objective_1x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.CustomGeomorphs_Challenge_1x1, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_4m, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_2m, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_1m, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_05m, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_Bottom, ref complexDicts, ref num);
				PopulateComplexDate(obj.Ladders_Top, ref complexDicts, ref num);
			}
			num = 0;
			newComplexResource.GeomorphTiles_1x1 = PopulateNewComplex(newComplexResource.GeomorphTiles_1x1, ref complexDicts, ref num);
			newComplexResource.GeomorphTiles_2x1 = PopulateNewComplex(newComplexResource.GeomorphTiles_2x1, ref complexDicts, ref num);
			newComplexResource.GeomorphTiles_2x2 = PopulateNewComplex(newComplexResource.GeomorphTiles_2x2, ref complexDicts, ref num);
			newComplexResource.SmallWeakGates = PopulateNewComplex(newComplexResource.SmallWeakGates, ref complexDicts, ref num);
			newComplexResource.SmallSecurityGates = PopulateNewComplex(newComplexResource.SmallSecurityGates, ref complexDicts, ref num);
			newComplexResource.SmallApexGates = PopulateNewComplex(newComplexResource.SmallApexGates, ref complexDicts, ref num);
			newComplexResource.SmallBulkheadGates = PopulateNewComplex(newComplexResource.SmallBulkheadGates, ref complexDicts, ref num);
			newComplexResource.SmallMainPathBulkheadGates = PopulateNewComplex(newComplexResource.SmallMainPathBulkheadGates, ref complexDicts, ref num);
			newComplexResource.SmallWallCaps = PopulateNewComplex(newComplexResource.SmallWallCaps, ref complexDicts, ref num);
			newComplexResource.SmallDestroyedCaps = PopulateNewComplex(newComplexResource.SmallDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.SmallWallAndDestroyedCaps = PopulateNewComplex(newComplexResource.SmallWallAndDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.MediumWeakGates = PopulateNewComplex(newComplexResource.MediumWeakGates, ref complexDicts, ref num);
			newComplexResource.MediumSecurityGates = PopulateNewComplex(newComplexResource.MediumSecurityGates, ref complexDicts, ref num);
			newComplexResource.MediumApexGates = PopulateNewComplex(newComplexResource.MediumApexGates, ref complexDicts, ref num);
			newComplexResource.MediumBulkheadGates = PopulateNewComplex(newComplexResource.MediumBulkheadGates, ref complexDicts, ref num);
			newComplexResource.MediumMainPathBulkheadGates = PopulateNewComplex(newComplexResource.MediumMainPathBulkheadGates, ref complexDicts, ref num);
			newComplexResource.MediumWallCaps = PopulateNewComplex(newComplexResource.MediumWallCaps, ref complexDicts, ref num);
			newComplexResource.MediumDestroyedCaps = PopulateNewComplex(newComplexResource.MediumDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.MediumWallAndDestroyedCaps = PopulateNewComplex(newComplexResource.MediumWallAndDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.LargeWeakGates = PopulateNewComplex(newComplexResource.LargeWeakGates, ref complexDicts, ref num);
			newComplexResource.LargeSecurityGates = PopulateNewComplex(newComplexResource.LargeSecurityGates, ref complexDicts, ref num);
			newComplexResource.LargeApexGates = PopulateNewComplex(newComplexResource.LargeApexGates, ref complexDicts, ref num);
			newComplexResource.LargeBulkheadGates = PopulateNewComplex(newComplexResource.LargeBulkheadGates, ref complexDicts, ref num);
			newComplexResource.LargeMainPathBulkheadGates = PopulateNewComplex(newComplexResource.LargeMainPathBulkheadGates, ref complexDicts, ref num);
			newComplexResource.LargeWallCaps = PopulateNewComplex(newComplexResource.LargeWallCaps, ref complexDicts, ref num);
			newComplexResource.LargeDestroyedCaps = PopulateNewComplex(newComplexResource.LargeDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.LargeWallAndDestroyedCaps = PopulateNewComplex(newComplexResource.LargeWallAndDestroyedCaps, ref complexDicts, ref num);
			newComplexResource.StraightPlugsNoGates = PopulateNewComplex(newComplexResource.StraightPlugsNoGates, ref complexDicts, ref num);
			newComplexResource.StraightPlugsWithGates = PopulateNewComplex(newComplexResource.StraightPlugsWithGates, ref complexDicts, ref num);
			newComplexResource.SingleDropPlugsNoGates = PopulateNewComplex(newComplexResource.SingleDropPlugsNoGates, ref complexDicts, ref num);
			newComplexResource.SingleDropPlugsWithGates = PopulateNewComplex(newComplexResource.SingleDropPlugsWithGates, ref complexDicts, ref num);
			newComplexResource.DoubleDropPlugsNoGates = PopulateNewComplex(newComplexResource.DoubleDropPlugsNoGates, ref complexDicts, ref num);
			newComplexResource.DoubleDropPlugsWithGates = PopulateNewComplex(newComplexResource.DoubleDropPlugsWithGates, ref complexDicts, ref num);
			newComplexResource.PlugCaps = PopulateNewComplex(newComplexResource.PlugCaps, ref complexDicts, ref num);
			newComplexResource.ElevatorShafts_1x1 = PopulateNewComplex(newComplexResource.ElevatorShafts_1x1, ref complexDicts, ref num);
			newComplexResource.CustomGeomorphs_Exit_1x1 = PopulateNewComplex(newComplexResource.CustomGeomorphs_Exit_1x1, ref complexDicts, ref num);
			newComplexResource.CustomGeomorphs_Objective_1x1 = PopulateNewComplex(newComplexResource.CustomGeomorphs_Objective_1x1, ref complexDicts, ref num);
			newComplexResource.CustomGeomorphs_Challenge_1x1 = PopulateNewComplex(newComplexResource.CustomGeomorphs_Challenge_1x1, ref complexDicts, ref num);
			newComplexResource.Ladders_4m = PopulateNewComplex(newComplexResource.Ladders_4m, ref complexDicts, ref num);
			newComplexResource.Ladders_2m = PopulateNewComplex(newComplexResource.Ladders_2m, ref complexDicts, ref num);
			newComplexResource.Ladders_1m = PopulateNewComplex(newComplexResource.Ladders_1m, ref complexDicts, ref num);
			newComplexResource.Ladders_05m = PopulateNewComplex(newComplexResource.Ladders_05m, ref complexDicts, ref num);
			newComplexResource.Ladders_Bottom = PopulateNewComplex(newComplexResource.Ladders_Bottom, ref complexDicts, ref num);
			newComplexResource.Ladders_Top = PopulateNewComplex(newComplexResource.Ladders_Top, ref complexDicts, ref num);
		}

		public static void PopulateComplexDate(List<ResourceData> datas, ref Dictionary<string, Resource>[] dict, ref int index)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected I4, but got Unknown
			//IL_0032: Expected I4, but got Unknown
			Enumerator<ResourceData> enumerator = datas.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ResourceData val = enumerator.Current;
				dict[index][val.Prefab] = new Resource(val.Prefab, (int)val.SubComplex, (int)val.Shard);
			}
			index++;
		}

		public static List<ResourceData> PopulateNewComplex(List<ResourceData> datas, ref Dictionary<string, Resource>[] dict, ref int index)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			datas.Clear();
			foreach (string key in dict[index].Keys)
			{
				ResourceData val = new ResourceData();
				val.Prefab = dict[index][key].prefab;
				val.SubComplex = (SubComplex)dict[index][key].subcomplex;
				val.Shard = (AssetBundleShard)dict[index][key].shard;
				datas.Add(val);
			}
			index++;
			return datas;
		}
	}
	public struct Resource
	{
		public string prefab;

		public int subcomplex;

		public int shard;

		public Resource(string prefab, int subcomplex, int shard)
		{
			this.prefab = prefab;
			this.subcomplex = 5;
			this.shard = shard;
		}
	}
	internal struct WeaponCate
	{
		public string id;

		public string baseItem;

		public string toReplace;

		public WeaponCate(string id, string baseItem, string toReplace)
		{
			this.id = id;
			this.baseItem = baseItem;
			this.toReplace = toReplace;
		}
	}
	public static class Detour
	{
		public unsafe delegate void StaticVoidDelegate(Il2CppMethodInfo* methodInfo);

		public unsafe delegate void InstanceVoidDelegate(IntPtr instance, Il2CppMethodInfo* methodInfo);

		public static bool TryCreate<T>(DetourDescription description, T to, out T originalCall, out INativeDetour detourInstance) where T : Delegate
		{
			try
			{
				detourInstance = INativeDetour.CreateAndApply<T>((IntPtr)description.GetMethodPointer(), to, ref originalCall);
				return detourInstance != null;
			}
			catch
			{
			}
			originalCall = null;
			detourInstance = null;
			return false;
		}
	}
	public struct DetourDescription
	{
		public Type Type;

		public Type ReturnType;

		public Type[] ArgTypes;

		public string MethodName;

		public bool IsGeneric;

		public unsafe nint GetMethodPointer()
		{
			if (Type == null)
			{
				throw new MissingFieldException("Field Type is not set!");
			}
			if (ReturnType == null)
			{
				throw new MissingFieldException("Field ReturnType is not set! If you mean 'void' do typeof(void)");
			}
			if (string.IsNullOrEmpty(MethodName))
			{
				throw new MissingFieldException("Field MethodName is not set or valid!");
			}
			Il2CppType.From(Type, true);
			IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(Type);
			Type val = Il2CppType.From(ReturnType, true);
			Type[] array;
			if (ArgTypes == null || ArgTypes.Length == 0)
			{
				array = Array.Empty<Type>();
			}
			else
			{
				int num = ArgTypes.Length;
				array = (Type[])(object)new Type[num];
				for (int i = 0; i < num; i++)
				{
					Type type = ArgTypes[i];
					array[i] = Il2CppType.From(type, true);
				}
			}
			string[] array2 = array.Select((Type t) => t.FullName).ToArray();
			void** ptr = (void**)IL2CPP.GetIl2CppMethod(nativeClassPointer, IsGeneric, MethodName, val.FullName, array2).ToPointer();
			if (ptr == null)
			{
				return (nint)ptr;
			}
			return (nint)(*ptr);
		}
	}
	[BepInPlugin("JishWasha.GTFR", "GTFR", "0.2.3")]
	public class EntryPoint : BasePlugin
	{
		public static ConfigEntry<bool> GeosRandom;

		public static ConfigEntry<bool> bioScans;

		public static ConfigEntry<bool> movingScans;

		public static ConfigEntry<bool> BloodDoors;

		public static ConfigEntry<bool> Enemy;

		public static ConfigEntry<bool> EnemyScale;

		public static ConfigEntry<bool> EnemyBirth;

		public static ConfigEntry<bool> chaosRando;

		public static ConfigEntry<bool> spittersRando;

		public static ConfigEntry<bool> itemsRando;

		public static ConfigEntry<bool> eventRando;

		public static int configLevel;

		public static ConfigFile configFile;

		public static EntryPoint e;

		public override void Load()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			e = this;
			Harmony val = new Harmony("JishWasha.GTFR");
			ClassInjector.RegisterTypeInIl2Cpp<Datablock>();
			ClassInjector.RegisterTypeInIl2Cpp<MovingScanAI>();
			Action<ulong, pScanPos> action = delegate(ulong _, pScanPos data)
			{
				ScansReplicator.UpdateScanPosition(data);
			};
			NetworkAPI.RegisterEvent<pScanPos>("UpdateScanPosition", action);
			LogIt("Scans setting up to be synced");
			LogIt("Levels are ready to be EvilWasha");
			GetTheSettings();
			ResourcePack.CreateDetour();
			val.PatchAll();
		}

		public static void GetTheSettings()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "JishWasha.GTFR.cfg"), true);
			GeosRandom = configFile.Bind<bool>("Setup", "GeosRandom", true, "Toggle for Geomorphs --- Everyone must have the same config in order to drop");
			bioScans = configFile.Bind<bool>("Setup", "bioScans", true, "Bioscans Rando");
			movingScans = configFile.Bind<bool>("Setup", "movingScans", true, "Bioscans Rando");
			BloodDoors = configFile.Bind<bool>("Setup", "BloodDoors", true, "Toggle for Blood Doors");
			Enemy = configFile.Bind<bool>("Setup", "Enemy", false, "Toggle for enemies spawning");
			EnemyScale = configFile.Bind<bool>("Setup", "EnemyScale", true, "Toggle for enemies Scale");
			EnemyBirth = configFile.Bind<bool>("Setup", "EnemyBirth", true, "Toggle for Mom and scout random wave");
			chaosRando = configFile.Bind<bool>("Setup", "chaosRando", false, "Chaos Jish rando >__<");
			spittersRando = configFile.Bind<bool>("Setup", "spittersRando", false, "evil Spitters being random");
			itemsRando = configFile.Bind<bool>("Setup", "itemsRando", false, "Toggle for da babies that are not yours");
			eventRando = configFile.Bind<bool>("Setup", "eventRando", false, "Toggle to take the red pills and randomize events");
			Geos.randomize = GeosRandom.Value;
			BioScans.randomize = bioScans.Value;
			ScanPatch.randomize = movingScans.Value;
			Enemies.randoBloodDoors = BloodDoors.Value;
			Enemies.randoEnemy = Enemy.Value;
			EnemyPatch.random = EnemyBirth.Value;
			EnemySpawnPatch.random = EnemyScale.Value;
			Spitters.randomize = spittersRando.Value;
			ItemsRandomizer.randomize = itemsRando.Value;
			LevelDesignRando.randomize = chaosRando.Value;
			Events.randomize = eventRando.Value;
		}

		public static int ConfigToBinary()
		{
			string text = "";
			configLevel = 0;
			text += "1";
			text += (GeosRandom.Value ? "1" : "0");
			text += (bioScans.Value ? "1" : "0");
			text += (movingScans.Value ? "1" : "0");
			text += (BloodDoors.Value ? "1" : "0");
			text += (Enemy.Value ? "1" : "0");
			text += (EnemyBirth.Value ? "1" : "0");
			text += (EnemyScale.Value ? "1" : "0");
			text += (chaosRando.Value ? "1" : "0");
			text += (spittersRando.Value ? "1" : "0");
			text += (itemsRando.Value ? "1" : "0");
			text += (eventRando.Value ? "1" : "0");
			text += "1";
			string text2 = text;
			foreach (char c in text2)
			{
				configLevel += (int)char.GetNumericValue(c);
			}
			LogIt("HostID: " + (int)Convert.ToInt64(text, 2));
			return (int)Convert.ToInt64(text, 2);
		}

		public static void BinaryToConfig(int num)
		{
			string text = Convert.ToString(num, 2);
			LogIt("Config is: " + text);
			Geos.randomize = text[1] == '1';
			BioScans.randomize = text[2] == '1';
			ScanPatch.randomize = text[3] == '1';
			Enemies.randoBloodDoors = text[4] == '1';
			Enemies.randoEnemy = text[5] == '1';
			EnemyPatch.random = text[6] == '1';
			EnemySpawnPatch.random = text[7] == '1';
			LevelDesignRando.randomize = text[8] == '1';
			Spitters.randomize = text[9] == '1';
			ItemsRandomizer.randomize = text[10] == '1';
			Events.randomize = text[11] == '1';
		}

		public static void LogIt(object data)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			ManualLogSource log = ((BasePlugin)e).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(0, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(data);
			}
			log.LogInfo(val);
		}

		public override bool Unload()
		{
			return ((BasePlugin)this).Unload();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "JishWasha.GTFR";

		public const string PLUGIN_NAME = "GTFR";

		public const string PLUGIN_VERSION = "0.2.3";

		public const string AUTHOR = "time1pm/Jish/microchips-n-dips";

		public const string BRANCH = "OpenBeta";

		public const string INTERNAL_VERSION = "002346";
	}
	[HarmonyPatch]
	public class Initializer
	{
		public static int hostID;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartMainGame), "Start")]
		private static void StartData(StartMainGame __instance)
		{
			((Component)__instance).gameObject.AddComponent<Datablock>();
			ScansReplicator.scans = new List<MovingScanAI>();
			EntryPoint.LogIt("datablock is LOADED");
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")]
		public static void SetActiveExp(ref pActiveExpedition expPackage, ref ExpeditionInTierData expTierData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			Layout.tierLevel = (int)expPackage.tier;
			expTierData.MainLayerData.ArtifactData.ArtifactAmountMulti = 0f;
			EntryPoint.GetTheSettings();
			expTierData.Seeds.BuildSeed = new Random(expPackage.sessionSeed).Next(100000000, int.MaxValue);
			if (SNet.IsMaster)
			{
				expPackage.hostIDSeed = EntryPoint.ConfigToBinary();
				hostID = expPackage.hostIDSeed;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")]
		public static void GetSeeds(ref pActiveExpedition expPackage, ref ExpeditionInTierData expTierData)
		{
			BigPickUpPatch.seed = expPackage.sessionSeed;
			EntryPoint.LogIt("Session: " + expTierData.SessionSeed + " HostID: " + expTierData.HostIDSeed);
			BuildPatch.offSeed = 0u;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ExpeditionInTierData), "SetSeeds")]
		public static void SetHostSeed(ref int hostIDSeed)
		{
			if (!SNet.IsMaster)
			{
				hostID = hostIDSeed;
			}
			BuildPatch.offSeed = 0u;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Builder), "Build")]
		public static void BuildNewLevel()
		{
			EntryPoint.BinaryToConfig(hostID);
			ScansReplicator.scans.Clear();
			Datablock.current.Build();
		}
	}
}
namespace GTFR.Structs
{
	internal struct Danger
	{
		private float danger;

		private float enenmyDanger;

		private float costDanger;

		private static Danger current;

		public Danger()
		{
			danger = 0f;
			enenmyDanger = 0f;
			costDanger = 0f;
			current = this;
		}

		public static void Add(float amount)
		{
			current.danger += amount;
		}

		public static float Level()
		{
			current.costDanger = (EnemyCostManager.AllowedTotalCost - Datablock.originalEnemyTotalCost) / 100f * 3f;
			current.enenmyDanger = current.danger / 100f * 2f;
			return current.costDanger + current.enenmyDanger;
		}

		public static float ResMulti()
		{
			return 1f + Level() * 1.1f;
		}
	}
	public struct EnemyPop
	{
		public float cost;

		public float health;

		public EnemyPop(float cost, float health)
		{
			this.cost = cost;
			this.health = health;
		}
	}
	public enum EnemyRandomConfig
	{
		Normal,
		Rando,
		Evil,
		Jish
	}
	public enum TrueRandoConfig
	{
		Normal,
		EvilRando
	}
	public enum SpitterConfig
	{
		Normal,
		DecentAmount,
		ALOT
	}
	public enum BioScansConfig
	{
		Normal,
		Rando,
		HardRando
	}
	public struct LRandom
	{
		private Random random;

		private static LRandom current;

		public LRandom()
		{
			random = new Random(RundownManager.ActiveExpedition.SessionSeed);
			current = this;
		}

		public static int Next(int max)
		{
			return current.random.Next(max);
		}

		public static int Next(int min, int max)
		{
			return current.random.Next(min, max);
		}
	}
	public struct pScanPos
	{
		public int m_index;

		public Vector3 m_position;
	}
	public struct Rando
	{
		private Random random;

		private static Rando current;

		public Rando()
		{
			random = new Random(RundownManager.ActiveExpedition.SessionSeed + (int)BuildPatch.offSeed);
			current = this;
		}

		public static int Next(int max)
		{
			return current.random.Next(max);
		}

		public static int Next(int min, int max)
		{
			return current.random.Next(min, max);
		}
	}
}
namespace GTFR.Randomizers
{
	internal class Balance : Randomizer
	{
		public void Finalize(List<ExpeditionZoneData> zones, List<ExpeditionZoneData> ogZones)
		{
			CuratedException();
			RebalanceBoxes();
		}

		private void RebalanceBoxes()
		{
			int tierLevel = Layout.tierLevel;
			EnemyCostManager.AllowedTotalCost = Datablock.originalEnemyTotalCost + (float)(41 - 40 / tierLevel);
			EntryPoint.LogIt("Danger Level: " + (1f + Danger.Level()) * 100f + "%");
			LevelLayoutDataBlock[] data = Datablock.data;
			foreach (LevelLayoutDataBlock val in data)
			{
				if (val == null)
				{
					continue;
				}
				Enumerator<ExpeditionZoneData> enumerator = val.Zones.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ExpeditionZoneData current = enumerator.Current;
					if (current.BigPickupDistributionInZone == 10 || current.EventsOnPortalWarp.Count > 0)
					{
						EntryPoint.LogIt("There's MWP, we're skipping");
						continue;
					}
					float num = 0.2f * (float)tierLevel;
					current.ToolAmmoMulti = Mathf.Clamp(current.ToolAmmoMulti, num, 100f);
					current.WeaponAmmoMulti = Mathf.Clamp(current.WeaponAmmoMulti, num, 100f);
					current.HealthMulti = Mathf.Clamp(current.HealthMulti, num, 100f);
					current.DisinfectionMulti = Mathf.Clamp(current.DisinfectionMulti, 0.2f, 100f);
					float num2 = Danger.ResMulti();
					current.ToolAmmoMulti *= num2;
					current.WeaponAmmoMulti *= num2;
					current.HealthMulti *= num2;
					current.DisinfectionMulti *= num2;
					if (tierLevel > 2)
					{
						current.ToolAmmoMulti += (float)tierLevel;
						current.WeaponAmmoMulti += (float)tierLevel;
						current.HealthMulti += (float)tierLevel;
						current.DisinfectionMulti += (float)tierLevel;
					}
				}
			}
		}

		private void CuratedException()
		{
			LevelLayoutDataBlock val = Datablock.Block<LevelLayoutDataBlock>(RundownManager.ActiveExpedition.LevelLayoutData);
			if (((GameDataBlockBase<LevelLayoutDataBlock>)(object)val).name.Contains("R7_D2_MainframeRush"))
			{
				val.Zones[11].AltitudeData.AllowedZoneAltitude = (eWantedZoneHeighs)9;
				val.Zones[11].AltitudeData.ChanceToChange = 0f;
				val.Zones[11].ForbidTerminalsInZone = true;
			}
		}
	}
	internal struct BioScan
	{
		public uint id;

		public int numScans;

		public float difficulty;

		public BioScan(ChainedPuzzleDataBlock puzzle)
		{
			id = ((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)puzzle).persistentID;
			numScans = puzzle.ChainedPuzzle.Count;
			if (numScans == 0)
			{
				numScans = 1;
			}
			difficulty = PuzzleDifficulty(puzzle);
		}

		public static float ScanDifficulty(uint scanType)
		{
			switch (scanType)
			{
			case 3u:
				return -0.5f;
			case 5u:
			case 8u:
			case 14u:
				return 0.25f;
			case 6u:
			case 20u:
				return 0.5f;
			case 25u:
			case 26u:
			case 27u:
			case 28u:
			case 29u:
				return 0.75f;
			case 13u:
			case 16u:
			case 32u:
				return 1f;
			case 15u:
				return 1.5f;
			case 33u:
			case 34u:
			case 35u:
			case 36u:
			case 37u:
				return 2f;
			case 17u:
			case 18u:
				return 2f;
			case 40u:
			case 44u:
				return 2f;
			default:
				return 0f;
			}
		}

		public static float PuzzleDifficulty(ChainedPuzzleDataBlock puzzle)
		{
			float num = 0f;
			Enumerator<ChainedPuzzleComponent> enumerator = puzzle.ChainedPuzzle.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ChainedPuzzleComponent current = enumerator.Current;
				num += ScanDifficulty(current.PuzzleType);
			}
			return num;
		}

		public static bool IsInvalid(ChainedPuzzleDataBlock puzzle)
		{
			Enumerator<ChainedPuzzleComponent> enumerator = puzzle.ChainedPuzzle.GetEnumerator();
			while (enumerator.MoveNext())
			{
				bool flag;
				switch (enumerator.Current.PuzzleType)
				{
				case 10u:
				case 11u:
				case 12u:
				case 21u:
				case 22u:
				case 24u:
				case 31u:
				case 38u:
				case 42u:
				case 43u:
					flag = true;
					break;
				default:
					flag = false;
					break;
				}
				if (flag)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal class BioScans : Randomizer
	{
		public static List<BioScan>[] bioscans = new List<BioScan>[15];

		private Dictionary<uint, int> scanCounts = new Dictionary<uint, int>();

		public static bool randomize = true;

		public BioScans()
		{
			for (int i = 0; i < bioscans.Length; i++)
			{
				bioscans[i] = new List<BioScan>();
			}
			scanCounts[0u] = 1;
			ChainedPuzzleDataBlock[] array = Datablock.Blocks<ChainedPuzzleDataBlock>();
			foreach (ChainedPuzzleDataBlock puzzle in array)
			{
				if (!BioScan.IsInvalid(puzzle))
				{
					BioScan item = new BioScan(puzzle);
					bioscans[item.numScans].Add(item);
					scanCounts[item.id] = item.numScans;
				}
			}
		}

		public void Randomize(ExpeditionZoneData zone, ExpeditionZoneData original, int index)
		{
			if (randomize)
			{
				CreateScanInZone(zone);
			}
		}

		public void CreateScanInZone(ExpeditionZoneData zone)
		{
			int num;
			try
			{
				num = Math.Clamp(scanCounts[zone.ChainedPuzzleToEnter] + Rando.Next(5) - 2, 1, 14);
			}
			catch
			{
				return;
			}
			while (bioscans[num].Count == 0)
			{
				num--;
			}
			BioScan bioScan = bioscans[num][Rando.Next(bioscans[num].Count)];
			zone.ChainedPuzzleToEnter = bioScan.id;
			Danger.Add(bioScan.difficulty);
			if (ScanPatch.randomize)
			{
				Danger.Add(0.1f);
			}
			EntryPoint.LogI