Decompiled source of DungeonGenerationPlus v1.5.1

DunGenPlus.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Adapters;
using DunGen.Collision;
using DunGen.Graph;
using DunGenPlus.Attributes;
using DunGenPlus.Collections;
using DunGenPlus.Components;
using DunGenPlus.Components.Props;
using DunGenPlus.Components.Scrap;
using DunGenPlus.Components.Scripting;
using DunGenPlus.DevTools;
using DunGenPlus.DevTools.HoverUI;
using DunGenPlus.DevTools.Panels;
using DunGenPlus.DevTools.Panels.Collections;
using DunGenPlus.DevTools.UIElements;
using DunGenPlus.DevTools.UIElements.Collections;
using DunGenPlus.Generation;
using DunGenPlus.Managers;
using DunGenPlus.Patches;
using DunGenPlus.Utils;
using HarmonyLib;
using LethalLevelLoader;
using Soukoku.ExpressionParser;
using Soukoku.ExpressionParser.Parsing;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DunGenPlus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DunGenPlus")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("13cde60e-1975-463b-9da1-ccb3f3ebabd8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Soukoku.ExpressionParser
{
	public class EvaluationContext
	{
		private static Dictionary<string, FunctionRoutine> BuiltInFunctions = new Dictionary<string, FunctionRoutine>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"pow",
				new FunctionRoutine(2, (EvaluationContext ctx, ExpressionToken[] args) => new ExpressionToken(Math.Pow(args[0].ToDouble(ctx), args[1].ToDouble(ctx)).ToString(ctx.FormatCulture)))
			},
			{
				"sin",
				new FunctionRoutine(1, (EvaluationContext ctx, ExpressionToken[] args) => new ExpressionToken(Math.Sin(args[0].ToDouble(ctx)).ToString(ctx.FormatCulture)))
			},
			{
				"cos",
				new FunctionRoutine(1, (EvaluationContext ctx, ExpressionToken[] args) => new ExpressionToken(Math.Cos(args[0].ToDouble(ctx)).ToString(ctx.FormatCulture)))
			},
			{
				"tan",
				new FunctionRoutine(1, (EvaluationContext ctx, ExpressionToken[] args) => new ExpressionToken(Math.Tan(args[0].ToDouble(ctx)).ToString(ctx.FormatCulture)))
			}
		};

		private static readonly Dictionary<string, FunctionRoutine> __staticFuncs = new Dictionary<string, FunctionRoutine>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, FunctionRoutine> _instanceFuncs = new Dictionary<string, FunctionRoutine>(StringComparer.OrdinalIgnoreCase);

		private Func<string, (object, ValueTypeHint)> _fieldLookup;

		private readonly CultureInfo _usCulture = new CultureInfo("en-US");

		private CultureInfo _formatCulture = null;

		public CultureInfo FormatCulture
		{
			get
			{
				return _formatCulture ?? _usCulture;
			}
			set
			{
				_formatCulture = value;
			}
		}

		public EvaluationContext()
		{
		}

		public EvaluationContext(Func<string, (object Value, ValueTypeHint TypeHint)> fieldLookupRoutine)
		{
			_fieldLookup = fieldLookupRoutine;
		}

		public (object Value, ValueTypeHint TypeHint) ResolveFieldValue(string field)
		{
			if (_fieldLookup != null)
			{
				return _fieldLookup(field);
			}
			return OnResolveFieldValue(field);
		}

		protected virtual (object Value, ValueTypeHint TypeHint) OnResolveFieldValue(string field)
		{
			return (string.Empty, ValueTypeHint.Auto);
		}

		public static void RegisterGlobalFunction(string functionName, FunctionRoutine info)
		{
			__staticFuncs[functionName] = info;
		}

		public void RegisterFunction(string functionName, FunctionRoutine info)
		{
			_instanceFuncs[functionName] = info;
		}

		public FunctionRoutine GetFunction(string functionName)
		{
			if (_instanceFuncs.ContainsKey(functionName))
			{
				return _instanceFuncs[functionName];
			}
			if (__staticFuncs.ContainsKey(functionName))
			{
				return __staticFuncs[functionName];
			}
			if (BuiltInFunctions.ContainsKey(functionName))
			{
				return BuiltInFunctions[functionName];
			}
			return OnGetFunction(functionName) ?? throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Function \"{0}\" is not supported.", functionName));
		}

		protected virtual FunctionRoutine OnGetFunction(string functionName)
		{
			return null;
		}
	}
	public class Evaluator
	{
		private EvaluationContext _context;

		private Stack<ExpressionToken> _stack;

		public Evaluator(EvaluationContext context)
		{
			_context = context ?? throw new ArgumentNullException("context");
		}

		public ExpressionToken Evaluate(string input, bool coerseToBoolean = false)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return coerseToBoolean ? ExpressionToken.False : new ExpressionToken(input);
			}
			ExpressionToken[] array = new InfixToPostfixTokenizer().Tokenize(input);
			foreach (ExpressionToken item in array.Where((ExpressionToken tk) => tk.TokenType == ExpressionTokenType.Field))
			{
				item.FieldValue = _context.ResolveFieldValue(item.Value);
			}
			ListReader<ExpressionToken> listReader = new ListReader<ExpressionToken>(array);
			_stack = new Stack<ExpressionToken>();
			while (!listReader.IsEnd)
			{
				ExpressionToken expressionToken = listReader.Read();
				switch (expressionToken.TokenType)
				{
				case ExpressionTokenType.Field:
				case ExpressionTokenType.SingleQuoted:
				case ExpressionTokenType.DoubleQuoted:
				case ExpressionTokenType.Value:
					_stack.Push(expressionToken);
					break;
				case ExpressionTokenType.Operator:
					HandleOperator(expressionToken.OperatorType);
					break;
				case ExpressionTokenType.Function:
					HandleFunction(expressionToken.Value);
					break;
				}
			}
			if (_stack.Count == 1)
			{
				ExpressionToken expressionToken2 = _stack.Pop();
				if (coerseToBoolean)
				{
					return ConvertTokenToFalseTrue(expressionToken2);
				}
				return expressionToken2;
			}
			throw new NotSupportedException("Unbalanced expression.");
		}

		public ExpressionToken ConvertTokenToFalseTrue(ExpressionToken token)
		{
			if (IsFalse(token.ToString()))
			{
				return ExpressionToken.False;
			}
			return ExpressionToken.True;
		}

		private void HandleFunction(string functionName)
		{
			FunctionRoutine function = _context.GetFunction(functionName);
			Stack<ExpressionToken> stack = new Stack<ExpressionToken>(function.ArgumentCount);
			while (stack.Count < function.ArgumentCount)
			{
				stack.Push(_stack.Pop());
			}
			_stack.Push(function.Evaluate(_context, stack.ToArray()));
		}

		private static bool IsDate(string lhs, string rhs, out DateTime lhsDate, out DateTime rhsDate)
		{
			lhsDate = default(DateTime);
			rhsDate = default(DateTime);
			if (DateTime.TryParse(lhs, out lhsDate))
			{
				DateTime.TryParse(rhs, out rhsDate);
				return true;
			}
			if (DateTime.TryParse(rhs, out rhsDate))
			{
				DateTime.TryParse(lhs, out lhsDate);
				return true;
			}
			return false;
		}

		private bool IsNumber(string lhs, string rhs, out decimal lhsNumber, out decimal rhsNumber)
		{
			lhsNumber = default(decimal);
			rhsNumber = default(decimal);
			bool flag = decimal.TryParse(lhs, ExpressionToken.NumberParseStyle, _context.FormatCulture, out lhsNumber);
			bool flag2 = decimal.TryParse(rhs, ExpressionToken.NumberParseStyle, _context.FormatCulture, out rhsNumber);
			return flag && flag2;
		}

		private static bool IsBoolean(string lhs, string rhs, out bool lhsBool, out bool rhsBool)
		{
			bool flag = false;
			bool flag2 = false;
			lhsBool = false;
			rhsBool = false;
			if (!string.IsNullOrEmpty(lhs))
			{
				if (string.Equals(lhs, "true", StringComparison.OrdinalIgnoreCase) || lhs == "1")
				{
					lhsBool = true;
					flag = true;
				}
				else if (string.Equals(lhs, "false", StringComparison.OrdinalIgnoreCase) || lhs == "0")
				{
					flag = true;
				}
			}
			if (flag && !string.IsNullOrEmpty(rhs))
			{
				if (string.Equals(rhs, "true", StringComparison.OrdinalIgnoreCase) || rhs == "1")
				{
					rhsBool = true;
					flag2 = true;
				}
				else if (string.Equals(rhs, "false", StringComparison.OrdinalIgnoreCase) || rhs == "0")
				{
					flag2 = true;
				}
			}
			return flag && flag2;
		}

		private void HandleOperator(OperatorType op)
		{
			decimal lhsNumber;
			decimal rhsNumber;
			bool lhsBool;
			bool rhsBool;
			switch (op)
			{
			case OperatorType.Addition:
				BinaryNumberOperation((decimal a, decimal b) => a + b);
				break;
			case OperatorType.Subtraction:
				BinaryNumberOperation((decimal a, decimal b) => a - b);
				break;
			case OperatorType.Multiplication:
				BinaryNumberOperation((decimal a, decimal b) => a * b);
				break;
			case OperatorType.Division:
				BinaryNumberOperation((decimal a, decimal b) => a / b);
				break;
			case OperatorType.Modulus:
				BinaryNumberOperation((decimal a, decimal b) => a % b);
				break;
			case OperatorType.LessThan:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate;
				DateTime rhsDate;
				if (IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber < rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate, out rhsDate))
				{
					_stack.Push((lhsDate < rhsDate) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) < 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.LessThanOrEqual:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate6;
				DateTime rhsDate6;
				if (IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber <= rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate6, out rhsDate6))
				{
					_stack.Push((lhsDate6 <= rhsDate6) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) <= 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.GreaterThan:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate2;
				DateTime rhsDate2;
				if (IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber > rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate2, out rhsDate2))
				{
					_stack.Push((lhsDate2 > rhsDate2) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) > 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.GreaterThanOrEqual:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate3;
				DateTime rhsDate3;
				if (IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber >= rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate3, out rhsDate3))
				{
					_stack.Push((lhsDate3 >= rhsDate3) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) >= 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.Equal:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate5;
				DateTime rhsDate5;
				if (IsBoolean(text2, text, out lhsBool, out rhsBool))
				{
					_stack.Push((lhsBool == rhsBool) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if ((AllowAutoFormat(expressionToken2) || AllowAutoFormat(expressionToken)) && IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber == rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate5, out rhsDate5))
				{
					_stack.Push((lhsDate5 == rhsDate5) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) == 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.NotEqual:
			{
				ExpressionToken expressionToken = _stack.Pop();
				ExpressionToken expressionToken2 = _stack.Pop();
				string text = expressionToken.ToString();
				string text2 = expressionToken2.ToString();
				DateTime lhsDate4;
				DateTime rhsDate4;
				if (IsBoolean(text2, text, out lhsBool, out rhsBool))
				{
					_stack.Push((lhsBool != rhsBool) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if ((AllowAutoFormat(expressionToken2) || AllowAutoFormat(expressionToken)) && IsNumber(text2, text, out lhsNumber, out rhsNumber))
				{
					_stack.Push((lhsNumber != rhsNumber) ? ExpressionToken.True : ExpressionToken.False);
				}
				else if (IsDate(text2, text, out lhsDate4, out rhsDate4))
				{
					_stack.Push((lhsDate4 != rhsDate4) ? ExpressionToken.True : ExpressionToken.False);
				}
				else
				{
					_stack.Push((string.Compare(text2, text, StringComparison.OrdinalIgnoreCase) != 0) ? ExpressionToken.True : ExpressionToken.False);
				}
				break;
			}
			case OperatorType.BitwiseAnd:
				BinaryNumberOperation((decimal a, decimal b) => (int)a & (int)b);
				break;
			case OperatorType.BitwiseOr:
				BinaryNumberOperation((decimal a, decimal b) => (int)a | (int)b);
				break;
			case OperatorType.LogicalAnd:
				BinaryLogicOperation((string a, string b) => IsTrue(a) && IsTrue(b));
				break;
			case OperatorType.LogicalOr:
				BinaryLogicOperation((string a, string b) => IsTrue(a) || IsTrue(b));
				break;
			case OperatorType.UnaryMinus:
				UnaryNumberOperation((decimal a) => -1m * a);
				break;
			case OperatorType.UnaryPlus:
				break;
			case OperatorType.LogicalNegation:
				UnaryLogicOperation((string a) => !IsTrue(a));
				break;
			case OperatorType.PreIncrement:
				UnaryNumberOperation((decimal a) => a + 1m);
				break;
			case OperatorType.PreDecrement:
				UnaryNumberOperation((decimal a) => a - 1m);
				break;
			default:
				throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "The {0} operation is not currently supported.", op));
			}
		}

		private static bool AllowAutoFormat(ExpressionToken token)
		{
			return token.TokenType != ExpressionTokenType.Field || token.FieldValue.TypeHint != ValueTypeHint.Text;
		}

		private static bool IsTrue(string value)
		{
			return string.Equals("true", value, StringComparison.OrdinalIgnoreCase) || value == "1";
		}

		private static bool IsFalse(string value)
		{
			return string.Equals("false", value, StringComparison.OrdinalIgnoreCase) || value == "0" || string.IsNullOrWhiteSpace(value);
		}

		private void UnaryNumberOperation(Func<decimal, decimal> operation)
		{
			decimal arg = _stack.Pop().ToDecimal(_context);
			decimal num = operation(arg);
			_stack.Push(new ExpressionToken(num.ToString(_context.FormatCulture)));
		}

		private void UnaryLogicOperation(Func<string, bool> operation)
		{
			ExpressionToken expressionToken = _stack.Pop();
			string value = (operation(expressionToken.ToString()) ? "1" : "0");
			_stack.Push(new ExpressionToken(value));
		}

		private void BinaryLogicOperation(Func<string, string, bool> operation)
		{
			ExpressionToken expressionToken = _stack.Pop();
			ExpressionToken expressionToken2 = _stack.Pop();
			string value = (operation(expressionToken2.ToString(), expressionToken.ToString()) ? "1" : "0");
			_stack.Push(new ExpressionToken(value));
		}

		private void BinaryNumberOperation(Func<decimal, decimal, decimal> operation)
		{
			decimal arg = _stack.Pop().ToDecimal(_context);
			decimal arg2 = _stack.Pop().ToDecimal(_context);
			decimal num = operation(arg2, arg);
			_stack.Push(new ExpressionToken(num.ToString(_context.FormatCulture)));
		}
	}
	public class ExpressionToken
	{
		public static readonly ExpressionToken True = new ExpressionToken("1");

		public static readonly ExpressionToken False = new ExpressionToken("0");

		internal static readonly NumberStyles NumberParseStyle = NumberStyles.Number | NumberStyles.AllowCurrencySymbol;

		private RawToken _rawToken;

		private const string FrozenErrorMsg = "Cannot modify frozen token.";

		private ExpressionTokenType _type;

		private string _value;

		public RawToken RawToken => _rawToken;

		public bool IsFrozen => _value != null;

		public ExpressionTokenType TokenType
		{
			get
			{
				return _type;
			}
			set
			{
				if (_value == null)
				{
					_type = value;
				}
			}
		}

		public OperatorType OperatorType { get; set; }

		public string Value => _value ?? _rawToken?.ToString();

		public (object Value, ValueTypeHint TypeHint) FieldValue { get; internal set; }

		public ExpressionToken()
		{
		}

		public ExpressionToken(string value)
		{
			_type = ExpressionTokenType.Value;
			_value = value;
		}

		public void Append(RawToken token)
		{
			if (IsFrozen)
			{
				throw new InvalidOperationException("Cannot modify frozen token.");
			}
			if (_rawToken == null)
			{
				_rawToken = token;
			}
			else
			{
				_rawToken.Append(token);
			}
		}

		public void Freeze()
		{
			if (IsFrozen)
			{
				throw new InvalidOperationException("Cannot modify frozen token.");
			}
			_value = _rawToken?.ToString();
		}

		public override string ToString()
		{
			ExpressionTokenType tokenType = TokenType;
			ExpressionTokenType expressionTokenType = tokenType;
			if (expressionTokenType == ExpressionTokenType.Field)
			{
				return FieldValue.Value?.ToString() ?? "";
			}
			return Value ?? "";
		}

		public double ToDouble(EvaluationContext context)
		{
			switch (TokenType)
			{
			case ExpressionTokenType.SingleQuoted:
			case ExpressionTokenType.DoubleQuoted:
			case ExpressionTokenType.Value:
				return double.Parse(Value, NumberParseStyle, context.FormatCulture);
			case ExpressionTokenType.Field:
				return double.Parse(FieldValue.Value?.ToString(), NumberParseStyle, context.FormatCulture);
			default:
				throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot convert {0}({1}) to a numeric value.", TokenType, Value));
			}
		}

		public decimal ToDecimal(EvaluationContext context)
		{
			switch (TokenType)
			{
			case ExpressionTokenType.SingleQuoted:
			case ExpressionTokenType.DoubleQuoted:
			case ExpressionTokenType.Value:
				return decimal.Parse(Value, NumberParseStyle, context.FormatCulture);
			case ExpressionTokenType.Field:
				return decimal.Parse(FieldValue.Value?.ToString(), NumberParseStyle, context.FormatCulture);
			default:
				throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot convert {0}({1}) to a numeric value.", TokenType, Value));
			}
		}
	}
	public enum ExpressionTokenType
	{
		None,
		Operator,
		OpenParenthesis,
		CloseParenthesis,
		Function,
		Comma,
		Field,
		SingleQuoted,
		DoubleQuoted,
		Value
	}
	public class FunctionRoutine
	{
		private Func<EvaluationContext, ExpressionToken[], ExpressionToken> _routine;

		public int ArgumentCount { get; private set; }

		public FunctionRoutine(int argCount, Func<EvaluationContext, ExpressionToken[], ExpressionToken> routine)
		{
			if (routine == null)
			{
				throw new ArgumentNullException("routine");
			}
			ArgumentCount = argCount;
			_routine = routine;
		}

		public ExpressionToken Evaluate(EvaluationContext context, ExpressionToken[] args)
		{
			return _routine(context, args);
		}
	}
	public enum ValueTypeHint
	{
		Auto,
		Text
	}
}
namespace Soukoku.ExpressionParser.Parsing
{
	public interface IExpressionTokenizer
	{
		ExpressionToken[] Tokenize(string input);
	}
	public class InfixTokenizer : IExpressionTokenizer
	{
		private List<ExpressionToken> _currentTokens;

		public ExpressionToken[] Tokenize(string input)
		{
			_currentTokens = new List<ExpressionToken>();
			ExpressionToken expressionToken = null;
			ListReader<RawToken> listReader = new ListReader<RawToken>(new RawTokenizer().Tokenize(input));
			while (!listReader.IsEnd)
			{
				RawToken rawToken = listReader.Read();
				switch (rawToken.TokenType)
				{
				case RawTokenType.WhiteSpace:
					expressionToken = null;
					break;
				case RawTokenType.Literal:
					if (expressionToken == null || expressionToken.TokenType != ExpressionTokenType.Value)
					{
						expressionToken = new ExpressionToken
						{
							TokenType = ExpressionTokenType.Value
						};
						_currentTokens.Add(expressionToken);
					}
					expressionToken.Append(rawToken);
					break;
				case RawTokenType.Symbol:
					if (KnownOperators.IsKnown(rawToken.Value))
					{
						if (expressionToken != null && expressionToken.TokenType == ExpressionTokenType.Operator)
						{
							string operatorValue = expressionToken.Value + rawToken.Value;
							if (KnownOperators.IsKnown(operatorValue))
							{
								expressionToken.Append(rawToken);
								break;
							}
						}
						expressionToken = new ExpressionToken
						{
							TokenType = ExpressionTokenType.Operator
						};
						_currentTokens.Add(expressionToken);
						expressionToken.Append(rawToken);
					}
					else
					{
						expressionToken = HandleNonOperatorSymbolToken(listReader, expressionToken, rawToken);
					}
					break;
				default:
					throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Unsupported token type {0} at position {1}.", rawToken.TokenType, rawToken.Position));
				}
			}
			MassageTokens(_currentTokens);
			return _currentTokens.ToArray();
		}

		private ExpressionToken HandleNonOperatorSymbolToken(ListReader<RawToken> reader, ExpressionToken lastExpToken, RawToken curRawToken)
		{
			switch (curRawToken.Value)
			{
			case ",":
				lastExpToken = new ExpressionToken
				{
					TokenType = ExpressionTokenType.Comma
				};
				_currentTokens.Add(lastExpToken);
				lastExpToken.Append(curRawToken);
				break;
			case "(":
				if (lastExpToken != null && lastExpToken.TokenType == ExpressionTokenType.Value)
				{
					lastExpToken.TokenType = ExpressionTokenType.Function;
				}
				lastExpToken = new ExpressionToken
				{
					TokenType = ExpressionTokenType.OpenParenthesis
				};
				_currentTokens.Add(lastExpToken);
				lastExpToken.Append(curRawToken);
				break;
			case ")":
				lastExpToken = new ExpressionToken
				{
					TokenType = ExpressionTokenType.CloseParenthesis
				};
				_currentTokens.Add(lastExpToken);
				lastExpToken.Append(curRawToken);
				break;
			case "{":
				lastExpToken = ReadToLiteralAs(reader, "}", ExpressionTokenType.Field);
				break;
			case "\"":
				lastExpToken = ReadToLiteralAs(reader, "\"", ExpressionTokenType.DoubleQuoted);
				break;
			case "'":
				lastExpToken = ReadToLiteralAs(reader, "'", ExpressionTokenType.SingleQuoted);
				break;
			}
			return lastExpToken;
		}

		private ExpressionToken ReadToLiteralAs(ListReader<RawToken> reader, string literalValue, ExpressionTokenType tokenType)
		{
			ExpressionToken expressionToken = new ExpressionToken
			{
				TokenType = tokenType
			};
			_currentTokens.Add(expressionToken);
			while (!reader.IsEnd)
			{
				RawToken rawToken = reader.Read();
				if (rawToken.TokenType == RawTokenType.Symbol && rawToken.Value == literalValue)
				{
					break;
				}
				expressionToken.Append(rawToken);
			}
			return expressionToken;
		}

		private static void MassageTokens(List<ExpressionToken> tokens)
		{
			ListReader<ExpressionToken> listReader = new ListReader<ExpressionToken>(tokens);
			while (!listReader.IsEnd)
			{
				ExpressionToken expressionToken = listReader.Read();
				if (expressionToken.TokenType == ExpressionTokenType.Operator)
				{
					DetermineOperatorType(listReader, expressionToken);
				}
				expressionToken.Freeze();
			}
		}

		private static void DetermineOperatorType(ListReader<ExpressionToken> reader, ExpressionToken tk)
		{
			tk.OperatorType = KnownOperators.TryMap(tk.Value);
			switch (tk.OperatorType)
			{
			case OperatorType.PreIncrement:
			case OperatorType.PreDecrement:
			{
				ExpressionToken expressionToken = ((reader.Position > 1) ? reader.Peek(-2) : null);
				if (expressionToken != null && expressionToken.TokenType == ExpressionTokenType.Value)
				{
					if (tk.OperatorType == OperatorType.PreIncrement)
					{
						tk.OperatorType = OperatorType.PostIncrement;
					}
					else
					{
						tk.OperatorType = OperatorType.PostDecrement;
					}
				}
				break;
			}
			case OperatorType.Addition:
			case OperatorType.Subtraction:
			{
				ExpressionToken expressionToken = ((reader.Position > 1) ? reader.Peek(-2) : null);
				if (expressionToken == null || (expressionToken.TokenType == ExpressionTokenType.Operator && expressionToken.OperatorType != OperatorType.PostDecrement && expressionToken.OperatorType != OperatorType.PostIncrement))
				{
					if (tk.OperatorType == OperatorType.Addition)
					{
						tk.OperatorType = OperatorType.UnaryPlus;
					}
					else
					{
						tk.OperatorType = OperatorType.UnaryMinus;
					}
				}
				break;
			}
			case OperatorType.None:
				throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Operator {0} is not supported.", tk.Value));
			}
		}
	}
	public class InfixToPostfixTokenizer : IExpressionTokenizer
	{
		private const string UnbalancedParenMsg = "Unbalanced parenthesis in expression.";

		private List<ExpressionToken> _output;

		private Stack<ExpressionToken> _stack;

		public ExpressionToken[] Tokenize(string input)
		{
			ExpressionToken[] array = new InfixTokenizer().Tokenize(input);
			_output = new List<ExpressionToken>();
			_stack = new Stack<ExpressionToken>();
			ExpressionToken[] array2 = array;
			foreach (ExpressionToken expressionToken in array2)
			{
				switch (expressionToken.TokenType)
				{
				case ExpressionTokenType.Field:
				case ExpressionTokenType.SingleQuoted:
				case ExpressionTokenType.DoubleQuoted:
				case ExpressionTokenType.Value:
					_output.Add(expressionToken);
					break;
				case ExpressionTokenType.Function:
					_stack.Push(expressionToken);
					break;
				case ExpressionTokenType.Comma:
					HandleComma();
					break;
				case ExpressionTokenType.Operator:
					HandleOperatorToken(expressionToken);
					break;
				case ExpressionTokenType.OpenParenthesis:
					_stack.Push(expressionToken);
					break;
				case ExpressionTokenType.CloseParenthesis:
					HandleCloseParenthesis();
					break;
				}
			}
			while (_stack.Count > 0)
			{
				ExpressionToken expressionToken2 = _stack.Pop();
				if (expressionToken2.TokenType == ExpressionTokenType.OpenParenthesis)
				{
					throw new NotSupportedException("Unbalanced parenthesis in expression.");
				}
				_output.Add(expressionToken2);
			}
			return _output.ToArray();
		}

		private void HandleComma()
		{
			bool flag = false;
			while (_stack.Count > 1)
			{
				ExpressionToken expressionToken = _stack.Peek();
				if (expressionToken.TokenType == ExpressionTokenType.OpenParenthesis)
				{
					flag = true;
					break;
				}
				_output.Add(_stack.Pop());
			}
			if (!flag)
			{
				throw new NotSupportedException("Unbalanced parenthesis in expression.");
			}
		}

		private void HandleOperatorToken(ExpressionToken inToken)
		{
			while (_stack.Count > 0)
			{
				ExpressionToken expressionToken = _stack.Peek();
				if (expressionToken.TokenType == ExpressionTokenType.Operator)
				{
					int precedence = KnownOperators.GetPrecedence(inToken.OperatorType);
					int precedence2 = KnownOperators.GetPrecedence(expressionToken.OperatorType);
					bool flag = KnownOperators.IsLeftAssociative(inToken.OperatorType);
					if ((flag && precedence <= precedence2) || (!flag && precedence < precedence2))
					{
						_output.Add(_stack.Pop());
						continue;
					}
					break;
				}
				break;
			}
			_stack.Push(inToken);
		}

		private void HandleCloseParenthesis()
		{
			bool flag = false;
			while (_stack.Count > 0)
			{
				ExpressionToken expressionToken = _stack.Pop();
				if (expressionToken.TokenType == ExpressionTokenType.OpenParenthesis)
				{
					flag = true;
					break;
				}
				_output.Add(expressionToken);
			}
			if (!flag)
			{
				throw new NotSupportedException("Unbalanced parenthesis in expression.");
			}
			if (_stack.Count > 0)
			{
				ExpressionToken expressionToken2 = _stack.Peek();
				if (expressionToken2 != null && expressionToken2.TokenType == ExpressionTokenType.Function)
				{
					_output.Add(_stack.Pop());
				}
			}
		}
	}
	public static class KnownOperators
	{
		private static readonly Dictionary<string, OperatorType> DefaultMap = new Dictionary<string, OperatorType>
		{
			{
				"++",
				OperatorType.PreIncrement
			},
			{
				"--",
				OperatorType.PreDecrement
			},
			{
				"+=",
				OperatorType.AdditionAssignment
			},
			{
				"-=",
				OperatorType.SubtractionAssignment
			},
			{
				"*=",
				OperatorType.MultiplicationAssignment
			},
			{
				"/=",
				OperatorType.DivisionAssignment
			},
			{
				"%=",
				OperatorType.ModulusAssignment
			},
			{
				"==",
				OperatorType.Equal
			},
			{
				"!=",
				OperatorType.NotEqual
			},
			{
				"<=",
				OperatorType.LessThanOrEqual
			},
			{
				">=",
				OperatorType.GreaterThanOrEqual
			},
			{
				"&&",
				OperatorType.LogicalAnd
			},
			{
				"||",
				OperatorType.LogicalOr
			},
			{
				"+",
				OperatorType.Addition
			},
			{
				"-",
				OperatorType.Subtraction
			},
			{
				"*",
				OperatorType.Multiplication
			},
			{
				"/",
				OperatorType.Division
			},
			{
				"=",
				OperatorType.Assignment
			},
			{
				"%",
				OperatorType.Modulus
			},
			{
				"<",
				OperatorType.LessThan
			},
			{
				">",
				OperatorType.GreaterThan
			},
			{
				"&",
				OperatorType.BitwiseAnd
			},
			{
				"|",
				OperatorType.BitwiseOr
			},
			{
				"!",
				OperatorType.LogicalNegation
			}
		};

		public static bool IsKnown(string operatorValue)
		{
			return DefaultMap.ContainsKey(operatorValue);
		}

		public static OperatorType TryMap(string operatorValue)
		{
			if (DefaultMap.ContainsKey(operatorValue))
			{
				return DefaultMap[operatorValue];
			}
			return OperatorType.None;
		}

		public static int GetPrecedence(OperatorType type)
		{
			switch (type)
			{
			case OperatorType.PostIncrement:
			case OperatorType.PostDecrement:
				return 100;
			case OperatorType.PreIncrement:
			case OperatorType.PreDecrement:
			case OperatorType.UnaryPlus:
			case OperatorType.UnaryMinus:
			case OperatorType.LogicalNegation:
				return 90;
			case OperatorType.Multiplication:
			case OperatorType.Division:
			case OperatorType.Modulus:
				return 85;
			case OperatorType.Addition:
			case OperatorType.Subtraction:
				return 80;
			case OperatorType.LessThan:
			case OperatorType.LessThanOrEqual:
			case OperatorType.GreaterThan:
			case OperatorType.GreaterThanOrEqual:
				return 75;
			case OperatorType.Equal:
			case OperatorType.NotEqual:
				return 70;
			case OperatorType.BitwiseAnd:
			case OperatorType.BitwiseOr:
				return 65;
			case OperatorType.LogicalAnd:
			case OperatorType.LogicalOr:
				return 60;
			case OperatorType.Assignment:
			case OperatorType.AdditionAssignment:
			case OperatorType.SubtractionAssignment:
			case OperatorType.MultiplicationAssignment:
			case OperatorType.DivisionAssignment:
			case OperatorType.ModulusAssignment:
				return 20;
			default:
				return 0;
			}
		}

		public static bool IsLeftAssociative(OperatorType type)
		{
			if ((uint)(type - 3) <= 4u || (uint)(type - 23) <= 5u)
			{
				return false;
			}
			return true;
		}
	}
	public class ListReader<TItem>
	{
		private IList<TItem> _list;

		private int _position;

		public int Position
		{
			get
			{
				return _position;
			}
			set
			{
				if (value < 0 || value > _list.Count)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_position = value;
			}
		}

		public bool IsEnd => _position >= _list.Count;

		public ListReader(IList<TItem> list)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			_list = list;
		}

		public TItem Read()
		{
			return _list[Position++];
		}

		public TItem Peek()
		{
			return Peek(0);
		}

		public TItem Peek(int offset)
		{
			return _list[Position + offset];
		}
	}
	public enum OperatorType
	{
		None,
		PostIncrement,
		PostDecrement,
		PreIncrement,
		PreDecrement,
		UnaryPlus,
		UnaryMinus,
		LogicalNegation,
		Multiplication,
		Division,
		Modulus,
		Addition,
		Subtraction,
		LessThan,
		LessThanOrEqual,
		GreaterThan,
		GreaterThanOrEqual,
		Equal,
		NotEqual,
		BitwiseAnd,
		BitwiseOr,
		LogicalAnd,
		LogicalOr,
		Assignment,
		AdditionAssignment,
		SubtractionAssignment,
		MultiplicationAssignment,
		DivisionAssignment,
		ModulusAssignment
	}
	public class RawToken
	{
		public RawTokenType TokenType { get; private set; }

		public int Position { get; private set; }

		internal StringBuilder ValueBuilder { get; private set; }

		public string Value => ValueBuilder.ToString();

		internal RawToken(RawTokenType type, int position)
		{
			TokenType = type;
			Position = position;
			ValueBuilder = new StringBuilder();
		}

		internal void Append(RawToken token)
		{
			if (token != null)
			{
				ValueBuilder.Append((object?)token.ValueBuilder);
			}
		}

		public override string ToString()
		{
			return Value;
		}
	}
	public enum RawTokenType
	{
		None,
		WhiteSpace,
		Symbol,
		Literal
	}
	public class RawTokenizer
	{
		private static readonly char[] DefaultSymbols = new char[22]
		{
			'+', '-', '*', '/', '=', '%', '^', ',', '<', '>',
			'&', '|', '!', '(', ')', '{', '}', '[', ']', '"',
			'\'', '~'
		};

		private char[] _symbols;

		public RawTokenizer()
			: this(null)
		{
		}

		public RawTokenizer(params char[] symbols)
		{
			_symbols = symbols ?? DefaultSymbols;
		}

		public char[] GetSymbols()
		{
			return (char[])_symbols.Clone();
		}

		public RawToken[] Tokenize(string input)
		{
			List<RawToken> list = new List<RawToken>();
			if (input != null)
			{
				RawToken rawToken = null;
				for (int i = 0; i < input.Length; i++)
				{
					char c = input[i];
					rawToken = (char.IsWhiteSpace(c) ? NewTokenIfNecessary(list, rawToken, RawTokenType.WhiteSpace, i) : ((!_symbols.Contains(c)) ? NewTokenIfNecessary(list, rawToken, RawTokenType.Literal, i) : NewTokenIfNecessary(list, rawToken, RawTokenType.Symbol, i)));
					if (c == '\\' && ++i < input.Length)
					{
						char value = input[i];
						rawToken.ValueBuilder.Append(value);
					}
					else
					{
						rawToken.ValueBuilder.Append(c);
					}
				}
			}
			return list.ToArray();
		}

		private static RawToken NewTokenIfNecessary(List<RawToken> tokens, RawToken lastToken, RawTokenType curTokenType, int position)
		{
			if (lastToken == null || lastToken.TokenType != curTokenType || curTokenType == RawTokenType.Symbol)
			{
				lastToken = new RawToken(curTokenType, position);
				tokens.Add(lastToken);
			}
			return lastToken;
		}
	}
}
namespace DunGenPlus
{
	public class API
	{
		public static bool AddDunGenExtender(DungeonFlow dungeonFlow, DunGenExtender dunGenExtender)
		{
			if ((Object)(object)dungeonFlow == (Object)null)
			{
				Plugin.logger.LogError((object)"dungeonFlow was null");
				return false;
			}
			if (ContainsDungeonFlow(dungeonFlow))
			{
				Plugin.logger.LogWarning((object)("Already contains DunGenExtender asset for " + ((Object)dungeonFlow).name));
				return false;
			}
			Plugin.DunGenExtenders.Add(dungeonFlow, dunGenExtender);
			Plugin.logger.LogInfo((object)("Added DunGenExtender asset for " + ((Object)dungeonFlow).name));
			return true;
		}

		public static bool RemoveDunGenExtender(DungeonFlow dungeonFlow)
		{
			if ((Object)(object)dungeonFlow == (Object)null)
			{
				Plugin.logger.LogError((object)"dungeonFlow was null");
				return false;
			}
			if (Plugin.DunGenExtenders.Remove(dungeonFlow))
			{
				Plugin.logger.LogInfo((object)("Removed DunGenExtender asset for " + ((Object)dungeonFlow).name));
				return true;
			}
			Plugin.logger.LogWarning((object)("Trying to remove DunGenExtender asset for " + ((Object)dungeonFlow).name + " when it already doesn't exist"));
			return false;
		}

		public static bool AddDunGenExtender(DunGenExtender dunGenExtender)
		{
			if ((Object)(object)dunGenExtender == (Object)null)
			{
				Plugin.logger.LogError((object)"dunGenExtender was null");
				return false;
			}
			return AddDunGenExtender(dunGenExtender.DungeonFlow, dunGenExtender);
		}

		public static bool RemoveDunGenExtender(DunGenExtender dunGenExtender)
		{
			if ((Object)(object)dunGenExtender == (Object)null)
			{
				Plugin.logger.LogError((object)"dunGenExtender was null");
				return false;
			}
			return RemoveDunGenExtender(dunGenExtender.DungeonFlow);
		}

		public static bool ContainsDungeonFlow(DungeonFlow dungeonFlow)
		{
			return Plugin.DunGenExtenders.ContainsKey(dungeonFlow);
		}

		public static bool ContainsDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow)
		{
			if ((Object)(object)extendedDungeonFlow == (Object)null)
			{
				return false;
			}
			return ContainsDungeonFlow(extendedDungeonFlow.DungeonFlow);
		}

		public static DunGenExtender GetDunGenExtender(DungeonFlow dungeonFlow)
		{
			if (Plugin.DunGenExtenders.TryGetValue(dungeonFlow, out var value))
			{
				return value;
			}
			return null;
		}

		public static bool IsDunGenExtenderActive(DungeonFlow dungeonFlow)
		{
			return IsDunGenExtenderActive(GetDunGenExtender(dungeonFlow));
		}

		public static bool IsDunGenExtenderActive(DunGenExtender extender)
		{
			return (Object)(object)extender != (Object)null && (Object)(object)extender == (Object)(object)DunGenPlusGenerator.Instance;
		}

		public static DunGenExtender CreateDunGenExtender(DungeonFlow dungeonFlow)
		{
			DunGenExtender dunGenExtender = ScriptableObject.CreateInstance<DunGenExtender>();
			dunGenExtender.DungeonFlow = dungeonFlow;
			return dunGenExtender;
		}

		public static void AddTileToMainPathDictionary(Dictionary<TileProxy, Tile> dictionary)
		{
			DunGenPlusGenerator.AddTileToMainPathDictionary(dictionary);
		}

		public static bool IsDevDebugModeActive()
		{
			return DevDebugManager.IsActive;
		}
	}
	internal class Assets
	{
		public static AssetBundle MainAssetBundle;

		public static GameObject DevDebugPrefab;

		public static void LoadAssets()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.lethalbundle", SearchOption.AllDirectories);
			foreach (string fileName in files)
			{
				FileInfo fileInfo = new FileInfo(fileName);
				AssetBundleLoader.AddOnLethalBundleLoadedListener((Action<AssetBundle>)AutoAddLethalBundle, fileInfo.Name);
			}
		}

		private static void AutoAddLethalBundle(AssetBundle assetBundle)
		{
			if (!assetBundle.isStreamedSceneAssetBundle)
			{
				DunGenExtender[] array = assetBundle.LoadAllAssets<DunGenExtender>();
				ExtendedContent[] array2 = assetBundle.LoadAllAssets<ExtendedContent>();
				if (array2.Length == 0 && array.Length != 0)
				{
					Plugin.logger.LogWarning((object)".lethalbundle does not contain any ExtendedContent. Unless you are manually creating and adding your ExtendedDungeonFlow with code, the DunGenExtender will probably not work.");
				}
				DunGenExtender[] array3 = array;
				foreach (DunGenExtender dunGenExtender in array3)
				{
					API.AddDunGenExtender(dunGenExtender);
				}
			}
		}

		public static T Load<T>(string name, bool onlyReportErrors = true) where T : Object
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				Plugin.logger.LogError((object)"Trying to load in asset but asset bundle is missing");
				return default(T);
			}
			T val = MainAssetBundle.LoadAsset<T>(name);
			bool flag = (Object)(object)val == (Object)null;
			if (flag || onlyReportErrors)
			{
				Plugin.logger.LogDebug((object)("Loading asset " + name));
			}
			if (flag)
			{
				Plugin.logger.LogError((object)"...but it was not found");
			}
			return val;
		}

		public static void LoadAssetBundle()
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				if (manifestResourceNames.Length >= 1)
				{
					string text = manifestResourceNames[0];
					using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
					Plugin.logger.LogDebug((object)("Loading resource " + text));
					MainAssetBundle = AssetBundle.LoadFromStream(stream);
				}
			}
			DevDebugPrefab = Assets.Load<GameObject>("DevDebug", onlyReportErrors: true);
		}
	}
	[Serializable]
	public class PropertyOverride<T>
	{
		[Tooltip("If false, use the value found in DungeonFlow. If true, use this Value instead.")]
		public bool Override;

		public T Value;

		public PropertyOverride(bool _override, T value)
		{
			Override = _override;
			Value = value;
		}
	}
	[CreateAssetMenu(fileName = "Main Path Extender", menuName = "DunGenExtender/Main Path Extender", order = 2)]
	public class MainPathExtender : ScriptableObject
	{
		internal const string LocalMainPathGlobalPropsTooltip = "Limits the amount of Global Props that can spawn on a single main path.\n\nThis does not afffect the global limit defined in DungeonFlow.";

		public PropertyOverride<IntRange> Length = new PropertyOverride<IntRange>(_override: false, new IntRange(5, 10));

		public PropertyOverride<BranchMode> BranchMode = new PropertyOverride<BranchMode>(_override: false, (BranchMode)0);

		public PropertyOverride<IntRange> BranchCount = new PropertyOverride<IntRange>(_override: false, new IntRange(1, 5));

		public PropertyOverride<List<GraphNode>> Nodes = new PropertyOverride<List<GraphNode>>(_override: false, new List<GraphNode>());

		public PropertyOverride<List<GraphLine>> Lines = new PropertyOverride<List<GraphLine>>(_override: false, new List<GraphLine>());

		[Tooltip("Limits the amount of Global Props that can spawn on a single main path.\n\nThis does not afffect the global limit defined in DungeonFlow.")]
		public List<LocalGlobalPropSettings> LocalGroupProps = new List<LocalGlobalPropSettings>();

		[Header("DEV ONLY: DON'T TOUCH")]
		[ReadOnly]
		public string Version = "0";

		public static IntRange GetLength(MainPathExtender extender, DungeonFlow flow)
		{
			if (Object.op_Implicit((Object)(object)extender) && extender.Length.Override)
			{
				return extender.Length.Value;
			}
			return flow.Length;
		}

		public static BranchMode GetBranchMode(MainPathExtender extender, DungeonFlow flow)
		{
			//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_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_0032: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)extender) && extender.BranchMode.Override)
			{
				return extender.BranchMode.Value;
			}
			return flow.BranchMode;
		}

		public static IntRange GetBranchCount(MainPathExtender extender, DungeonFlow flow)
		{
			if (Object.op_Implicit((Object)(object)extender) && extender.BranchCount.Override)
			{
				return extender.BranchCount.Value;
			}
			return flow.BranchCount;
		}

		public static List<GraphNode> GetNodes(MainPathExtender extender, DungeonFlow flow)
		{
			if (Object.op_Implicit((Object)(object)extender) && extender.Nodes.Override)
			{
				return extender.Nodes.Value;
			}
			return flow.Nodes;
		}

		public static List<GraphLine> GetLines(MainPathExtender extender, DungeonFlow flow)
		{
			if (Object.op_Implicit((Object)(object)extender) && extender.Lines.Override)
			{
				return extender.Lines.Value;
			}
			return flow.Lines;
		}
	}
	internal class PluginConfig
	{
		public static ConfigEntry<bool> EnableDevDebugTools;

		public static void SetupConfig(ConfigFile cfg)
		{
			//IL_000c: 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_0027: Expected O, but got Unknown
			//IL_0027: Expected O, but got Unknown
			EnableDevDebugTools = cfg.Bind<bool>(new ConfigDefinition("Dev", "Enable Dev Debug Tools"), false, new ConfigDescription("If enabled, allows the dev debug tools to be usable in the ship.\n\nPress LeftAlt + M to activate.", (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[CreateAssetMenu(fileName = "DunGen Extender", menuName = "DunGenExtender/DunGen Extender", order = 1)]
	public class DunGenExtender : ScriptableObject
	{
		[Tooltip("DunGenExtender will only influence this DungeonFlow")]
		public DungeonFlow DungeonFlow;

		public DunGenExtenderProperties Properties = new DunGenExtenderProperties();

		public DunGenExtenderEvents Events = new DunGenExtenderEvents();

		[Header("DEV ONLY: DON'T TOUCH")]
		[ReadOnly]
		public string Version = CURRENT_VERSION;

		internal bool Active = true;

		public static readonly string CURRENT_VERSION = "1";

		public void OnValidate()
		{
			if (Version == "0")
			{
				Properties.AdditionalTilesProperties.CopyFrom(Properties.ForcedTilesProperties);
				Version = "1";
			}
		}
	}
	[BepInPlugin("dev.ladyalice.dungenplus", "Dungeon Generation Plus", "1.5.1")]
	[BepInDependency("imabatby.lethallevelloader", "1.6.9")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal const string modGUID = "dev.ladyalice.dungenplus";

		private const string modName = "Dungeon Generation Plus";

		private const string modVersion = "1.5.1";

		internal readonly Harmony Harmony = new Harmony("dev.ladyalice.dungenplus");

		internal static Dictionary<DungeonFlow, DunGenExtender> DunGenExtenders = new Dictionary<DungeonFlow, DunGenExtender>();

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource logger { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("dev.ladyalice.dungenplus");
			logger.LogInfo((object)"Plugin Dungeon Generation Plus has been added!");
			PluginConfig.SetupConfig(((BaseUnityPlugin)this).Config);
			Harmony.PatchAll(typeof(DungeonGeneratorPatch));
			Harmony.PatchAll(typeof(DungeonPatch));
			Harmony.PatchAll(typeof(DungeonProxyPatch));
			Harmony.PatchAll(typeof(RoundManagerPatch));
			Harmony.PatchAll(typeof(BranchCountHelperPatch));
			Harmony.PatchAll(typeof(TileProxyPatch));
			Harmony.PatchAll(typeof(DoorwayPairFinderPatch));
			try
			{
				Harmony.PatchAll(typeof(LethalLevelLoaderPatches));
			}
			catch (Exception ex)
			{
				logger.LogError((object)"Failed to patch LLL for dev debug. You can ignore this.");
				logger.LogError((object)ex);
			}
			Assets.LoadAssets();
			Assets.LoadAssetBundle();
			DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.OnMainEntranceTeleportSpawnedFunction);
		}
	}
}
namespace DunGenPlus.Utils
{
	internal class InjectionDictionary
	{
		public string name;

		public List<CodeInstruction> instructions;

		public CodeInstruction[] injections;

		private int counter;

		public InjectionDictionary(string name, MethodInfo methodInjection, params CodeInstruction[] instructions)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			this.name = name;
			injections = (CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)methodInjection)
			};
			this.instructions = instructions.ToList();
		}

		public InjectionDictionary(string name, CodeInstruction[] codeInjections, params CodeInstruction[] instructions)
		{
			this.name = name;
			injections = codeInjections;
			this.instructions = instructions.ToList();
		}

		public void ResetCounter()
		{
			counter = 0;
		}

		public void AddCounter()
		{
			counter++;
		}

		public void Report(string debugFunction, int? expectedCounter)
		{
			if (counter == 0)
			{
				Plugin.logger.LogError((object)(debugFunction + " could not inject " + name + ". Probably scary"));
			}
			else if (!expectedCounter.HasValue)
			{
				Plugin.logger.LogDebug((object)$"{debugFunction} inject {name} {counter} time(s)");
			}
			else if (expectedCounter.Value != counter)
			{
				Plugin.logger.LogWarning((object)$"{debugFunction} inject {name} {counter} time(s) (Expected {expectedCounter.Value}). Probably not an error but be warned");
			}
		}
	}
	internal abstract class InstructionSequence
	{
		protected enum AdvanceResult
		{
			Failed,
			Advanced,
			Finished
		}

		protected List<Func<CodeInstruction, bool>> seq;

		protected string name;

		protected string extraErrorMessage;

		protected int stage;

		protected bool completed;

		protected bool single;

		public bool debugProgress;

		public InstructionSequence(string name, bool single = true, string extraErrorMessage = null)
		{
			seq = new List<Func<CodeInstruction, bool>>();
			stage = 0;
			completed = false;
			this.name = name;
			this.single = single;
			this.extraErrorMessage = extraErrorMessage;
		}

		public void Add(Func<CodeInstruction, bool> next)
		{
			seq.Add(next);
		}

		public void AddBasic(OpCode opcode)
		{
			seq.Add((CodeInstruction i) => i.opcode == opcode);
		}

		public void AddBasic(OpCode opcode, object operand)
		{
			seq.Add((CodeInstruction i) => i.opcode == opcode && i.operand == operand);
		}

		public void AddBasicLocal(OpCode opcode, int operand)
		{
			seq.Add((CodeInstruction i) => i.opcode == opcode && (i.operand as LocalBuilder).LocalIndex == operand);
		}

		public void AddAny()
		{
			seq.Add(null);
		}

		public void AddOperandTypeCheck(OpCode opcode, Type operandType)
		{
			seq.Add(delegate(CodeInstruction i)
			{
				FieldInfo fieldInfo = i.operand as FieldInfo;
				return i.opcode == opcode && fieldInfo != null && fieldInfo.FieldType == operandType;
			});
		}

		public void AddBasicWithAlternateMethodName(OpCode opcode, object operand, string methodName)
		{
			seq.Add(delegate(CodeInstruction i)
			{
				if (i.opcode == opcode && i.operand == operand)
				{
					return true;
				}
				MethodInfo methodInfo = i.operand as MethodInfo;
				return (methodInfo != null && methodInfo.Name == methodName) ? true : false;
			});
		}

		public void AddSpecial(OpCode opcode, Func<CodeInstruction, bool> extra)
		{
			seq.Add((CodeInstruction i) => i.opcode == opcode && extra(i));
		}

		public void ReportComplete()
		{
			if (!completed)
			{
				string text = (string.IsNullOrWhiteSpace(extraErrorMessage) ? "BIG PROBLEM!" : extraErrorMessage);
				Plugin.logger.LogError((object)("HarmonyTranspiler for " + name + " has failed. " + text));
			}
		}

		protected AdvanceResult AdvanceStage(CodeInstruction current)
		{
			Func<CodeInstruction, bool> func = seq[stage];
			AdvanceResult advanceResult = AdvanceResult.Failed;
			if (func == null)
			{
				func = seq[stage + 1];
				if (func(current))
				{
					stage += 2;
				}
				advanceResult = AdvanceResult.Advanced;
				if (debugProgress)
				{
					Debug.LogWarning((object)current);
				}
			}
			else if (func(current))
			{
				stage++;
				advanceResult = AdvanceResult.Advanced;
				if (debugProgress)
				{
					Debug.LogWarning((object)current);
				}
			}
			else
			{
				stage = 0;
				advanceResult = AdvanceResult.Failed;
			}
			if (stage >= seq.Count)
			{
				if (completed && single)
				{
					throw new Exception("Found multiple valid " + name + " instructions");
				}
				stage = 0;
				completed = true;
				advanceResult = AdvanceResult.Finished;
			}
			return advanceResult;
		}
	}
	internal class InstructionSequenceStandard : InstructionSequence
	{
		public InstructionSequenceStandard(string name, bool single = true, string extraErrorMessage = null)
			: base(name, single, extraErrorMessage)
		{
		}

		public bool VerifyStage(CodeInstruction current)
		{
			return AdvanceStage(current) == AdvanceResult.Finished;
		}
	}
	internal class InstructionSequenceHold : InstructionSequence
	{
		public enum HoldResult
		{
			None,
			Hold,
			Release,
			Finished
		}

		public List<CodeInstruction> Instructions;

		private new List<Func<CodeInstruction, bool>> seq;

		private new string name;

		private new string extraErrorMessage;

		private new int stage = 0;

		private new bool completed = false;

		public InstructionSequenceHold(string name, bool single = true, string extraErrorMessage = null)
			: base(name, single, extraErrorMessage)
		{
			Instructions = new List<CodeInstruction>();
		}

		public HoldResult VerifyStage(CodeInstruction current)
		{
			switch (AdvanceStage(current))
			{
			case AdvanceResult.Failed:
				if (Instructions.Count > 0)
				{
					Instructions.Add(current);
					return HoldResult.Release;
				}
				return HoldResult.None;
			case AdvanceResult.Advanced:
				Instructions.Add(current);
				return HoldResult.Hold;
			default:
				Instructions.Add(current);
				return HoldResult.Finished;
			}
		}

		public void ClearInstructions()
		{
			Instructions.Clear();
		}
	}
	internal class TranspilerUtilities
	{
		[CompilerGenerated]
		private sealed class <InjectMethod>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private InjectionDictionary injection;

			public InjectionDictionary <>3__injection;

			private string debugFunction;

			public string <>3__debugFunction;

			private int? expectedCounter;

			public int? <>3__expectedCounter;

			private List<CodeInstruction> <targets>5__1;

			private CodeInstruction[] <codeInjections>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <i>5__4;

			private List<CodeInstruction>.Enumerator <>s__5;

			private CodeInstruction <t>5__6;

			private CodeInstruction[] <>s__7;

			private int <>s__8;

			private CodeInstruction <c>5__9;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InjectMethod>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 2u)
				{
					try
					{
						if (num == -4 || (uint)(num - 1) <= 1u)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<targets>5__1 = null;
				<codeInjections>5__2 = null;
				<>s__3 = null;
				<i>5__4 = null;
				<>s__5 = default(List<CodeInstruction>.Enumerator);
				<t>5__6 = null;
				<>s__7 = null;
				<c>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<targets>5__1 = injection.instructions;
						<codeInjections>5__2 = injection.injections;
						injection.ResetCounter();
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -4;
						<>s__7 = <codeInjections>5__2;
						<>s__8 = 0;
						goto IL_0191;
					case 2:
						<>1__state = -4;
						<c>5__9 = null;
						<>s__8++;
						goto IL_0191;
					case 3:
						{
							<>1__state = -3;
							goto IL_020b;
						}
						IL_0191:
						if (<>s__8 < <>s__7.Length)
						{
							<c>5__9 = <>s__7[<>s__8];
							<>2__current = <c>5__9;
							<>1__state = 2;
							return true;
						}
						<>s__7 = null;
						injection.AddCounter();
						<>m__Finally2();
						goto IL_020b;
						IL_020b:
						<i>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<i>5__4 = <>s__3.Current;
						<>s__5 = <targets>5__1.GetEnumerator();
						<>1__state = -4;
						while (<>s__5.MoveNext())
						{
							<t>5__6 = <>s__5.Current;
							if (<i>5__4.opcode == <t>5__6.opcode && <i>5__4.operand == <t>5__6.operand)
							{
								<>2__current = <i>5__4;
								<>1__state = 1;
								return true;
							}
							<t>5__6 = null;
						}
						<>m__Finally2();
						<>s__5 = default(List<CodeInstruction>.Enumerator);
						<>2__current = <i>5__4;
						<>1__state = 3;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					injection.Report(debugFunction, expectedCounter);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				((IDisposable)<>s__5).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<InjectMethod>d__0 <InjectMethod>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<InjectMethod>d__ = this;
				}
				else
				{
					<InjectMethod>d__ = new <InjectMethod>d__0(0);
				}
				<InjectMethod>d__.instructions = <>3__instructions;
				<InjectMethod>d__.injection = <>3__injection;
				<InjectMethod>d__.debugFunction = <>3__debugFunction;
				<InjectMethod>d__.expectedCounter = <>3__expectedCounter;
				return <InjectMethod>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<InjectMethod>d__0))]
		public static IEnumerable<CodeInstruction> InjectMethod(IEnumerable<CodeInstruction> instructions, InjectionDictionary injection, string debugFunction, int? expectedCounter = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InjectMethod>d__0(-2)
			{
				<>3__instructions = instructions,
				<>3__injection = injection,
				<>3__debugFunction = debugFunction,
				<>3__expectedCounter = expectedCounter
			};
		}

		public static bool IsInstructionNearFloatValue(CodeInstruction instruction, float value)
		{
			return Mathf.Abs((float)instruction.operand - value) < 0.1f;
		}

		public static void PrintInstructions(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				PrintInstruction(instruction);
			}
		}

		public static void PrintInstruction(CodeInstruction inst)
		{
			string text = inst.opcode.ToString();
			string text2 = ((inst.operand != null) ? inst.operand.ToString() : "NULL");
			Plugin.logger.LogInfo((object)(text + ": " + text2));
		}
	}
	public class ActionList
	{
		public string name;

		public List<(string name, Action action)> actionList;

		public List<(string name, Action action)> temporaryActionList;

		public ActionList(string name)
		{
			this.name = name;
			actionList = new List<(string, Action)>();
			temporaryActionList = new List<(string, Action)>();
		}

		public void AddEvent(string name, Action act)
		{
			actionList.Add((name, act));
		}

		public void AddTemporaryEvent(string name, Action act)
		{
			temporaryActionList.Add((name, act));
		}

		public void Call()
		{
			foreach (var action in actionList)
			{
				try
				{
					action.action();
				}
				catch (Exception ex)
				{
					Plugin.logger.LogError((object)("Error with event " + name + "/" + action.name));
					Plugin.logger.LogError((object)ex.ToString());
				}
			}
			foreach (var temporaryAction in temporaryActionList)
			{
				try
				{
					temporaryAction.action();
				}
				catch (Exception ex2)
				{
					Plugin.logger.LogError((object)("Error with event " + name + "/" + temporaryAction.name));
					Plugin.logger.LogError((object)ex2.ToString());
				}
			}
			ClearTemporaryActionList();
		}

		public void ClearTemporaryActionList()
		{
			temporaryActionList.Clear();
		}
	}
	public static class Utility
	{
		public static void PrintLog(string message, LogLevel logLevel)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if (DunGenPlusScript.InDebugMode)
			{
				if (logLevel - 1 > 1)
				{
					if ((int)logLevel == 4)
					{
						Debug.LogWarning((object)message);
					}
					else
					{
						Debug.Log((object)message);
					}
				}
				else
				{
					Debug.LogError((object)message);
				}
			}
			else
			{
				Plugin.logger.Log(logLevel, (object)message);
			}
		}
	}
}
namespace DunGenPlus.Patches
{
	internal class BranchCountHelperPatch
	{
		[CompilerGenerated]
		private sealed class <ComputeBranchCountsGlobalPatch>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private FieldInfo <branchCountField>5__1;

			private InstructionSequenceStandard <branchSequence>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			private MethodInfo <specialFunction>5__5;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ComputeBranchCountsGlobalPatch>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<branchCountField>5__1 = null;
				<branchSequence>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<specialFunction>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<branchCountField>5__1 = typeof(DungeonFlow).GetField("BranchCount", BindingFlags.Instance | BindingFlags.Public);
						<branchSequence>5__2 = new InstructionSequenceStandard("BranchCount");
						<branchSequence>5__2.AddBasic(OpCodes.Ldfld, <branchCountField>5__1);
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						<instruction>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<instruction>5__4 = <>s__3.Current;
						if (<branchSequence>5__2.VerifyStage(<instruction>5__4))
						{
							<specialFunction>5__5 = typeof(DunGenPlusGenerator).GetMethod("GetBranchCount", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__5);
							<>1__state = 1;
							return true;
						}
						<>2__current = <instruction>5__4;
						<>1__state = 2;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					<branchSequence>5__2.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<ComputeBranchCountsGlobalPatch>d__1 <ComputeBranchCountsGlobalPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ComputeBranchCountsGlobalPatch>d__ = this;
				}
				else
				{
					<ComputeBranchCountsGlobalPatch>d__ = new <ComputeBranchCountsGlobalPatch>d__1(0);
				}
				<ComputeBranchCountsGlobalPatch>d__.instructions = <>3__instructions;
				return <ComputeBranchCountsGlobalPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <ComputeBranchCountsPatch>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private FieldInfo <branchModeField>5__1;

			private InstructionSequenceStandard <branchSequence>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			private MethodInfo <specialFunction>5__5;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ComputeBranchCountsPatch>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<branchModeField>5__1 = null;
				<branchSequence>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<specialFunction>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<branchModeField>5__1 = typeof(DungeonFlow).GetField("BranchMode", BindingFlags.Instance | BindingFlags.Public);
						<branchSequence>5__2 = new InstructionSequenceStandard("BranchMode", single: false);
						<branchSequence>5__2.AddBasic(OpCodes.Ldfld, <branchModeField>5__1);
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						<instruction>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<instruction>5__4 = <>s__3.Current;
						if (<branchSequence>5__2.VerifyStage(<instruction>5__4))
						{
							<specialFunction>5__5 = typeof(DunGenPlusGenerator).GetMethod("GetBranchMode", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__5);
							<>1__state = 1;
							return true;
						}
						<>2__current = <instruction>5__4;
						<>1__state = 2;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					<branchSequence>5__2.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<ComputeBranchCountsPatch>d__0 <ComputeBranchCountsPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ComputeBranchCountsPatch>d__ = this;
				}
				else
				{
					<ComputeBranchCountsPatch>d__ = new <ComputeBranchCountsPatch>d__0(0);
				}
				<ComputeBranchCountsPatch>d__.instructions = <>3__instructions;
				return <ComputeBranchCountsPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<ComputeBranchCountsPatch>d__0))]
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCounts")]
		public static IEnumerable<CodeInstruction> ComputeBranchCountsPatch(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ComputeBranchCountsPatch>d__0(-2)
			{
				<>3__instructions = instructions
			};
		}

		[IteratorStateMachine(typeof(<ComputeBranchCountsGlobalPatch>d__1))]
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCountsGlobal")]
		public static IEnumerable<CodeInstruction> ComputeBranchCountsGlobalPatch(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ComputeBranchCountsGlobalPatch>d__1(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	internal class DoorwayPairFinderPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(DoorwayPairFinder), "GetPotentialDoorwayPairsForNonFirstTile")]
		public static void GenerateBranchPathsPatch(ref DoorwayPairFinder __instance, ref IEnumerable<DoorwayPair> __result)
		{
			if (DunGenPlusGenerator.Active)
			{
				__result = DunGenPlusGenerator.GetPotentialDoorwayPairsForNonFirstTileAlternate(__instance);
			}
		}
	}
	internal class DungeonPatch
	{
		[CompilerGenerated]
		private sealed class <FromProxyPatch>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private InstructionSequenceStandard <endSequence>5__1;

			private FieldInfo <indexField>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			private FieldInfo <field>5__5;

			private MethodInfo <specialFunction>5__6;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FromProxyPatch>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 3u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<endSequence>5__1 = null;
				<indexField>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<field>5__5 = null;
				<specialFunction>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Expected O, but got Unknown
				//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Expected O, but got Unknown
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<endSequence>5__1 = new InstructionSequenceStandard("Forloop End");
						<endSequence>5__1.AddBasicLocal(OpCodes.Ldloca_S, 18);
						<endSequence>5__1.AddBasic(OpCodes.Constrained);
						<endSequence>5__1.AddBasic(OpCodes.Callvirt);
						<endSequence>5__1.AddBasic(OpCodes.Endfinally);
						<indexField>5__2 = null;
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						goto IL_0209;
					case 1:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldfld, (object)<indexField>5__2);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__6);
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -3;
						<specialFunction>5__6 = null;
						goto IL_01db;
					case 4:
						{
							<>1__state = -3;
							<field>5__5 = null;
							<instruction>5__4 = null;
							goto IL_0209;
						}
						IL_0209:
						if (<>s__3.MoveNext())
						{
							<instruction>5__4 = <>s__3.Current;
							object operand = <instruction>5__4.operand;
							<field>5__5 = operand as FieldInfo;
							if ((object)<field>5__5 != null && <field>5__5.Name.StartsWith("<proxyToTileMap>"))
							{
								<indexField>5__2 = <field>5__5;
							}
							if (<endSequence>5__1.VerifyStage(<instruction>5__4))
							{
								<specialFunction>5__6 = typeof(DunGenPlusGenerator).GetMethod("AddTileToMainPathDictionary", BindingFlags.Static | BindingFlags.Public);
								<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
								<>1__state = 1;
								return true;
							}
							goto IL_01db;
						}
						<>m__Finally1();
						<>s__3 = null;
						<endSequence>5__1.ReportComplete();
						return false;
						IL_01db:
						<>2__current = <instruction>5__4;
						<>1__state = 4;
						return true;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<FromProxyPatch>d__0 <FromProxyPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<FromProxyPatch>d__ = this;
				}
				else
				{
					<FromProxyPatch>d__ = new <FromProxyPatch>d__0(0);
				}
				<FromProxyPatch>d__.instructions = <>3__instructions;
				return <FromProxyPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<FromProxyPatch>d__0))]
		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static IEnumerable<CodeInstruction> FromProxyPatch(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FromProxyPatch>d__0(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	internal class TileProxyPatch
	{
		public static Dictionary<TileProxy, TileExtenderProxy> TileExtenderProxyDictionary = new Dictionary<TileProxy, TileExtenderProxy>();

		public static void ResetDictionary()
		{
			TileExtenderProxyDictionary.Clear();
		}

		public static TileExtenderProxy GetTileExtenderProxy(TileProxy proxy)
		{
			return TileExtenderProxyDictionary[proxy];
		}

		public static void AddTileExtenderProxy(TileProxy tileProxy, TileExtenderProxy tileExtenderProxy)
		{
			TileExtenderProxyDictionary.Add(tileProxy, tileExtenderProxy);
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		public static void TileProxyConstructorNewPatch(ref TileProxy __instance)
		{
			AddTileExtenderProxy(__instance, new TileExtenderProxy(__instance));
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		public static void TileProxyConstructorExistingPatch(ref TileProxy __instance, TileProxy existingTile)
		{
			AddTileExtenderProxy(__instance, new TileExtenderProxy(__instance, GetTileExtenderProxy(existingTile)));
		}
	}
	internal class DungeonProxyPatch
	{
		[CompilerGenerated]
		private sealed class <ConnectOverlappingDoorwaysPatch>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private MethodInfo <callFunction>5__1;

			private InstructionSequenceStandard <sequence>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			private MethodInfo <method>5__5;

			private MethodInfo <getTileProxy>5__6;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ConnectOverlappingDoorwaysPatch>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 8u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<callFunction>5__1 = null;
				<sequence>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<method>5__5 = null;
				<getTileProxy>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Expected O, but got Unknown
				//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bd: Expected O, but got Unknown
				//IL_01df: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e9: Expected O, but got Unknown
				//IL_020c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0216: Expected O, but got Unknown
				//IL_0239: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: Expected O, but got Unknown
				//IL_0265: Unknown result type (might be due to invalid IL or missing references)
				//IL_026f: Expected O, but got Unknown
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<callFunction>5__1 = typeof(DungeonFlow).GetMethod("CanDoorwaysConnect", BindingFlags.Instance | BindingFlags.Public);
						<sequence>5__2 = new InstructionSequenceStandard("doorway connect", single: false);
						<sequence>5__2.AddBasic(OpCodes.Callvirt, <callFunction>5__1);
						<sequence>5__2.AddBasic(OpCodes.Brfalse);
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Callvirt, (object)<getTileProxy>5__6);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)19);
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Callvirt, (object)<getTileProxy>5__6);
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)10);
						<>1__state = 5;
						return true;
					case 5:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)19);
						<>1__state = 6;
						return true;
					case 6:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Call, (object)<method>5__5);
						<>1__state = 7;
						return true;
					case 7:
						<>1__state = -3;
						<>2__current = <instruction>5__4;
						<>1__state = 8;
						return true;
					case 8:
						<>1__state = -3;
						break;
					case 9:
						<>1__state = -3;
						<instruction>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<instruction>5__4 = <>s__3.Current;
						if (<sequence>5__2.VerifyStage(<instruction>5__4))
						{
							<method>5__5 = typeof(DoorwaySistersRule).GetMethod("CanDoorwaysConnect", BindingFlags.Static | BindingFlags.Public);
							<getTileProxy>5__6 = typeof(DoorwayProxy).GetMethod("get_TileProxy", BindingFlags.Instance | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)10);
							<>1__state = 1;
							return true;
						}
						<>2__current = <instruction>5__4;
						<>1__state = 9;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					<sequence>5__2.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<ConnectOverlappingDoorwaysPatch>d__1 <ConnectOverlappingDoorwaysPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ConnectOverlappingDoorwaysPatch>d__ = this;
				}
				else
				{
					<ConnectOverlappingDoorwaysPatch>d__ = new <ConnectOverlappingDoorwaysPatch>d__1(0);
				}
				<ConnectOverlappingDoorwaysPatch>d__.instructions = <>3__instructions;
				return <ConnectOverlappingDoorwaysPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")]
		[HarmonyPrefix]
		public static void ConnectOverlappingDoorwaysPrePatch(ref DungeonProxy __instance)
		{
			IEnumerable<DoorwayProxy> list = __instance.AllTiles.SelectMany((TileProxy t) => t.Doorways);
			DoorwaySistersRule.UpdateCache(list);
		}

		[IteratorStateMachine(typeof(<ConnectOverlappingDoorwaysPatch>d__1))]
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")]
		public static IEnumerable<CodeInstruction> ConnectOverlappingDoorwaysPatch(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ConnectOverlappingDoorwaysPatch>d__1(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	internal class DungeonGeneratorPatch
	{
		[CompilerGenerated]
		private sealed class <AddTileDebugPatch>d__8 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private InstructionSequenceStandard <addTileSequence>5__1;

			private IEnumerator<CodeInstruction> <>s__2;

			private CodeInstruction <instruction>5__3;

			private MethodInfo <specialFunction>5__4;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AddTileDebugPatch>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 5u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<addTileSequence>5__1 = null;
				<>s__2 = null;
				<instruction>5__3 = null;
				<specialFunction>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Expected O, but got Unknown
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Expected O, but got Unknown
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a7: Expected O, but got Unknown
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<addTileSequence>5__1 = new InstructionSequenceStandard("Add Tile Placement");
						<addTileSequence>5__1.AddBasic(OpCodes.Callvirt);
						<addTileSequence>5__1.AddBasic(OpCodes.Ldc_I4_0);
						<addTileSequence>5__1.AddBasic(OpCodes.Bgt);
						<addTileSequence>5__1.AddBasicLocal(OpCodes.Ldloc_S, 8);
						<>s__2 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)8);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldarg_1, (object)null);
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__4);
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -3;
						<>2__current = <instruction>5__3;
						<>1__state = 5;
						return true;
					case 5:
						<>1__state = -3;
						break;
					case 6:
						<>1__state = -3;
						<instruction>5__3 = null;
						break;
					}
					if (<>s__2.MoveNext())
					{
						<instruction>5__3 = <>s__2.Current;
						if (<addTileSequence>5__1.VerifyStage(<instruction>5__3))
						{
							<specialFunction>5__4 = typeof(DunGenPlusGenerator).GetMethod("RecordLastTilePlacementResult", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
							<>1__state = 1;
							return true;
						}
						<>2__current = <instruction>5__3;
						<>1__state = 6;
						return true;
					}
					<>m__Finally1();
					<>s__2 = null;
					<addTileSequence>5__1.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__2 != null)
				{
					<>s__2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<AddTileDebugPatch>d__8 <AddTileDebugPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<AddTileDebugPatch>d__ = this;
				}
				else
				{
					<AddTileDebugPatch>d__ = new <AddTileDebugPatch>d__8(0);
				}
				<AddTileDebugPatch>d__.instructions = <>3__instructions;
				return <AddTileDebugPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GenerateMainPathDebugPatch>d__10 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private InstructionSequenceStandard <tileProxyNullSequence>5__1;

			private FieldInfo <indexField>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			private FieldInfo <field>5__5;

			private MethodInfo <specialFunction>5__6;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GenerateMainPathDebugPatch>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 5u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<tileProxyNullSequence>5__1 = null;
				<indexField>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<field>5__5 = null;
				<specialFunction>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Expected O, but got Unknown
				//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Expected O, but got Unknown
				//IL_0216: Unknown result type (might be due to invalid IL or missing references)
				//IL_0220: Expected O, but got Unknown
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a1: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<tileProxyNullSequence>5__1 = new InstructionSequenceStandard("TileProxyNull");
						<tileProxyNullSequence>5__1.AddBasic(OpCodes.Br);
						<tileProxyNullSequence>5__1.AddBasicLocal(OpCodes.Ldloc_S, 15);
						<tileProxyNullSequence>5__1.AddBasic(OpCodes.Brtrue);
						<indexField>5__2 = null;
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						if (<indexField>5__2 != null)
						{
							<specialFunction>5__6 = typeof(DunGenPlusGenerator).GetMethod("PrintAddTileErrorQuick", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Ldloc_1, (object)null);
							<>1__state = 2;
							return true;
						}
						Plugin.logger.LogWarning((object)"Failed to find current tile index field in the main path enumerator");
						break;
					case 2:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Ldfld, (object)<indexField>5__2);
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -3;
						<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__6);
						<>1__state = 5;
						return true;
					case 5:
						<>1__state = -3;
						<specialFunction>5__6 = null;
						break;
					case 6:
						<>1__state = -3;
						<field>5__5 = null;
						<instruction>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<instruction>5__4 = <>s__3.Current;
						object operand = <instruction>5__4.operand;
						<field>5__5 = operand as FieldInfo;
						if ((object)<field>5__5 != null && <field>5__5.Name.StartsWith("<j>"))
						{
							<indexField>5__2 = <field>5__5;
						}
						if (<tileProxyNullSequence>5__1.VerifyStage(<instruction>5__4))
						{
							<>2__current = <instruction>5__4;
							<>1__state = 1;
							return true;
						}
						<>2__current = <instruction>5__4;
						<>1__state = 6;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					<tileProxyNullSequence>5__1.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<GenerateMainPathDebugPatch>d__10 <GenerateMainPathDebugPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GenerateMainPathDebugPatch>d__ = this;
				}
				else
				{
					<GenerateMainPathDebugPatch>d__ = new <GenerateMainPathDebugPatch>d__10(0);
				}
				<GenerateMainPathDebugPatch>d__.instructions = <>3__instructions;
				return <GenerateMainPathDebugPatch>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GenerateMainPathGetLineAtDepthPatch>d__5 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private MethodInfo <getLineFunction>5__1;

			private FieldInfo <nodesField>5__2;

			private InstructionSequenceStandard <lineSequence>5__3;

			private InstructionSequenceStandard <nodesSequence>5__4;

			private IEnumerator<CodeInstruction> <>s__5;

			private CodeInstruction <instruction>5__6;

			private MethodInfo <specialFunction>5__7;

			private MethodInfo <specialFunction>5__8;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GenerateMainPathGetLineAtDepthPatch>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 2u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<getLineFunction>5__1 = null;
				<nodesField>5__2 = null;
				<lineSequence>5__3 = null;
				<nodesSequence>5__4 = null;
				<>s__5 = null;
				<instruction>5__6 = null;
				<specialFunction>5__7 = null;
				<specialFunction>5__8 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Expected O, but got Unknown
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a5: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<getLineFunction>5__1 = typeof(DungeonFlow).GetMethod("GetLineAtDepth", BindingFlags.Instance | BindingFlags.Public);
						<nodesField>5__2 = typeof(DungeonFlow).GetField("Nodes", BindingFlags.Instance | BindingFlags.Public);
						<lineSequence>5__3 = new InstructionSequenceStandard("GetLineAtDepth");
						<lineSequence>5__3.AddBasic(OpCodes.Callvirt, <getLineFunction>5__1);
						<nodesSequence>5__4 = new InstructionSequenceStandard("Nodes", single: false);
						<nodesSequence>5__4.AddBasic(OpCodes.Ldfld, <nodesField>5__2);
						<>s__5 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						break;
					case 3:
						<>1__state = -3;
						<instruction>5__6 = null;
						break;
					}
					if (<>s__5.MoveNext())
					{
						<instruction>5__6 = <>s__5.Current;
						if (<lineSequence>5__3.VerifyStage(<instruction>5__6))
						{
							<specialFunction>5__7 = typeof(DunGenPlusGenerator).GetMethod("GetLineAtDepth", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__7);
							<>1__state = 1;
							return true;
						}
						if (<nodesSequence>5__4.VerifyStage(<instruction>5__6))
						{
							<specialFunction>5__8 = typeof(DunGenPlusGenerator).GetMethod("GetNodes", BindingFlags.Static | BindingFlags.Public);
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<specialFunction>5__8);
							<>1__state = 2;
							return true;
						}
						<>2__current = <instruction>5__6;
						<>1__state = 3;
						return true;
					}
					<>m__Finally1();
					<>s__5 = null;
					<lineSequence>5__3.ReportComplete();
					<nodesSequence>5__4.ReportComplete();
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__5 != null)
				{
					<>s__5.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<GenerateMainPathGetLineAtDepthPatch>d__5 <GenerateMainPathGetLineAtDepthPatch>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GenerateMainPathGetLineAtDepthPatch>d__ = this;
				}
				else
				{
					<GenerateMainPathGetLineAtDepthPatch>d__ = new <GenerateMainPathGetLineAtDepthPatch>d__5(0);
				}
				<GenerateMainPathGetLineAtDepthP