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 BuiltInFunctions = new Dictionary(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 __staticFuncs = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _instanceFuncs = new Dictionary(StringComparer.OrdinalIgnoreCase); private Func _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 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 _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 listReader = new ListReader(array); _stack = new Stack(); 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 stack = new Stack(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 operation) { decimal arg = _stack.Pop().ToDecimal(_context); decimal num = operation(arg); _stack.Push(new ExpressionToken(num.ToString(_context.FormatCulture))); } private void UnaryLogicOperation(Func operation) { ExpressionToken expressionToken = _stack.Pop(); string value = (operation(expressionToken.ToString()) ? "1" : "0"); _stack.Push(new ExpressionToken(value)); } private void BinaryLogicOperation(Func 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 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 _routine; public int ArgumentCount { get; private set; } public FunctionRoutine(int argCount, Func 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 _currentTokens; public ExpressionToken[] Tokenize(string input) { _currentTokens = new List(); ExpressionToken expressionToken = null; ListReader listReader = new ListReader(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 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 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 tokens) { ListReader listReader = new ListReader(tokens); while (!listReader.IsEnd) { ExpressionToken expressionToken = listReader.Read(); if (expressionToken.TokenType == ExpressionTokenType.Operator) { DetermineOperatorType(listReader, expressionToken); } expressionToken.Freeze(); } } private static void DetermineOperatorType(ListReader 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 _output; private Stack _stack; public ExpressionToken[] Tokenize(string input) { ExpressionToken[] array = new InfixTokenizer().Tokenize(input); _output = new List(); _stack = new Stack(); 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 DefaultMap = new Dictionary { { "++", 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 { private IList _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 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 list = new List(); 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 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.DungeonFlow = dungeonFlow; return dunGenExtender; } public static void AddTileToMainPathDictionary(Dictionary 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)AutoAddLethalBundle, fileInfo.Name); } } private static void AutoAddLethalBundle(AssetBundle assetBundle) { if (!assetBundle.isStreamedSceneAssetBundle) { DunGenExtender[] array = assetBundle.LoadAllAssets(); ExtendedContent[] array2 = assetBundle.LoadAllAssets(); 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(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(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("DevDebug", onlyReportErrors: true); } } [Serializable] public class PropertyOverride { [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 Length = new PropertyOverride(_override: false, new IntRange(5, 10)); public PropertyOverride BranchMode = new PropertyOverride(_override: false, (BranchMode)0); public PropertyOverride BranchCount = new PropertyOverride(_override: false, new IntRange(1, 5)); public PropertyOverride> Nodes = new PropertyOverride>(_override: false, new List()); public PropertyOverride> Lines = new PropertyOverride>(_override: false, new List()); [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 LocalGroupProps = new List(); [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 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 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 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(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())); } } [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 DunGenExtenders = new Dictionary(); 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 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> 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>(); stage = 0; completed = false; this.name = name; this.single = single; this.extraErrorMessage = extraErrorMessage; } public void Add(Func 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 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 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 Instructions; private new List> 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(); } 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 d__0 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>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 5__1; private CodeInstruction[] 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private List.Enumerator <>s__5; private CodeInstruction 5__6; private CodeInstruction[] <>s__7; private int <>s__8; private CodeInstruction 5__9; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; <>s__5 = default(List.Enumerator); 5__6 = null; <>s__7 = null; 5__9 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = injection.instructions; 5__2 = injection.injections; injection.ResetCounter(); <>s__3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -4; <>s__7 = 5__2; <>s__8 = 0; goto IL_0191; case 2: <>1__state = -4; 5__9 = null; <>s__8++; goto IL_0191; case 3: { <>1__state = -3; goto IL_020b; } IL_0191: if (<>s__8 < <>s__7.Length) { 5__9 = <>s__7[<>s__8]; <>2__current = 5__9; <>1__state = 2; return true; } <>s__7 = null; injection.AddCounter(); <>m__Finally2(); goto IL_020b; IL_020b: 5__4 = null; break; } if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; <>s__5 = 5__1.GetEnumerator(); <>1__state = -4; while (<>s__5.MoveNext()) { 5__6 = <>s__5.Current; if (5__4.opcode == 5__6.opcode && 5__4.operand == 5__6.operand) { <>2__current = 5__4; <>1__state = 1; return true; } 5__6 = null; } <>m__Finally2(); <>s__5 = default(List.Enumerator); <>2__current = 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 IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.instructions = <>3__instructions; d__.injection = <>3__injection; d__.debugFunction = <>3__debugFunction; d__.expectedCounter = <>3__expectedCounter; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] public static IEnumerable InjectMethod(IEnumerable instructions, InjectionDictionary injection, string debugFunction, int? expectedCounter = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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 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 d__1 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private FieldInfo 5__1; private InstructionSequenceStandard 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private MethodInfo 5__5; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; 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; 5__1 = typeof(DungeonFlow).GetField("BranchCount", BindingFlags.Instance | BindingFlags.Public); 5__2 = new InstructionSequenceStandard("BranchCount"); 5__2.AddBasic(OpCodes.Ldfld, 5__1); <>s__3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; 5__4 = null; break; } if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; if (5__2.VerifyStage(5__4)) { 5__5 = typeof(DunGenPlusGenerator).GetMethod("GetBranchCount", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Call, (object)5__5); <>1__state = 1; return true; } <>2__current = 5__4; <>1__state = 2; return true; } <>m__Finally1(); <>s__3 = null; 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 IEnumerable.GetEnumerator() { d__1 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__1(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private FieldInfo 5__1; private InstructionSequenceStandard 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private MethodInfo 5__5; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; 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; 5__1 = typeof(DungeonFlow).GetField("BranchMode", BindingFlags.Instance | BindingFlags.Public); 5__2 = new InstructionSequenceStandard("BranchMode", single: false); 5__2.AddBasic(OpCodes.Ldfld, 5__1); <>s__3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; 5__4 = null; break; } if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; if (5__2.VerifyStage(5__4)) { 5__5 = typeof(DunGenPlusGenerator).GetMethod("GetBranchMode", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Call, (object)5__5); <>1__state = 1; return true; } <>2__current = 5__4; <>1__state = 2; return true; } <>m__Finally1(); <>s__3 = null; 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 IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] [HarmonyTranspiler] [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCounts")] public static IEnumerable ComputeBranchCountsPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__instructions = instructions }; } [IteratorStateMachine(typeof(d__1))] [HarmonyTranspiler] [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCountsGlobal")] public static IEnumerable ComputeBranchCountsGlobalPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(-2) { <>3__instructions = instructions }; } } internal class DoorwayPairFinderPatch { [HarmonyPostfix] [HarmonyPatch(typeof(DoorwayPairFinder), "GetPotentialDoorwayPairsForNonFirstTile")] public static void GenerateBranchPathsPatch(ref DoorwayPairFinder __instance, ref IEnumerable __result) { if (DunGenPlusGenerator.Active) { __result = DunGenPlusGenerator.GetPotentialDoorwayPairsForNonFirstTileAlternate(__instance); } } } internal class DungeonPatch { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private InstructionSequenceStandard 5__1; private FieldInfo 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private FieldInfo 5__5; private MethodInfo 5__6; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; 5__5 = null; 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; 5__1 = new InstructionSequenceStandard("Forloop End"); 5__1.AddBasicLocal(OpCodes.Ldloca_S, 18); 5__1.AddBasic(OpCodes.Constrained); 5__1.AddBasic(OpCodes.Callvirt); 5__1.AddBasic(OpCodes.Endfinally); 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)5__2); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__6); <>1__state = 3; return true; case 3: <>1__state = -3; 5__6 = null; goto IL_01db; case 4: { <>1__state = -3; 5__5 = null; 5__4 = null; goto IL_0209; } IL_0209: if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; object operand = 5__4.operand; 5__5 = operand as FieldInfo; if ((object)5__5 != null && 5__5.Name.StartsWith("")) { 5__2 = 5__5; } if (5__1.VerifyStage(5__4)) { 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; 5__1.ReportComplete(); return false; IL_01db: <>2__current = 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 IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable FromProxyPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__instructions = instructions }; } } internal class TileProxyPatch { public static Dictionary TileExtenderProxyDictionary = new Dictionary(); 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 d__1 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private MethodInfo 5__1; private InstructionSequenceStandard 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private MethodInfo 5__5; private MethodInfo 5__6; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; 5__5 = null; 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; 5__1 = typeof(DungeonFlow).GetMethod("CanDoorwaysConnect", BindingFlags.Instance | BindingFlags.Public); 5__2 = new InstructionSequenceStandard("doorway connect", single: false); 5__2.AddBasic(OpCodes.Callvirt, 5__1); 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)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)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)5__5); <>1__state = 7; return true; case 7: <>1__state = -3; <>2__current = 5__4; <>1__state = 8; return true; case 8: <>1__state = -3; break; case 9: <>1__state = -3; 5__4 = null; break; } if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; if (5__2.VerifyStage(5__4)) { 5__5 = typeof(DoorwaySistersRule).GetMethod("CanDoorwaysConnect", BindingFlags.Static | BindingFlags.Public); 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 = 5__4; <>1__state = 9; return true; } <>m__Finally1(); <>s__3 = null; 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 IEnumerable.GetEnumerator() { d__1 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__1(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] [HarmonyPrefix] public static void ConnectOverlappingDoorwaysPrePatch(ref DungeonProxy __instance) { IEnumerable list = __instance.AllTiles.SelectMany((TileProxy t) => t.Doorways); DoorwaySistersRule.UpdateCache(list); } [IteratorStateMachine(typeof(d__1))] [HarmonyTranspiler] [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] public static IEnumerable ConnectOverlappingDoorwaysPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(-2) { <>3__instructions = instructions }; } } internal class DungeonGeneratorPatch { [CompilerGenerated] private sealed class d__8 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private InstructionSequenceStandard 5__1; private IEnumerator <>s__2; private CodeInstruction 5__3; private MethodInfo 5__4; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; <>s__2 = null; 5__3 = null; 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; 5__1 = new InstructionSequenceStandard("Add Tile Placement"); 5__1.AddBasic(OpCodes.Callvirt); 5__1.AddBasic(OpCodes.Ldc_I4_0); 5__1.AddBasic(OpCodes.Bgt); 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)5__4); <>1__state = 4; return true; case 4: <>1__state = -3; <>2__current = 5__3; <>1__state = 5; return true; case 5: <>1__state = -3; break; case 6: <>1__state = -3; 5__3 = null; break; } if (<>s__2.MoveNext()) { 5__3 = <>s__2.Current; if (5__1.VerifyStage(5__3)) { 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 = 5__3; <>1__state = 6; return true; } <>m__Finally1(); <>s__2 = null; 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 IEnumerable.GetEnumerator() { d__8 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__8(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__10 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private InstructionSequenceStandard 5__1; private FieldInfo 5__2; private IEnumerator <>s__3; private CodeInstruction 5__4; private FieldInfo 5__5; private MethodInfo 5__6; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 5u) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__4 = null; 5__5 = null; 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; 5__1 = new InstructionSequenceStandard("TileProxyNull"); 5__1.AddBasic(OpCodes.Br); 5__1.AddBasicLocal(OpCodes.Ldloc_S, 15); 5__1.AddBasic(OpCodes.Brtrue); 5__2 = null; <>s__3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; if (5__2 != null) { 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)5__2); <>1__state = 4; return true; case 4: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__6); <>1__state = 5; return true; case 5: <>1__state = -3; 5__6 = null; break; case 6: <>1__state = -3; 5__5 = null; 5__4 = null; break; } if (<>s__3.MoveNext()) { 5__4 = <>s__3.Current; object operand = 5__4.operand; 5__5 = operand as FieldInfo; if ((object)5__5 != null && 5__5.Name.StartsWith("")) { 5__2 = 5__5; } if (5__1.VerifyStage(5__4)) { <>2__current = 5__4; <>1__state = 1; return true; } <>2__current = 5__4; <>1__state = 6; return true; } <>m__Finally1(); <>s__3 = null; 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 IEnumerable.GetEnumerator() { d__10 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__10(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__5 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private MethodInfo 5__1; private FieldInfo 5__2; private InstructionSequenceStandard 5__3; private InstructionSequenceStandard 5__4; private IEnumerator <>s__5; private CodeInstruction 5__6; private MethodInfo 5__7; private MethodInfo 5__8; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>s__5 = null; 5__6 = null; 5__7 = null; 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; 5__1 = typeof(DungeonFlow).GetMethod("GetLineAtDepth", BindingFlags.Instance | BindingFlags.Public); 5__2 = typeof(DungeonFlow).GetField("Nodes", BindingFlags.Instance | BindingFlags.Public); 5__3 = new InstructionSequenceStandard("GetLineAtDepth"); 5__3.AddBasic(OpCodes.Callvirt, 5__1); 5__4 = new InstructionSequenceStandard("Nodes", single: false); 5__4.AddBasic(OpCodes.Ldfld, 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; 5__6 = null; break; } if (<>s__5.MoveNext()) { 5__6 = <>s__5.Current; if (5__3.VerifyStage(5__6)) { 5__7 = typeof(DunGenPlusGenerator).GetMethod("GetLineAtDepth", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Call, (object)5__7); <>1__state = 1; return true; } if (5__4.VerifyStage(5__6)) { 5__8 = typeof(DunGenPlusGenerator).GetMethod("GetNodes", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Call, (object)5__8); <>1__state = 2; return true; } <>2__current = 5__6; <>1__state = 3; return true; } <>m__Finally1(); <>s__5 = null; 5__3.ReportComplete(); 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 IEnumerable.GetEnumerator() { d__5 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__5(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__4 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private MethodInfo 5__1; private InstructionSequenceStandard 5__2; private InstructionSequenceStandard 5__3; private IEnumerator <>s__4; private CodeInstruction 5__5; private MethodInfo 5__6; private MethodInfo 5__7; private MethodInfo 5__8; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(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) <= 9u) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; 5__3 = null; <>s__4 = null; 5__5 = null; 5__6 = null; 5__7 = null; 5__8 = 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_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = typeof(TilePlacementParameters).GetMethod("set_Node", BindingFlags.Instance | BindingFlags.NonPublic); 5__2 = new InstructionSequenceStandard("archetype node"); 5__2.AddBasicLocal(OpCodes.Ldloc_S, 10); 5__2.AddBasicLocal(OpCodes.Ldloc_S, 8); 5__2.AddBasic(OpCodes.Callvirt, 5__1); 5__3 = new InstructionSequenceStandard("attach to"); 5__3.AddBasicLocal(OpCodes.Stloc_S, 14); <>s__4 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)10); <>1__state = 2; return true; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)8); <>1__state = 3; return true; case 3: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Ldloc_1, (object)null); <>1__state = 4; return true; case 4: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__6); <>1__state = 5; return true; case 5: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__7); <>1__state = 6; return true; case 6: <>1__state = -3; break; case 7: <>1__state = -3; 5__8 = typeof(MainRoomDoorwayGroups).GetMethod("ModifyGroupBasedOnBehaviourSimple", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Ldloc_S, (object)14); <>1__state = 8; return true; case 8: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__8); <>1__state = 9; return true; case 9: <>1__state = -3; break; case 10: <>1__state = -3; 5__5 = null; break; } if (<>s__4.MoveNext()) { 5__5 = <>s__4.Current; if (5__2.VerifyStage(5__5)) { 5__6 = typeof(DungeonGenerator).GetMethod("get_RandomStream", BindingFlags.Instance | BindingFlags.Public); 5__7 = typeof(DunGenPlusGenerator).GetMethod("ModifyMainBranchNodeArchetype", BindingFlags.Static | BindingFlags.Public); <>2__current = 5__5; <>1__state = 1; return true; } if (5__3.VerifyStage(5__5)) { <>2__current = 5__5; <>1__state = 7; return true; } <>2__current = 5__5; <>1__state = 10; return true; } <>m__Finally1(); <>s__4 = null; 5__2.ReportComplete(); 5__3.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__4 != null) { <>s__4.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__4 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__4(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__6 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private FieldInfo 5__1; private MethodInfo 5__2; private InstructionSequenceStandard 5__3; private InstructionSequenceStandard 5__4; private IEnumerator <>s__5; private CodeInstruction 5__6; private MethodInfo 5__7; private MethodInfo 5__8; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(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(); } } 5__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>s__5 = null; 5__6 = null; 5__7 = null; 5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = typeof(DungeonFlow).GetField("Length", BindingFlags.Instance | BindingFlags.Public); 5__2 = typeof(Application).GetMethod("get_isEditor", BindingFlags.Static | BindingFlags.Public); 5__3 = new InstructionSequenceStandard("Length"); 5__3.AddBasic(OpCodes.Ldfld, 5__1); 5__4 = new InstructionSequenceStandard("Editor"); 5__4.AddBasic(OpCodes.Call, 5__2); <>s__5 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)5__8); <>1__state = 3; return true; case 3: <>1__state = -3; break; case 4: <>1__state = -3; 5__6 = null; break; } if (<>s__5.MoveNext()) { 5__6 = <>s__5.Current; if (5__3.VerifyStage(5__6)) { 5__7 = typeof(DunGenPlusGenerator).GetMethod("GetLength", BindingFlags.Static | BindingFlags.Public); <>2__current = new CodeInstruction(OpCodes.Call, (object)5__7); <>1__state = 1; return true; } if (5__4.VerifyStage(5__6)) { 5__8 = typeof(DunGenPlusGenerator).GetMethod("AllowRetryStop", BindingFlags.Static | BindingFlags.Public); <>2__current = 5__6; <>1__state = 2; return true; } <>2__current = 5__6; <>1__state = 4; return true; } <>m__Finally1(); <>s__5 = null; 5__3.ReportComplete(); 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 IEnumerable.GetEnumerator() { d__6 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__6(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static TileProxy lastAttachTo; public static IEnumerable lastUseableTileSets; public static float lastNormalizedDepth; public static TilePlacementParameters lastPlacementParms; [HarmonyPriority(800)] [HarmonyPatch(typeof(DungeonGenerator), "Generate")] [HarmonyPrefix] public static void GeneratePatch(ref DungeonGenerator __instance) { DunGenPlusGenerator.Deactivate(); DungeonFlow dungeonFlow = __instance.DungeonFlow; DunGenExtender dunGenExtender = API.GetDunGenExtender(dungeonFlow); if (Object.op_Implicit((Object)(object)dunGenExtender) && dunGenExtender.Active) { Plugin.logger.LogInfo((object)("Loading DunGenExtender for " + ((Object)dungeonFlow).name)); DunGenPlusGenerator.Activate(__instance, dunGenExtender); } else { Plugin.logger.LogInfo((object)"Did not load a DunGenExtenderer"); DunGenPlusGenerator.Deactivate(); } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate")] public static void InnerGeneratePatch(ref DungeonGenerator __instance, bool isRetry) { if (API.IsDevDebugModeActive() && !isRetry) { DevDebugManager.Instance.RecordNewSeed(__instance.ChosenSeed); } if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { TileProxyPatch.ResetDictionary(); DunGenPlusGenerator.SetCurrentMainPathExtender(0); MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviourSimpleOnce = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath")] public static void GenerateMainPathPatch(ref DungeonGenerator __instance) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { DunGenPlusGenerator.RandomizeLineArchetypes(__instance, randomizeMainPath: true); } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "GenerateBranchPaths")] public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance, ref IEnumerator __result) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { __result = DunGenPlusGenerator.GenerateAlternativeMainPaths(__instance); } } [IteratorStateMachine(typeof(d__4))] [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable GenerateMainPathPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(-2) { <>3__instructions = instructions }; } [IteratorStateMachine(typeof(d__5))] [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable GenerateMainPathGetLineAtDepthPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(-2) { <>3__instructions = instructions }; } [IteratorStateMachine(typeof(d__6))] [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable InnerGenerateLengthPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(-2) { <>3__instructions = instructions }; } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "PostProcess")] public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance) { if (DunGenPlusGenerator.Active) { int value = __instance.RandomStream.Next(999); SpawnSyncedObjectCycle.UpdateCycle(value); } } [IteratorStateMachine(typeof(d__8))] [HarmonyTranspiler] [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] public static IEnumerable AddTileDebugPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(-2) { <>3__instructions = instructions }; } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")] public static bool ProcessGlobalPropsPatch(ref DungeonGenerator __instance) { if (DunGenPlusGenerator.Active) { bool flag = DunGenPlusGenerator.Properties.MainPathProperties.DetailedGlobalPropSettings.Count > 0; bool flag2 = DunGenPlusGenerator.Properties.MainPathProperties.MainPathDetails.Any((MainPathExtender d) => d.LocalGroupProps.Count > 0); if (flag || flag2) { Plugin.logger.LogDebug((object)"Performing Local Global Props algorithm"); DunGenPlusGenerator.ProcessGlobalPropsPerMainPath(__instance); return false; } } return true; } [IteratorStateMachine(typeof(d__10))] [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable GenerateMainPathDebugPatch(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(-2) { <>3__instructions = instructions }; } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] public static void AddTileDebugPatch(TileProxy attachTo, IEnumerable useableTileSets, float normalizedDepth, TilePlacementParameters placementParams) { lastAttachTo = attachTo; lastUseableTileSets = useableTileSets; lastNormalizedDepth = normalizedDepth; lastPlacementParms = placementParams; } } internal class LethalLevelLoaderPatches { [HarmonyPrefix] [HarmonyPatch(typeof(Patches), "DungeonGeneratorGenerate_Prefix")] public static bool DungeonGeneratorGenerate_Prefix_Patches_Prefix() { return (Object)(object)DevDebugManager.Instance == (Object)null; } [HarmonyPatch(typeof(EventPatches), "DungeonGeneratorGenerate_Prefix")] [HarmonyPrefix] public static void DungeonGeneratorGenerate_Prefix_EventPatches_Prefix() { ScrapItemManager.Initialize(Patches.RoundManager); EnemyManager.Initialize(Patches.RoundManager); } } internal class RoundManagerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] public static void GenerateBranchPathsPatch() { if (DunGenPlusGenerator.Active) { Plugin.logger.LogDebug((object)"Alt. InnerGenerate() function complete"); } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "SetPowerOffAtStart")] public static void SetPowerOffAtStartPatch() { DoorwayManager.onMainEntranceTeleportSpawnedEvent.Call(); } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "Awake")] public static void AwakePatch() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (PluginConfig.EnableDevDebugTools.Value) { GameObject val = new GameObject("DevDebugOpen", new Type[1] { typeof(DevDebugOpen) }); } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "Start")] public static void StartPatch(ref RoundManager __instance) { ScrapItemManager.UndoPreviousChanges(); EnemyManager.UndoPreviousChanges(); } [HarmonyPrefix] [HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")] public static void waitForScrapToSpawnToSyncPatch(ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn) { return; } List list = spawnedScrap.ToList(); List list2 = scrapValues.ToList(); RandomGuaranteedScrapSpawn[] array = Object.FindObjectsOfType(); RandomGuaranteedScrapSpawn.ResetCache(); RandomGuaranteedScrapSpawn[] array2 = array; foreach (RandomGuaranteedScrapSpawn randomGuaranteedScrapSpawn in array2) { (NetworkObject, int) tuple = randomGuaranteedScrapSpawn.CreateItem(__instance, __instance.currentLevel.spawnableScrap); if ((Object)(object)tuple.Item1 != (Object)null) { Plugin.logger.LogDebug((object)$"Created guaranteed item {((Object)((Component)tuple.Item1).gameObject).name} w/ value {tuple.Item2}"); list.Add(NetworkObjectReference.op_Implicit(tuple.Item1)); list2.Add(tuple.Item2); } } spawnedScrap = list.ToArray(); scrapValues = list2.ToArray(); } [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch(typeof(RoundManager), "SetLevelObjectVariables")] public static void SetLevelObjectVariablesPatch(ref RoundManager __instance) { DoorwayManager.SetLevelObjectVariablesFunction(); } } internal class StartOfRoundPatch { } } namespace DunGenPlus.Managers { public static class EnemyManager { internal static SelectableLevel previousLevel; internal static List previouslyAddedEnemies = new List(); internal static List previouslyModifiedEnemies = new List(); internal static void UndoPreviousChanges() { if (!((Object)(object)previousLevel != (Object)null)) { return; } Plugin.logger.LogDebug((object)("Undoing changes of EnemyManager for " + previousLevel.PlanetName)); List enemies = previousLevel.Enemies; if (previouslyAddedEnemies.Count > 0) { for (int num = previouslyAddedEnemies.Count - 1; num >= 0; num--) { SpawnableEnemyWithRarity val = previouslyAddedEnemies[num]; int num2 = enemies.Count - 1; while (true) { if (num2 >= 0) { SpawnableEnemyWithRarity val2 = enemies[num2]; if (val2 == val) { enemies.RemoveAt(num2); Plugin.logger.LogDebug((object)("Properly removed temporary enemy " + val.enemyType.enemyName)); break; } num2--; continue; } Plugin.logger.LogWarning((object)("Couldn't find/remove temporary enemy " + val.enemyType.enemyName)); break; } } previouslyAddedEnemies.Clear(); } if (previouslyModifiedEnemies.Count > 0) { for (int i = 0; i < previouslyModifiedEnemies.Count; i++) { SpawnableEnemyWithRarity val3 = previouslyModifiedEnemies[i]; int num3 = 0; while (true) { if (num3 < enemies.Count) { if ((Object)(object)enemies[num3].enemyType == (Object)(object)val3.enemyType) { enemies[num3] = val3; Plugin.logger.LogDebug((object)("Properly fixed modified enemy " + val3.enemyType.enemyName)); break; } num3++; continue; } Plugin.logger.LogWarning((object)("Couldn't find/fix modified enemy " + val3.enemyType.enemyName)); break; } } previouslyModifiedEnemies.Clear(); } previousLevel = null; } internal static void Initialize(RoundManager roundManager) { UndoPreviousChanges(); previousLevel = roundManager.currentLevel; Plugin.logger.LogDebug((object)("Initialized EnemyManager to " + previousLevel.PlanetName)); } public static void AddEnemies(IEnumerable newEnemies) { foreach (SpawnableEnemyWithRarity newEnemy in newEnemies) { AddEnemy(newEnemy); } } public static void AddEnemy(SpawnableEnemyWithRarity newEnemy) { List enemies = previousLevel.Enemies; for (int i = 0; i < enemies.Count; i++) { if ((Object)(object)enemies[i].enemyType == (Object)(object)newEnemy.enemyType) { if (enemies[i].rarity == newEnemy.rarity) { Plugin.logger.LogDebug((object)("Skipping " + newEnemy.enemyType.enemyName + " as it has the same rarity")); return; } previouslyModifiedEnemies.Add(enemies[i]); enemies[i] = newEnemy; Plugin.logger.LogDebug((object)$"Modifying already existing enemy {newEnemy.enemyType.enemyName} to new weight {newEnemy.rarity}"); return; } } previouslyAddedEnemies.Add(newEnemy); enemies.Add(newEnemy); Plugin.logger.LogDebug((object)$"Adding temporary enemy {newEnemy.enemyType.enemyName} with weight {newEnemy.rarity}"); } } public static class ScrapItemManager { internal static SelectableLevel previousLevel; internal static List previouslyAddedItems = new List(); internal static List previouslyModifiedItems = new List(); internal static void UndoPreviousChanges() { if (!((Object)(object)previousLevel != (Object)null)) { return; } Plugin.logger.LogDebug((object)("Undoing changes of ScrapItemManager for " + previousLevel.PlanetName)); List spawnableScrap = previousLevel.spawnableScrap; if (previouslyAddedItems.Count > 0) { for (int num = previouslyAddedItems.Count - 1; num >= 0; num--) { SpawnableItemWithRarity val = previouslyAddedItems[num]; int num2 = spawnableScrap.Count - 1; while (true) { if (num2 >= 0) { SpawnableItemWithRarity val2 = spawnableScrap[num2]; if (val2 == val) { spawnableScrap.RemoveAt(num2); Plugin.logger.LogDebug((object)("Properly removed temporary item " + val.spawnableItem.itemName)); break; } num2--; continue; } Plugin.logger.LogWarning((object)("Couldn't find/remove temporary item " + val.spawnableItem.itemName)); break; } } previouslyAddedItems.Clear(); } if (previouslyModifiedItems.Count > 0) { for (int i = 0; i < previouslyModifiedItems.Count; i++) { SpawnableItemWithRarity val3 = previouslyModifiedItems[i]; int num3 = 0; while (true) { if (num3 < spawnableScrap.Count) { if ((Object)(object)spawnableScrap[num3].spawnableItem == (Object)(object)val3.spawnableItem) { spawnableScrap[num3] = val3; Plugin.logger.LogDebug((object)("Properly fixed modified item " + val3.spawnableItem.itemName)); break; } num3++; continue; } Plugin.logger.LogWarning((object)("Couldn't find/fix modified item " + val3.spawnableItem.itemName)); break; } } previouslyModifiedItems.Clear(); } previousLevel = null; } internal static void Initialize(RoundManager roundManager) { UndoPreviousChanges(); previousLevel = roundManager.currentLevel; Plugin.logger.LogDebug((object)("Initialized ScrapItemManager to " + previousLevel.PlanetName)); } public static void AddItems(IEnumerable newItems) { foreach (SpawnableItemWithRarity newItem in newItems) { AddItem(newItem); } } public static void AddItem(SpawnableItemWithRarity newItem) { List spawnableScrap = previousLevel.spawnableScrap; for (int i = 0; i < spawnableScrap.Count; i++) { if ((Object)(object)spawnableScrap[i].spawnableItem == (Object)(object)newItem.spawnableItem) { if (spawnableScrap[i].rarity == newItem.rarity) { Plugin.logger.LogDebug((object)("Skipping " + newItem.spawnableItem.itemName + " as it has the same rarity")); return; } previouslyModifiedItems.Add(spawnableScrap[i]); spawnableScrap[i] = newItem; Plugin.logger.LogDebug((object)$"Modifying already existing item {newItem.spawnableItem.itemName} to new weight {newItem.rarity}"); return; } } previouslyAddedItems.Add(newItem); spawnableScrap.Add(newItem); Plugin.logger.LogDebug((object)$"Adding temporary item {newItem.spawnableItem.itemName} with weight {newItem.rarity}"); } } public static class DoorwayManager { public class Scripts { public List scriptList; public List actionList; public Scripts() { scriptList = new List(); actionList = new List(); } public void Add(IDunGenScriptingParent script) { scriptList.Add(script); } public void Add(Action action) { actionList.Add(action); } public bool Call() { foreach (IDunGenScriptingParent script in scriptList) { script.Call(); } foreach (Action action in actionList) { action(); } return scriptList.Count + actionList.Count > 0; } } public static ActionList onMainEntranceTeleportSpawnedEvent = new ActionList("onMainEntranceTeleportSpawned"); public static Dictionary scriptingLists; public static void ResetList() { scriptingLists = new Dictionary(); foreach (DunGenScriptingHook value in Enum.GetValues(typeof(DunGenScriptingHook))) { scriptingLists.Add(value, new Scripts()); } } public static void AddDunGenScriptHook(IDunGenScriptingParent script) { scriptingLists[script.GetScriptingHook].Add(script); } public static void AddActionHook(DunGenScriptingHook hook, Action action) { scriptingLists[hook].Add(action); } public static void OnMainEntranceTeleportSpawnedFunction() { if (!DunGenPlusGenerator.Active) { return; } bool flag = false; foreach (Scripts value in scriptingLists.Values) { flag |= value.Call(); } if (flag) { try { RuntimeDungeon dungeonGenerator = RoundManager.Instance.dungeonGenerator; UnityNavMeshAdapter componentInChildren = ((Component)((Component)dungeonGenerator).transform.parent).GetComponentInChildren(); ((BaseAdapter)componentInChildren).Run(dungeonGenerator.Generator); Plugin.logger.LogDebug((object)"Rebuild nav mesh"); } catch (Exception ex) { Plugin.logger.LogError((object)"Failed to rebuild nav mesh"); Plugin.logger.LogError((object)ex.ToString()); } } } public static void SetLevelObjectVariablesFunction() { if (DunGenPlusGenerator.Active) { scriptingLists[DunGenScriptingHook.SetLevelObjectVariables].Call(); } } } } namespace DunGenPlus.Generation { internal class DunGenPlusGenerator { private class BranchPathProxy { public TileProxy mainPathTile; public int mainPathIndex; public List list; public float weight; public Dictionary injectedTiles; public List tilesPendingInjection; public BranchPathProxy(DungeonGenerator gen, TileProxy attachTileProxy) { mainPathTile = attachTileProxy; mainPathIndex = GetMainPathIndexFromTileProxy(attachTileProxy); list = new List(); weight = 0f; injectedTiles = new Dictionary(gen.injectedTiles); tilesPendingInjection = new List(gen.tilesPendingInjection); } public void CalculateWeight(DungeonGenerator gen) { //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) int count = list.Count; if (count == 0) { return; } TilePlacementResultProxy tilePlacementResultProxy = list[count - 1]; BranchPathMultiSimulationProperties branchPathMultiSimulationProperties = Properties.BranchPathMultiSimulationProperties; int branchDepth = tilePlacementResultProxy.tileProxy.Placement.BranchDepth; float normalizedBranchDepth = tilePlacementResultProxy.tileProxy.Placement.NormalizedBranchDepth; weight += branchPathMultiSimulationProperties.GetWeightBase(branchDepth, normalizedBranchDepth); IEnumerable enumerable = gen.proxyDungeon.AllTiles.SelectMany((TileProxy t) => t.Doorways); ProposedConnection val = default(ProposedConnection); foreach (TilePlacementResultProxy item in list) { foreach (DoorwayProxy item2 in enumerable) { if (item2.TileProxy == mainPathTile) { continue; } int mainPathIndexFromTileProxy = GetMainPathIndexFromTileProxy(item2.TileProxy); foreach (DoorwayProxy doorway in item.tileProxy.doorways) { if (item2.TileProxy != item.previousDoorway.TileProxy) { ((ProposedConnection)(ref val))..ctor(gen.proxyDungeon, item2.TileProxy, doorway.TileProxy, item2, doorway); if (gen.DungeonFlow.CanDoorwaysConnect(val) && (double)Vector3.SqrMagnitude(item2.Position - doorway.Position) < 1E-05) { int num = Mathf.Abs(item2.TileProxy.Placement.PathDepth - doorway.TileProxy.Placement.PathDepth); float normalizedDepthDifference = Mathf.Abs(item2.TileProxy.Placement.NormalizedPathDepth - doorway.TileProxy.Placement.NormalizedPathDepth); bool samePath = mainPathIndex == mainPathIndexFromTileProxy; weight += branchPathMultiSimulationProperties.GetWeightPathConnection(samePath, num, normalizedDepthDifference); } } } } } } } private class TilePlacementResultProxy { public TilePlacementResult result; public TileProxy tileProxy; public DoorwayProxy previousDoorway; public DoorwayProxy nextDoorway; public TilePlacementResultProxy(TilePlacementResult result) { this.result = result; tileProxy = null; previousDoorway = null; nextDoorway = null; } public TilePlacementResultProxy(TilePlacementResult result, TileProxy tile, DoorwayProxy previousDoorway, DoorwayProxy nextDoorway) { this.result = result; tileProxy = tile; this.previousDoorway = previousDoorway; this.nextDoorway = nextDoorway; } public override string ToString() { return $"result: {result}\ntile: {tileProxy}\nprev: {previousDoorway}\nnext: {nextDoorway}"; } } [CompilerGenerated] private sealed class <>c__DisplayClass41_0 { public GameObject mainRoomTilePrefab; public Func <>9__4; public Predicate <>9__2; internal bool b__0(TileProxy t) { return (Object)(object)t.Prefab == (Object)(object)mainRoomTilePrefab; } internal bool b__2(GraphNode n) { return n.TileSets.SelectMany((TileSet t) => t.TileWeights.Weights).Any((GameObjectChance t) => (Object)(object)t.Value == (Object)(object)mainRoomTilePrefab); } internal bool b__4(GameObjectChance t) { return (Object)(object)t.Value == (Object)(object)mainRoomTilePrefab; } } [CompilerGenerated] private sealed class <>c__DisplayClass41_1 { public float lineDepthRatio; internal bool b__5(GraphNode n) { return n.Position >= lineDepthRatio; } } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <>c__DisplayClass64_0 { public DoorwayProxy nextDoor; } [CompilerGenerated] private sealed class d__41 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public DungeonGenerator gen; private <>c__DisplayClass41_0 <>8__1; private int 5__2; private List 5__3; private DunGenExtenderProperties.CopyNodeBehaviour 5__4; private List> 5__5; private TileProxy 5__6; private int 5__7; private int 5__8; private bool 5__9; private int 5__10; private int 5__11; private List 5__12; private List> 5__13; private List 5__14; private int 5__15; private GraphNode[] 5__16; private List 5__17; private TileProxy 5__18; private List 5__19; private int 5__20; private int 5__21; private <>c__DisplayClass41_1 <>8__22; private float 5__23; private GraphLine 5__24; private GraphNode 5__25; private TilePlacementParameters 5__26; private List 5__27; private GraphNode[] <>s__28; private int <>s__29; private GraphNode 5__30; private int 5__31; private int 5__32; private TileProxy 5__33; private float 5__34; private TileProxy 5__35; private int 5__36; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__41(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__3 = null; 5__5 = null; 5__6 = null; 5__12 = null; 5__13 = null; 5__14 = null; 5__16 = null; 5__17 = null; 5__18 = null; 5__19 = null; <>8__22 = null; 5__24 = null; 5__25 = null; 5__26 = null; 5__27 = null; <>s__28 = null; 5__30 = null; 5__33 = null; 5__35 = null; <>1__state = -2; } private bool MoveNext() { //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_06f1: Expected O, but got Unknown int num; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass41_0(); if (!Active) { ActiveAlternative = false; <>2__current = gen.Wait(gen.GenerateBranchPaths()); <>1__state = 1; return true; } 5__2 = Properties.MainPathProperties.MainPathCount - 1; tileProxyMainPath.Clear(); tileMainPath.Clear(); 5__3 = gen.proxyDungeon.MainPathTiles.ToList(); AddMainPathTileProxies(5__3, 0); <>8__1.mainRoomTilePrefab = Properties.MainPathProperties.MainRoomTilePrefab; 5__4 = Properties.MainPathProperties.CopyNodeBehaviour; if (5__2 <= 0) { <>2__current = gen.Wait(GenerateBranchPaths(gen, null, $"MainPathCount being {5__2 + 1}", (LogLevel)16)); <>1__state = 2; return true; } if ((Object)(object)<>8__1.mainRoomTilePrefab == (Object)null) { <>2__current = gen.Wait(GenerateBranchPaths(gen, null, "MainRoomTilePrefab being null", (LogLevel)4)); <>1__state = 3; return true; } 5__5 = new List>(); 5__5.Add(5__3); 5__6 = ((IEnumerable)gen.proxyDungeon.MainPathTiles).FirstOrDefault((Func)((TileProxy t) => (Object)(object)t.Prefab == (Object)(object)<>8__1.mainRoomTilePrefab)); if (5__6 == null) { <>2__current = gen.Wait(GenerateBranchPaths(gen, null, "MainRoomTilePrefab not spawning on the main path", (LogLevel)4)); <>1__state = 4; return true; } 5__7 = 5__6.Placement.Depth + 1; Plugin.logger.LogDebug((object)$"Main Room Length Index: {5__7}"); gen.ChangeStatus((GenerationStatus)3); 5__8 = 0; goto IL_0b18; case 1: <>1__state = -1; ActiveAlternative = true; return false; case 2: <>1__state = -1; return false; case 3: <>1__state = -1; return false; case 4: <>1__state = -1; return false; case 5: <>1__state = -1; return false; case 6: <>1__state = -1; return false; case 7: <>1__state = -1; return false; case 8: <>1__state = -1; goto IL_0a1c; case 9: <>1__state = -1; GenerateBranchBoostedPathsStopWatch.Stop(); GenerateBranchBoostedPathsTime += (float)GenerateBranchBoostedPathsStopWatch.Elapsed.TotalMilliseconds; goto IL_0c8b; case 10: { <>1__state = -1; goto IL_0c8b; } IL_0c8b: num = 5__36 + 1; 5__36 = num; break; IL_0b18: if (5__8 < 5__2) { SetCurrentMainPathExtender(5__8 + 1); RandomizeLineArchetypes(gen, randomizeMainPath: true); 5__9 = false; 5__10 = 5__7; gen.nextNodeIndex = 5__7; 5__11 = Mathf.RoundToInt((float)GetLength(gen.DungeonFlow).GetRandom(gen.RandomStream) * gen.LengthMultiplier); 5__12 = new List(5__11); 5__13 = new List>(5__11); MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviour(5__6, 5__8 + 1); 5__14 = (from n in GetNodes(gen.DungeonFlow) orderby n.Position select n).ToList(); if (5__4 == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList) { 5__21 = 5__14.FindIndex((GraphNode n) => n.TileSets.SelectMany((TileSet t) => t.TileWeights.Weights).Any((GameObjectChance t) => (Object)(object)t.Value == (Object)(object)<>8__1.mainRoomTilePrefab)); if (5__21 == -1) { <>2__current = gen.Wait(GenerateBranchPaths(gen, 5__6, "CopyNodeBehaviour being CopyFromNodeList AND MainRoomTilePrefab not existing in the Nodes' tilesets", (LogLevel)4)); <>1__state = 5; return true; } 5__15 = 5__21 + 1; } else if (5__4 == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromMainPathPosition) { <>8__22 = new <>c__DisplayClass41_1(); <>8__22.lineDepthRatio = Mathf.Clamp01((float)5__6.Placement.Depth / (float)(5__11 - 1)); 5__15 = 5__14.FindIndex((GraphNode n) => n.Position >= <>8__22.lineDepthRatio); <>8__22 = null; } else { Plugin.logger.LogFatal((object)$"{5__4} is not yet defined. Really really bad"); 5__15 = -1; } 5__16 = 5__14.Skip(5__15).ToArray(); 5__17 = new List(5__16.Count()); while (!5__9) { 5__23 = Mathf.Clamp01((float)5__10 / (float)(5__11 - 1)); 5__24 = GetLineAtDepth(gen.DungeonFlow, 5__23); if (5__24 == null) { <>2__current = gen.Wait(gen.InnerGenerate(true)); <>1__state = 6; return true; } if (5__24 != gen.previousLineSegment) { gen.currentArchetype = 5__24.GetRandomArchetype(gen.RandomStream, 5__12.Select((TilePlacementParameters x) => x.Archetype)); gen.previousLineSegment = 5__24; } 5__25 = null; <>s__28 = 5__16; for (<>s__29 = 0; <>s__29 < <>s__28.Length; <>s__29++) { 5__30 = <>s__28[<>s__29]; if (5__23 >= 5__30.Position && !5__17.Contains(5__30)) { 5__25 = 5__30; 5__17.Add(5__30); break; } 5__30 = null; } <>s__28 = null; 5__26 = new TilePlacementParameters(); 5__12.Add(5__26); if (5__25 != null) { 5__27 = 5__25.TileSets; gen.nextNodeIndex = ((gen.nextNodeIndex >= 5__16.Length - 1) ? (-1) : (gen.nextNodeIndex + 1)); 5__26.Node = 5__25; ModifyMainBranchNodeArchetype(5__26, 5__25, gen.RandomStream); if (5__25 == 5__16[5__16.Length - 1]) { 5__9 = true; } } else { 5__27 = gen.currentArchetype.TileSets; 5__26.Archetype = gen.currentArchetype; 5__26.Line = 5__24; } 5__13.Add(5__27); 5__10++; 5__24 = null; 5__25 = null; 5__26 = null; 5__27 = null; } 5__18 = 5__6; 5__19 = new List(); 5__31 = 0; goto IL_0a92; } MainRoomDoorwayGroups.RemoveFakeDoorwayProxies(5__6); ActiveAlternative = false; Plugin.logger.LogDebug((object)$"Created {5__2} alt. paths, creating branches now"); gen.ChangeStatus((GenerationStatus)4); 5__36 = 0; break; IL_0a92: if (5__31 < 5__12.Count) { 5__32 = 5__31 + 5__7; 5__33 = ((5__31 == 0) ? 5__6 : 5__19[5__19.Count - 1]); 5__34 = (float)5__32 / (float)(5__11 - 1); 5__35 = gen.AddTile(5__33, (IEnumerable)5__13[5__31], 5__34, 5__12[5__31]); if (5__35 == null) { PrintAddTileError(gen, 5__18, 5__12[5__31], 5__13[5__31], 5__8 + 1, 5__32, 5__34); <>2__current = gen.Wait(gen.InnerGenerate(true)); <>1__state = 7; return true; } 5__35.Placement.BranchDepth = 5__32; 5__35.Placement.NormalizedBranchDepth = 5__34; 5__35.Placement.PlacementParameters = 5__12[5__31]; 5__19.Add(5__35); if (gen.ShouldSkipFrame(true)) { <>2__current = gen.GetRoomPause(); <>1__state = 8; return true; } goto IL_0a1c; } AddMainPathTileProxies(5__19, 5__8 + 1); 5__5.Add(5__19); 5__12 = null; 5__13 = null; 5__14 = null; 5__16 = null; 5__17 = null; 5__18 = null; 5__19 = null; num = 5__8 + 1; 5__8 = num; goto IL_0b18; IL_0a1c: 5__20 = 5__31; if (5__31 == 5__12.Count - 1) { Plugin.logger.LogDebug((object)$"Alt. main branch at {5__8} ended with {((Object)5__35.PrefabTile).name}"); } 5__33 = null; 5__35 = null; 5__31 = 5__20 + 1; goto IL_0a92; } if (5__36 < 5__2 + 1) { Plugin.logger.LogDebug((object)$"Branch {5__36}"); SetCurrentMainPathExtender(5__36); RandomizeLineArchetypes(gen, randomizeMainPath: false); gen.proxyDungeon.MainPathTiles = 5__5[5__36]; if (Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim) { GenerateBranchBoostedPathsStopWatch.Reset(); GenerateBranchBoostedPathsStopWatch.Start(); <>2__current = gen.Wait(GenerateMultiBranchPaths(gen)); <>1__state = 9; return true; } <>2__current = gen.Wait(gen.GenerateBranchPaths()); <>1__state = 10; return true; } ActiveAlternative = true; gen.proxyDungeon.MainPathTiles = 5__5[0]; if (!Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim) { BuildBranchPathTileProxiesDictionary(gen.proxyDungeon); } AddAdditionalTiles(gen); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__42 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public DungeonGenerator gen; public TileProxy mainRoom; public string message; public LogLevel logLevel; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__42(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; Plugin.logger.Log(logLevel, (object)("Switching to default dungeon branch generation: " + message)); ActiveAlternative = false; SetCurrentMainPathExtender(0); if (mainRoom != null) { MainRoomDoorwayGroups.RemoveFakeDoorwayProxies(mainRoom); } <>2__current = gen.Wait(gen.GenerateBranchPaths()); <>1__state = 1; return true; case 1: <>1__state = -1; ActiveAlternative = true; BuildBranchPathTileProxiesDictionary(gen.proxyDungeon); AddAdditionalTiles(gen); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__53 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public DungeonGenerator gen; private int[] 5__1; private int 5__2; private TileProxy 5__3; private int 5__4; private int 5__5; private List 5__6; private BranchPathProxy 5__7; private int 5__8; private BranchPathProxy 5__9; private TileProxy 5__10; private int 5__11; private DungeonCollisionManager 5__12; private List.Enumerator <>s__13; private TileProxy 5__14; private int 5__15; private List 5__16; private float 5__17; private TilePlacementResultProxy 5__18; private TileProxy 5__19; private TilePlacementData 5__20; private Dictionary 5__21; private List.Enumerator <>s__22; private TilePlacementResultProxy 5__23; private Dictionary.Enumerator <>s__24; private KeyValuePair 5__25; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__53(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__3 = null; 5__6 = null; 5__7 = null; 5__9 = null; 5__10 = null; 5__12 = null; <>s__13 = default(List.Enumerator); 5__14 = null; 5__16 = null; 5__18 = null; 5__19 = null; 5__20 = null; 5__21 = null; <>s__22 = default(List.Enumerator); 5__23 = null; <>s__24 = default(Dictionary.Enumerator); 5__25 = default(KeyValuePair); <>1__state = -2; } private bool MoveNext() { //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Invalid comparison between Unknown and I4 //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Invalid comparison between Unknown and I4 int num; switch (<>1__state) { default: return false; case 0: <>1__state = -1; gen.ChangeStatus((GenerationStatus)4); 5__1 = new int[gen.proxyDungeon.MainPathTiles.Count]; BranchCountHelper.ComputeBranchCounts(gen.DungeonFlow, gen.RandomStream, gen.proxyDungeon, ref 5__1); 5__2 = 0; goto IL_086c; case 1: <>1__state = -1; goto IL_0510; case 2: { <>1__state = -1; goto IL_080b; } IL_086c: if (5__2 < 5__1.Length) { 5__3 = gen.proxyDungeon.MainPathTiles[5__2]; 5__4 = 5__1[5__2]; if ((Object)(object)5__3.Placement.Archetype == (Object)null || 5__4 == 0) { goto IL_085a; } 5__5 = 0; goto IL_0834; } return false; IL_0813: 5__6 = null; 5__7 = null; num = 5__5 + 1; 5__5 = num; goto IL_0834; IL_053f: if (5__15 < 5__11) { if (5__15 == 0 && 5__3.Placement.Archetype.GetHasValidBranchStartTiles()) { if ((int)5__3.Placement.Archetype.BranchStartType == 0) { 5__16 = 5__3.Placement.Archetype.BranchStartTileSets; } else { 5__16 = 5__3.Placement.Archetype.TileSets.Concat(5__3.Placement.Archetype.BranchStartTileSets).ToList(); } } if (5__15 == 5__11 - 1 && 5__3.Placement.Archetype.GetHasValidBranchCapTiles()) { if ((int)5__3.Placement.Archetype.BranchCapType == 0) { 5__16 = 5__3.Placement.Archetype.BranchCapTileSets; } else { 5__16 = 5__3.Placement.Archetype.TileSets.Concat(5__3.Placement.Archetype.BranchCapTileSets).ToList(); } } else { 5__16 = 5__3.Placement.Archetype.TileSets; } 5__17 = ((5__11 <= 1) ? 1f : ((float)5__15 / (float)(5__11 - 1))); GetTileResultStopwatch.Reset(); GetTileResultStopwatch.Start(); 5__18 = AddBranchTileSimulation(gen, 5__12, 5__9, 5__10, 5__16, 5__17, 5__3.Placement.PlacementParameters); GetTileResultStopwatch.Stop(); GetTileResultTime += (float)GetTileResultStopwatch.Elapsed.TotalMilliseconds; if (5__18 != null) { 5__19 = 5__18.tileProxy; 5__9.list.Add(5__18); 5__20 = 5__19.Placement; 5__20.BranchDepth = 5__15; 5__20.NormalizedBranchDepth = 5__17; 5__20.BranchId = 5__5; 5__20.PlacementParameters = 5__10.Placement.PlacementParameters; 5__10 = 5__19; if (gen.ShouldSkipFrame(true)) { <>2__current = gen.GetRoomPause(); <>1__state = 1; return true; } goto IL_0510; } } if (5__9.list.Count == 0) { goto IL_0620; } CalculateWeightStopwatch.Reset(); CalculateWeightStopwatch.Start(); 5__9.CalculateWeight(gen); CalculateWeightStopwatch.Stop(); CalculateWeightTime += (float)CalculateWeightStopwatch.Elapsed.TotalMilliseconds; 5__6.Add(5__9); 5__9 = null; 5__10 = null; 5__12 = null; num = 5__8 + 1; 5__8 = num; goto IL_0600; IL_0620: 5__7 = 5__6.OrderByDescending((BranchPathProxy p) => p.weight).FirstOrDefault(); if (5__7 != null) { <>s__22 = 5__7.list.GetEnumerator(); try { while (<>s__22.MoveNext()) { 5__23 = <>s__22.Current; MakeTileProxyConnection(gen, 5__23); 5__23 = null; } } finally { ((IDisposable)<>s__22).Dispose(); } <>s__22 = default(List.Enumerator); 5__21 = gen.injectedTiles; 5__21.Clear(); <>s__24 = 5__7.injectedTiles.GetEnumerator(); try { while (<>s__24.MoveNext()) { 5__25 = <>s__24.Current; 5__21.Add(5__25.Key, 5__25.Value); 5__25 = default(KeyValuePair); } } finally { ((IDisposable)<>s__24).Dispose(); } <>s__24 = default(Dictionary.Enumerator); gen.tilesPendingInjection = 5__7.tilesPendingInjection; AddMainPathTileProxies(5__7.list.Select((TilePlacementResultProxy x) => x.tileProxy), 5__7.mainPathIndex); if (gen.ShouldSkipFrame(true)) { <>2__current = gen.GetRoomPause(); <>1__state = 2; return true; } goto IL_080b; } goto IL_0813; IL_080b: 5__21 = null; goto IL_0813; IL_0834: if (5__5 < 5__4) { 5__6 = new List(); 5__8 = 0; goto IL_0600; } 5__3 = null; 5__3 = null; goto IL_085a; IL_0510: 5__16 = null; 5__18 = null; 5__19 = null; 5__20 = null; num = 5__15 + 1; 5__15 = num; goto IL_053f; IL_0600: if (5__8 < Properties.BranchPathMultiSimulationProperties.SimulationCount) { 5__9 = new BranchPathProxy(gen, 5__3); 5__10 = 5__3; 5__11 = 5__3.Placement.Archetype.BranchingDepth.GetRandom(gen.RandomStream); 5__12 = new DungeonCollisionManager(); 5__12.Settings = gen.CollisionSettings; 5__12.Initialize(gen); <>s__13 = gen.CollisionManager.tiles.GetEnumerator(); try { while (<>s__13.MoveNext()) { 5__14 = <>s__13.Current; 5__12.AddTile(5__14); 5__14 = null; } } finally { ((IDisposable)<>s__13).Dispose(); } <>s__13 = default(List.Enumerator); 5__15 = 0; goto IL_053f; } goto IL_0620; IL_085a: num = 5__2 + 1; 5__2 = num; goto IL_086c; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__64 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private DoorwayPair <>2__current; private int <>l__initialThreadId; private DoorwayPairFinder __instance; public DoorwayPairFinder <>3____instance; private TileProxy 5__1; private TileExtenderProxy 5__2; private List 5__3; private IEnumerable 5__4; private bool 5__5; private IEnumerator <>s__6; private DoorwayProxy 5__7; private bool 5__8; private List.Enumerator <>s__9; private GameObjectChance 5__10; private TileProxy 5__11; private float 5__12; private TileExtenderProxy 5__13; private IEnumerator <>s__14; private <>c__DisplayClass64_0 <>8__15; private bool 5__16; private float 5__17; private bool 5__18; private bool 5__19; private DoorwayPairCollection 5__20; DoorwayPair IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } [DebuggerHidden] public d__64(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -5) <= 2u || num == 1) { try { if ((uint)(num - -5) <= 1u || num == 1) { try { if (num == -5 || num == 1) { try { } finally { <>m__Finally3(); } } } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } 5__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>s__6 = null; 5__7 = null; <>s__9 = default(List.Enumerator); 5__10 = null; 5__11 = null; 5__13 = null; <>s__14 = null; <>8__15 = default(<>c__DisplayClass64_0); 5__20 = default(DoorwayPairCollection); <>1__state = -2; } private bool MoveNext() { //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -5; goto IL_0508; } <>1__state = -1; 5__1 = __instance.PreviousTile; 5__2 = TileProxyPatch.GetTileExtenderProxy(5__1); 5__3 = __instance.tileOrder; if (!5__2.EntranceExitInterchangable) { 5__4 = 5__1.UnusedDoorways.Intersect(5__2.Exits); } else if (5__1.UsedDoorways.Intersect(5__2.Exits).Any()) { 5__4 = 5__1.UnusedDoorways.Intersect(5__2.Entrances); } else if (5__1.UsedDoorways.Intersect(5__2.Entrances).Any()) { 5__4 = 5__1.UnusedDoorways.Intersect(5__2.Exits); } else { 5__4 = new List(); } 5__5 = 5__4.Any(); <>s__6 = 5__1.UnusedDoorways.GetEnumerator(); <>1__state = -3; goto IL_0574; IL_0508: <>8__15 = default(<>c__DisplayClass64_0); goto IL_0515; IL_0515: while (<>s__14.MoveNext()) { <>8__15.nextDoor = <>s__14.Current; 5__16 = 5__13.OverlappingDoorways.Contains(<>8__15.nextDoor); if (5__16) { continue; } if (!5__13.EntranceExitInterchangable) { if (!g__AllowEntranceAndExitPair|64_0(5__13.Entrances, 5__13.Exits, ref <>8__15)) { continue; } } else { 5__18 = g__AllowEntranceAndExitPair|64_0(5__13.Entrances, 5__13.Exits, ref <>8__15); 5__19 = g__AllowEntranceAndExitPair|64_0(5__13.Exits, 5__13.Entrances, ref <>8__15); if (!5__18 && !5__19) { continue; } } goto IL_03fd; } <>m__Finally3(); <>s__14 = null; 5__11 = null; 5__13 = null; 5__10 = null; goto IL_0549; IL_02c7: 5__13 = TileProxyPatch.GetTileExtenderProxy(5__11); <>s__14 = 5__11.Doorways.GetEnumerator(); <>1__state = -5; goto IL_0515; IL_0549: while (<>s__9.MoveNext()) { 5__10 = <>s__9.Current; if (!5__3.Contains(5__10)) { continue; } 5__11 = __instance.GetTileTemplateDelegate.Invoke(5__10.Value); 5__12 = 5__3.Count - 5__3.IndexOf(5__10); if (__instance.IsTileAllowedPredicate != null && !__instance.IsTileAllowedPredicate.Invoke(5__1, 5__11, ref 5__12)) { continue; } goto IL_02c7; } <>m__Finally2(); <>s__9 = default(List.Enumerator); 5__7 = null; goto IL_0574; IL_0574: while (true) { if (<>s__6.MoveNext()) { 5__7 = <>s__6.Current; if (!5__7.IsDisabled) { 5__8 = 5__2.OverlappingDoorways.Contains(5__7); if (!5__8 && (!5__5 || 5__4.Contains(5__7))) { break; } } continue; } <>m__Finally1(); <>s__6 = null; return false; } <>s__9 = __instance.TileWeights.GetEnumerator(); <>1__state = -4; goto IL_0549; IL_03fd: 5__17 = 0f; if (__instance.IsValidDoorwayPairing(5__7, <>8__15.nextDoor, 5__1, 5__11, ref 5__17)) { if (__instance.IsOnMainPath) { 5__20 = new DoorwayPairCollection(5__1, 5__11, 5__7, <>8__15.nextDoor); Instance.Events.OnModifyDoorwayPairWeight.Invoke(ref 5__17, 5__20, default(EventCallbackScenario)); 5__20 = default(DoorwayPairCollection); } <>2__current = new DoorwayPair(5__1, 5__7, 5__11, <>8__15.nextDoor, 5__10.TileSet, 5__12, 5__17); <>1__state = 1; return true; } goto IL_0508; } 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__6 != null) { <>s__6.Dispose(); } } private void <>m__Finally2() { <>1__state = -3; ((IDisposable)<>s__9).Dispose(); } private void <>m__Finally3() { <>1__state = -4; if (<>s__14 != null) { <>s__14.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__64 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__64(0); } d__.__instance = <>3____instance; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static MainPathExtender currentMainPathExtender; public static TilePlacementResult lastTilePlacementResult; internal static HDRenderPipelineAsset previousHDRPAsset; internal static HDRenderPipelineAsset newHDRPAsset; private static Dictionary tileProxyMainPath = new Dictionary(); private static Dictionary tileMainPath = new Dictionary(); public static Stopwatch GenerateBranchBoostedPathsStopWatch = new Stopwatch(); public static float GenerateBranchBoostedPathsTime = 0f; public static Stopwatch GetTileResultStopwatch = new Stopwatch(); public static float GetTileResultTime = 0f; public static Stopwatch DoorwayPairStopwatch = new Stopwatch(); public static float DoorwayPairTime = 0f; public static Stopwatch CalculateWeightStopwatch = new Stopwatch(); public static float CalculateWeightTime = 0f; public static DunGenExtender Instance { get; internal set; } public static DunGenExtenderProperties Properties { get; internal set; } public static bool Active { get; internal set; } public static bool ActiveAlternative { get; internal set; } public static void SetCurrentMainPathExtender(int mainPathIndex) { currentMainPathExtender = Properties.MainPathProperties.GetMainPathDetails(mainPathIndex); } public static GraphLine GetLineAtDepth(DungeonFlow flow, float depth) { if (!Active) { return flow.GetLineAtDepth(depth); } List lines = MainPathExtender.GetLines(currentMainPathExtender, flow); return GetLineAtDepthHelper(lines, depth); } public static GraphLine GetLineAtDepthHelper(List graphLines, float normalizedDepth) { normalizedDepth = Mathf.Clamp(normalizedDepth, 0f, 1f); if (normalizedDepth == 0f) { return graphLines[0]; } if (normalizedDepth == 1f) { return graphLines[graphLines.Count - 1]; } foreach (GraphLine graphLine in graphLines) { if (normalizedDepth >= graphLine.Position && normalizedDepth < graphLine.Position + graphLine.Length) { return graphLine; } } Debug.LogError((object)("GetLineAtDepth was unable to find a line at depth " + normalizedDepth + ". This shouldn't happen.")); return null; } public static List GetNodes(DungeonFlow flow) { if (!Active) { return flow.Nodes; } return MainPathExtender.GetNodes(currentMainPathExtender, flow); } public static BranchMode GetBranchMode(DungeonFlow flow) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return flow.BranchMode; } return MainPathExtender.GetBranchMode(currentMainPathExtender, flow); } public static IntRange GetBranchCount(DungeonFlow flow) { if (!Active) { return flow.BranchCount; } return MainPathExtender.GetBranchCount(currentMainPathExtender, flow); } public static IntRange GetLength(DungeonFlow flow) { if (!Active) { return flow.Length; } return MainPathExtender.GetLength(currentMainPathExtender, flow); } public static void PrintAddTileError(DungeonGenerator gen, TileProxy previousTile, TilePlacementParameters placementParameters, IEnumerable useableTileSets, int branchId, int lineLength, float lineRatio) { string text = ((previousTile != null) ? ((Object)previousTile.Prefab).name : "NULL"); string text2 = (Object.op_Implicit((Object)(object)placementParameters.Archetype) ? ((Object)placementParameters.Archetype).name : "NULL"); string text3 = string.Join(", ", useableTileSets); List list = new List(); list.Add($"Main branch gen failed at Branch {branchId} (Length: {lineLength}, Ratio: {lineRatio})"); list.Add("Prev tile: " + text); list.Add("Archetype: " + text2); list.Add("Tilesets: " + text3); list.Add($"Reason: {lastTilePlacementResult}"); if (previousTile != null) { string text4 = string.Join(", ", previousTile.UnusedDoorways.Select((DoorwayProxy d) => ((Object)((Component)d.DoorwayComponent).gameObject).name)); string text5 = string.Join(", ", previousTile.UsedDoorways.Select((DoorwayProxy d) => ((Object)((Component)d.DoorwayComponent).gameObject).name)); list.Add("Available Doorways: " + text4); list.Add("Used Doorways: " + text5); if (API.IsDevDebugModeActive()) { Queue doorwayPairsDebug = GetDoorwayPairsDebug(gen, previousTile, useableTileSets, lineRatio, placementParameters); string text6 = string.Join(", ", from d in doorwayPairsDebug.Select((DoorwayPair t) => ((DoorwayPair)(ref t)).NextTemplate.Prefab).Distinct() select ((Object)d).name); list.Add("Next Possible Tiles: " + text6); } } list.Add(string.Empty); Plugin.logger.LogDebug((object)string.Join("\n", list)); } public static void PrintAddTileErrorQuick(DungeonGenerator gen, int lineLength) { PrintAddTileError(gen, DungeonGeneratorPatch.lastAttachTo, DungeonGeneratorPatch.lastPlacementParms, DungeonGeneratorPatch.lastUseableTileSets, 0, lineLength, DungeonGeneratorPatch.lastNormalizedDepth); } public static void RecordLastTilePlacementResult(DungeonGenerator gen, TilePlacementResult result, TileProxy attachTo) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown if (result == null) { result = (TilePlacementResult)new NoMatchingDoorwayPlacementResult(attachTo); } lastTilePlacementResult = result; } public static void ProcessGlobalPropsPerMainPath(DungeonGenerator dungeonGenerator) { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Expected O, but got Unknown //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_0630: Expected O, but got Unknown HashSet hashSet = (from x in Properties.MainPathProperties.MainPathDetails.SelectMany((MainPathExtender d) => d.LocalGroupProps) select x.ID).ToHashSet(); List detailedGlobalPropSettings = Properties.MainPathProperties.DetailedGlobalPropSettings; Dictionary> dictionary = new Dictionary>(); Dictionary dictionary2 = new Dictionary(); foreach (Tile allTile in dungeonGenerator.CurrentDungeon.AllTiles) { GlobalProp[] componentsInChildren = ((Component)allTile).GetComponentsInChildren(); foreach (GlobalProp val in componentsInChildren) { GameObjectChanceTable value2; if (hashSet.Contains(val.PropGroupID)) { if (!dictionary.TryGetValue(val.PropGroupID, out var value)) { value = new Dictionary(); dictionary.Add(val.PropGroupID, value); } int mainPathIndexFromTile = GetMainPathIndexFromTile(allTile); if (!value.TryGetValue(mainPathIndexFromTile, out value2)) { value2 = new GameObjectChanceTable(); value.Add(mainPathIndexFromTile, value2); } } else if (!dictionary2.TryGetValue(val.PropGroupID, out value2)) { value2 = new GameObjectChanceTable(); dictionary2.Add(val.PropGroupID, value2); } float num = (allTile.Placement.IsOnMainPath ? val.MainPathWeight : val.BranchPathWeight); num *= val.DepthWeightScale.Evaluate(allTile.Placement.NormalizedDepth); value2.Weights.Add(new GameObjectChance(((Component)val).gameObject, num, 0f, (TileSet)null)); } } foreach (Dictionary value6 in dictionary.Values) { foreach (GameObjectChanceTable value7 in value6.Values) { foreach (GameObjectChance weight in value7.Weights) { weight.Value.SetActive(false); } } } foreach (GameObjectChanceTable value8 in dictionary2.Values) { foreach (GameObjectChance weight2 in value8.Weights) { weight2.Value.SetActive(false); } } List list = new List(dictionary.Count + dictionary2.Count); foreach (KeyValuePair pair2 in dictionary2) { if (list.Contains(pair2.Key)) { Plugin.logger.LogWarning((object)("Dungeon Flow contains multiple entries for the global prop group ID: " + pair2.Key + ". Only the first entry will be used.")); continue; } GlobalPropSettings val2 = dungeonGenerator.DungeonFlow.GlobalProps.Where((GlobalPropSettings x) => x.ID == pair2.Key).FirstOrDefault(); DetailedGlobalPropSettings detailedGlobalPropSettings2 = detailedGlobalPropSettings.Where((DetailedGlobalPropSettings x) => x.ID == pair2.Key).FirstOrDefault(); GameObjectChanceTable val3 = new GameObjectChanceTable(); float num2 = detailedGlobalPropSettings2?.MinimumDistance ?? (-1f); bool flag = detailedGlobalPropSettings2?.GlobalCountMustBeReached ?? true; if (val2 != null) { GameObjectChanceTable value3 = pair2.Value; int random = val2.Count.GetRandom(dungeonGenerator.RandomStream); int num3 = ProcessGlobalPropID(value3, val3, random, 0, random, num2); Plugin.logger.LogDebug((object)$"Global ID: {pair2.Key} ({num3} / {random}). Min Dist: {num2}"); list.Add(pair2.Key); if (flag && num3 < random) { Plugin.logger.LogDebug((object)$"MinDistance be damned, forcing {random - num3} more to spawn"); num3 += ProcessRemainingGlobalPropIDNoMatterWhat(val3, random - num3); Plugin.logger.LogDebug((object)$"Spawned remaining props ({num3} / {random})"); } } } foreach (KeyValuePair> pair in dictionary) { int globalPropId = pair.Key; if (list.Contains(globalPropId)) { Plugin.logger.LogWarning((object)("Dungeon Flow contains multiple entries for the global prop group ID: " + pair.Key + ". Only the first entry will be used.")); continue; } GlobalPropSettings val4 = dungeonGenerator.DungeonFlow.GlobalProps.Where((GlobalPropSettings x) => x.ID == globalPropId).FirstOrDefault(); DetailedGlobalPropSettings detailedGlobalPropSettings3 = detailedGlobalPropSettings.Where((DetailedGlobalPropSettings x) => x.ID == pair.Key).FirstOrDefault(); GameObjectChanceTable val5 = new GameObjectChanceTable(); float num4 = detailedGlobalPropSettings3?.MinimumDistance ?? (-1f); bool flag2 = detailedGlobalPropSettings3?.GlobalCountMustBeReached ?? true; flag2 = true; if (val4 == null) { continue; } int num5 = 0; int random2 = val4.Count.GetRandom(dungeonGenerator.RandomStream); Dictionary value4 = pair.Value; Plugin.logger.LogDebug((object)$"Local ID: {pair.Key} (Max {random2}). Min Dist: {num4}"); List list2 = new List(); foreach (KeyValuePair item in value4) { int key = item.Key; List localGroupProps = Properties.MainPathProperties.GetMainPathDetails(key).LocalGroupProps; LocalGlobalPropSettings localGlobalPropSettings = localGroupProps.Where((LocalGlobalPropSettings x) => x.ID == globalPropId).FirstOrDefault(); if (localGlobalPropSettings == null) { Plugin.logger.LogDebug((object)$"Main Path {key}: No local ID defined, skipping"); continue; } GameObjectChanceTable value5 = item.Value; int random3 = localGlobalPropSettings.Count.GetRandom(dungeonGenerator.RandomStream); int num6 = ProcessGlobalPropID(value5, val5, random3, num5, random2, num4); num5 += num6; Plugin.logger.LogDebug((object)$"Main Path {key}: Local ({num6} / {random3}), Global ({num5} / {random2})"); if (localGlobalPropSettings.UseToReachGlobalPropLimit) { continue; } list2.Add(key); foreach (GameObjectChance weight3 in value5.Weights) { val5.Weights.Add(weight3); } } foreach (int item2 in list2) { value4.Remove(item2); } if (num5 < random2 && value4.Count > 0) { string text = string.Join(", ", value4.Keys); Plugin.logger.LogDebug((object)("Combining main paths (" + text + ") into one GameObjectChanceTable")); GameObjectChanceTable[] tables2 = value4.Select((KeyValuePair d) => d.Value).ToArray(); int num7 = ProcessRemainingGlobalPropID(tables2, val5, random2 - num5, num4); num5 += num7; Plugin.logger.LogDebug((object)$"Spawned remaining props ({num5} / {random2})"); } if (flag2 && num5 < random2) { Plugin.logger.LogDebug((object)$"MinDistance be damned, forcing {random2 - num5} more to spawn"); num5 += ProcessRemainingGlobalPropIDNoMatterWhat(val5, random2 - num5); Plugin.logger.LogDebug((object)$"Spawned remaining props ({num5} / {random2})"); } list.Add(pair.Key); } int ProcessGlobalPropID(GameObjectChanceTable table, GameObjectChanceTable reserveTable, int localMax, int globalCount, int globalMax, float minDistance) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) localMax = Mathf.Clamp(localMax, 0, table.Weights.Count); int m; for (m = 0; m < localMax && m + globalCount < globalMax; m++) { if (table.Weights.Count == 0) { return m; } GameObjectChance random5 = table.GetRandom(dungeonGenerator.RandomStream, true, 0f, (GameObject)null, true, true, false); if (random5 != null && (Object)(object)random5.Value != (Object)null) { random5.Value.SetActive(true); RemoveElementsTooClose(table, reserveTable, random5.Value.transform.position, minDistance); } } return m; } int ProcessRemainingGlobalPropID(GameObjectChanceTable[] tables, GameObjectChanceTable reserveTable, int count, float minDistance) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) count = Mathf.Clamp(count, 0, tables.Sum((GameObjectChanceTable t) => t.Weights.Count)); int j; for (j = 0; j < count; j++) { if (tables.Sum((GameObjectChanceTable t) => t.Weights.Count) == 0) { return j; } GameObject combinedRandom = GameObjectChanceTable.GetCombinedRandom(dungeonGenerator.RandomStream, true, 0f, tables); if ((Object)(object)combinedRandom != (Object)null) { combinedRandom.SetActive(true); foreach (GameObjectChanceTable table2 in tables) { RemoveElementsTooClose(table2, reserveTable, combinedRandom.transform.position, minDistance); } } } return j; } int ProcessRemainingGlobalPropIDNoMatterWhat(GameObjectChanceTable table, int count) { count = Mathf.Clamp(count, 0, table.Weights.Count); int l; for (l = 0; l < count; l++) { if (table.Weights.Count == 0) { return l; } GameObjectChance random4 = table.GetRandom(dungeonGenerator.RandomStream, true, 0f, (GameObject)null, true, true, false); if (random4 != null) { random4.Value.SetActive(true); } } return l; } static void RemoveElementsTooClose(GameObjectChanceTable table, GameObjectChanceTable reserveTable, Vector3 position, float minDistance) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (minDistance <= 0f) { return; } List list3 = new List(); foreach (GameObjectChance weight4 in table.Weights) { if (Vector3.SqrMagnitude(position - weight4.Value.transform.position) < minDistance * minDistance) { list3.Add(weight4); } } foreach (GameObjectChance item3 in list3) { table.Weights.Remove(item3); reserveTable.Weights.Add(item3); } } } public static void Activate(DungeonGenerator generator, DunGenExtender extender) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) Instance = extender; Active = true; ActiveAlternative = true; DunGenExtenderProperties dunGenExtenderProperties = extender.Properties.Copy(extender.Version); EventCallbackScenario param = new EventCallbackScenario(Object.op_Implicit((Object)(object)DunGenPlusPanel.Instance) && DunGenPlusPanel.Instance.eventCallbackValue); Instance.Events.OnModifyDunGenExtenderProperties.Invoke(dunGenExtenderProperties, param); dunGenExtenderProperties.NormalNodeArchetypesProperties.SetupProperties(generator); Properties = dunGenExtenderProperties; if (Properties.DungeonBoundsProperties.UseDungeonBounds) { generator.DebugRender = true; generator.RestrictDungeonToBounds = true; Bounds val = (generator.TilePlacementBounds = Properties.DungeonBoundsProperties.GetDungeonBounds(generator.LengthMultiplier)); Plugin.logger.LogDebug((object)$"Dungeon Bounds: {val}"); } if (Properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate) { Plugin.logger.LogDebug((object)$"Updating HDRP asset: setting max shadows request to {Properties.MiscellaneousProperties.MaxShadowsRequestCount}"); try { RenderPipelineAsset renderPipeline = QualitySettings.renderPipeline; previousHDRPAsset = (HDRenderPipelineAsset)(object)((renderPipeline is HDRenderPipelineAsset) ? renderPipeline : null); newHDRPAsset = Object.Instantiate(previousHDRPAsset); RenderPipelineSettings currentPlatformRenderPipelineSettings = newHDRPAsset.currentPlatformRenderPipelineSettings; currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots = Properties.MiscellaneousProperties.MaxShadowsRequestCount; newHDRPAsset.currentPlatformRenderPipelineSettings = currentPlatformRenderPipelineSettings; QualitySettings.renderPipeline = (RenderPipelineAsset)(object)newHDRPAsset; } catch (Exception ex) { Plugin.logger.LogError((object)"Failed to update HDRP asset"); Plugin.logger.LogError((object)ex.ToString()); } } DoorwayManager.ResetList(); DoorwayManager.onMainEntranceTeleportSpawnedEvent.ClearTemporaryActionList(); } public static void Deactivate() { Instance = null; Properties = null; Active = false; ActiveAlternative = false; if (Object.op_Implicit((Object)(object)previousHDRPAsset) && (Object)(object)QualitySettings.renderPipeline == (Object)(object)newHDRPAsset) { Plugin.logger.LogDebug((object)"Restoring original HDRP asset"); QualitySettings.renderPipeline = (RenderPipelineAsset)(object)previousHDRPAsset; previousHDRPAsset = null; newHDRPAsset = null; } } public static int GetMainPathIndexFromTileProxy(TileProxy tileProxy) { return tileProxyMainPath[tileProxy]; } public static int GetMainPathIndexFromTile(Tile tile) { if (tileMainPath.TryGetValue(tile, out var value)) { return value; } Plugin.logger.LogWarning((object)"Error with GetMainPathIndexFromTile.\nPLEASE REPORT TO MR. DEV WITH YOUR MOD PACK. THIS SHOULD NOT BE HAPPENING!"); return 0; } public static void AddTileProxy(TileProxy tileProxy, int index) { tileProxyMainPath.Add(tileProxy, index); } public static void AddMainPathTileProxies(IEnumerable tileProxies, int index) { float num = tileProxies.Last().Placement.PathDepth; foreach (TileProxy tileProxy in tileProxies) { AddTileProxy(tileProxy, index); tileProxy.Placement.NormalizedPathDepth = (float)tileProxy.Placement.PathDepth / num; } } public static void BuildBranchPathTileProxiesDictionary(DungeonProxy dungeonProxy) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) int index = 0; foreach (ProxyDoorwayConnection connection in dungeonProxy.Connections) { ProxyDoorwayConnection current = connection; TileProxy tileProxy = ((ProxyDoorwayConnection)(ref current)).A.TileProxy; if (tileProxy.Placement.IsOnMainPath) { index = GetMainPathIndexFromTileProxy(tileProxy); } TileProxy tileProxy2 = ((ProxyDoorwayConnection)(ref current)).B.TileProxy; if (!tileProxy2.Placement.IsOnMainPath) { AddTileProxy(tileProxy2, index); } } } public static void AddTileToMainPathDictionary(Dictionary dictionary) { if (!Active) { return; } foreach (KeyValuePair item in dictionary) { tileMainPath.Add(item.Value, GetMainPathIndexFromTileProxy(item.Key)); } } [IteratorStateMachine(typeof(d__41))] public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__41(0) { gen = gen }; } [IteratorStateMachine(typeof(d__42))] private static IEnumerator GenerateBranchPaths(DungeonGenerator gen, TileProxy mainRoom, string message, LogLevel logLevel) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__42(0) { gen = gen, mainRoom = mainRoom, message = message, logLevel = logLevel }; } [IteratorStateMachine(typeof(d__53))] public static IEnumerator GenerateMultiBranchPaths(DungeonGenerator gen) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__53(0) { gen = gen }; } private static TilePlacementResultProxy AddBranchTileSimulation(DungeonGenerator gen, DungeonCollisionManager collisionManager, BranchPathProxy pathProxy, TileProxy attachTo, IEnumerable useableTileSets, float normalizedDepth, TilePlacementParameters placementParams) { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) InjectedTile val = null; int index = -1; if (pathProxy.tilesPendingInjection != null && (Object)(object)placementParams.Archetype != (Object)null) { float num = (float)attachTo.Placement.PathDepth / ((float)gen.targetLength - 1f); for (int i = 0; i < pathProxy.tilesPendingInjection.Count; i++) { InjectedTile val2 = pathProxy.tilesPendingInjection[i]; if (val2.ShouldInjectTileAtPoint(false, num, normalizedDepth)) { val = val2; index = i; break; } } } IEnumerable collection = ((val == null) ? useableTileSets.SelectMany((TileSet t) => t.TileWeights.Weights) : new List(val.TileSet.TileWeights.Weights)); DoorwayPairStopwatch.Reset(); DoorwayPairStopwatch.Start(); Queue doorwayPairs = GetDoorwayPairs(gen, attachTo, collection, normalizedDepth, placementParams); DoorwayPairStopwatch.Stop(); DoorwayPairTime += (float)DoorwayPairStopwatch.Elapsed.TotalMilliseconds; TilePlacementResultProxy tilePlacementResultProxy = null; if (doorwayPairs.Count == 0) { tilePlacementResultProxy = new TilePlacementResultProxy((TilePlacementResult)new NoMatchingDoorwayPlacementResult(attachTo)); gen.tilePlacementResults.Add(tilePlacementResultProxy.result); } while (doorwayPairs.Count > 0) { DoorwayPair pair = doorwayPairs.Dequeue(); tilePlacementResultProxy = TryPlaceBranchTileSimulation(gen, collisionManager, pathProxy, pair, placementParams); if (tilePlacementResultProxy.result is SuccessPlacementResult) { break; } } if (tilePlacementResultProxy.result is SuccessPlacementResult) { if (val != null) { TileProxy tileProxy = tilePlacementResultProxy.tileProxy; tileProxy.Placement.InjectionData = val; pathProxy.injectedTiles[tileProxy] = val; pathProxy.tilesPendingInjection.RemoveAt(index); } return tilePlacementResultProxy; } return null; } private static Queue GetDoorwayPairs(DungeonGenerator gen, TileProxy attachTo, IEnumerable collection, float normalizedDepth, TilePlacementParameters placementParams) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown bool value = attachTo.PrefabTile.AllowRotation; if (gen.OverrideAllowTileRotation) { value = gen.AllowTileRotation; } DoorwayPairFinder val = new DoorwayPairFinder(); val.DungeonFlow = gen.DungeonFlow; val.RandomStream = gen.RandomStream; val.PlacementParameters = placementParams; val.GetTileTemplateDelegate = new GetTileTemplateDelegate(gen.GetTileTemplate); val.IsOnMainPath = false; val.NormalizedDepth = normalizedDepth; val.PreviousTile = attachTo; val.UpVector = gen.UpVector; val.AllowRotation = value; val.TileWeights = new List(collection); val.DungeonProxy = gen.proxyDungeon; val.IsTileAllowedPredicate = (TileMatchDelegate)delegate(TileProxy prev, TileProxy next, ref float weight) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected I4, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) bool flag = prev != null && (Object)(object)next.Prefab == (Object)(object)prev.Prefab; TileRepeatMode val2 = (TileRepeatMode)0; if (gen.OverrideRepeatMode) { val2 = gen.RepeatMode; } else if (next != null) { val2 = next.PrefabTile.RepeatMode; } TileRepeatMode val3 = val2; TileRepeatMode val4 = val3; return (int)val4 switch { 0 => true, 1 => !flag, 2 => !gen.proxyDungeon.AllTiles.Where((TileProxy x) => (Object)(object)x.Prefab == (Object)(object)next.Prefab).Any(), _ => throw new NotImplementedException($"TileRepeatMode {val2} is not implemented"), }; }; int? num = (gen.UseMaximumPairingAttempts ? new int?(gen.MaxPairingAttempts) : null); return val.GetDoorwayPairs(num); } private static TilePlacementResultProxy TryPlaceBranchTileSimulation(DungeonGenerator gen, DungeonCollisionManager collisionManager, BranchPathProxy pathProxy, DoorwayPair pair, TilePlacementParameters placementParams) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown TileProxy nextTemplate = ((DoorwayPair)(ref pair)).NextTemplate; DoorwayProxy previousDoorway = ((DoorwayPair)(ref pair)).PreviousDoorway; if (nextTemplate == null) { return new TilePlacementResultProxy((TilePlacementResult)new NullTemplatePlacementResult()); } int index = ((DoorwayPair)(ref pair)).NextTemplate.Doorways.IndexOf(((DoorwayPair)(ref pair)).NextDoorway); TileProxy val = gen.tileProxyPool.TakeObject(nextTemplate); val.Placement.IsOnMainPath = false; val.Placement.PlacementParameters = placementParams; val.Placement.TileSet = ((DoorwayPair)(ref pair)).NextTileSet; if (previousDoorway != null) { DoorwayProxy val2 = val.Doorways[index]; val.PositionBySocket(val2, previousDoorway); Bounds bounds = val.Placement.Bounds; if (gen.RestrictDungeonToBounds && !UnityUtil.Contains(gen.TilePlacementBounds, bounds)) { gen.tileProxyPool.ReturnObject(val); return new TilePlacementResultProxy((TilePlacementResult)new OutOfBoundsPlacementResult(nextTemplate)); } if (collisionManager.IsCollidingWithAnyTile(gen.UpDirection, val, previousDoorway.TileProxy)) { gen.tileProxyPool.ReturnObject(val); return new TilePlacementResultProxy((TilePlacementResult)new TileIsCollidingPlacementResult(nextTemplate)); } } if (val == null) { return new TilePlacementResultProxy((TilePlacementResult)new NullTemplatePlacementResult()); } val.Placement.PathDepth = ((DoorwayPair)(ref pair)).PreviousTile.Placement.PathDepth; val.Placement.NormalizedPathDepth = ((DoorwayPair)(ref pair)).PreviousTile.Placement.NormalizedPathDepth; val.Placement.BranchDepth = ((!((DoorwayPair)(ref pair)).PreviousTile.Placement.IsOnMainPath) ? (((DoorwayPair)(ref pair)).PreviousTile.Placement.BranchDepth + 1) : 0); collisionManager.AddTile(val); return new TilePlacementResultProxy((TilePlacementResult)new SuccessPlacementResult(), val, previousDoorway, val.Doorways[index]); } private static void MakeTileProxyConnection(DungeonGenerator gen, TilePlacementResultProxy proxy) { if (proxy.previousDoorway != null) { gen.proxyDungeon.MakeConnection(proxy.previousDoorway, proxy.nextDoorway); } gen.proxyDungeon.AddTile(proxy.tileProxy); gen.CollisionManager.AddTile(proxy.tileProxy); } private static Queue GetDoorwayPairsDebug(DungeonGenerator gen, TileProxy attachTo, IEnumerable useableTileSets, float normalizedDepth, TilePlacementParameters placementParams) { IEnumerable collection = useableTileSets.SelectMany((TileSet t) => t.TileWeights.Weights); return GetDoorwayPairs(gen, attachTo, collection, normalizedDepth, placementParams); } public static void AddAdditionalTiles(DungeonGenerator gen) { if (!Properties.AdditionalTilesProperties.UseAdditionalTiles) { return; } List list = Properties.AdditionalTilesProperties.AdditionalTileSets.ToList(); while (list.Count > 0) { AdditionalTileSetList item = list[list.Count - 1]; IOrderedEnumerable<(TileProxy, double)> orderedEnumerable = from pair in gen.proxyDungeon.AllTiles.Select(delegate(TileProxy t) { float num = item.DepthWeightScale.Evaluate(t.Placement.NormalizedDepth); float num2 = (t.Placement.IsOnMainPath ? item.MainPathWeight : item.BranchPathWeight); return (t, (double)(num * num2) * gen.RandomStream.NextDouble()); }) where pair.Item2 > 0.0 orderby pair.Item2 select pair; foreach (var item3 in orderedEnumerable) { TileProxy item2 = item3.Item1; TilePlacementData placement = item2.Placement; TilePlacementParameters placementParameters = placement.PlacementParameters; TileProxy val = gen.AddTile(item2, (IEnumerable)item.TileSets, placement.NormalizedDepth, placementParameters); if (val == null) { continue; } AddTileProxy(val, GetMainPathIndexFromTileProxy(item2)); TilePlacementData placement2 = val.Placement; TilePlacementParameters placementParameters2 = placement2.PlacementParameters; placement2.BranchDepth = placement.BranchDepth; placement2.NormalizedBranchDepth = placement.NormalizedDepth; placementParameters2.Node = placementParameters.Node; placementParameters2.Line = placementParameters.Line; Plugin.logger.LogDebug((object)("Forcefully added tile " + ((Object)val.Prefab).name)); break; } list.RemoveAt(list.Count - 1); } Plugin.logger.LogDebug((object)"Forcefully added all tiles"); } public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath) { if (!Properties.LineRandomizerProperties.UseLineRandomizer) { return; } DungeonFlow dungeonFlow = Instance.DungeonFlow; List lines = dungeonFlow.Lines; Dictionary dictionary = new Dictionary(); foreach (TileSet tileSet in Properties.LineRandomizerProperties.TileSets) { dictionary.Add(tileSet, 0); } foreach (DungeonArchetype archetype in Properties.LineRandomizerProperties.Archetypes) { List targetTileSet = (randomizeMainPath ? archetype.TileSets : archetype.BranchCapTileSets); RandomizeArchetype(gen, targetTileSet, dictionary); } } public static void RandomizeArchetype(DungeonGenerator gen, List targetTileSet, Dictionary tilesetsUsed) { IEnumerable enumerable = Properties.LineRandomizerProperties.TileSets.OrderBy((TileSet t) => (double)tilesetsUsed[t] + gen.RandomStream.NextDouble()).Take(Properties.LineRandomizerProperties.TileSetsTakeCount); int num = targetTileSet.Count - 1; using IEnumerator enumerator = enumerable.GetEnumerator(); while (enumerator.MoveNext()) { TileSet key = (targetTileSet[num] = enumerator.Current); num--; tilesetsUsed[key]++; } } public static void ModifyMainBranchNodeArchetype(TilePlacementParameters parameters, GraphNode node, RandomStream randomStream) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (Active && Properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes && (int)node.NodeType == 0) { parameters.Archetype = Properties.NormalNodeArchetypesProperties.GetRandomArchetype(node.Label, randomStream); } } public static bool AllowRetryStop(bool defaultState) { return defaultState || API.IsDevDebugModeActive(); } [IteratorStateMachine(typeof(d__64))] public static IEnumerable GetPotentialDoorwayPairsForNonFirstTileAlternate(DoorwayPairFinder __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__64(-2) { <>3____instance = __instance }; } [CompilerGenerated] internal static bool g__AllowEntranceAndExitPair|64_0(IEnumerable entrances, IEnumerable exits, ref <>c__DisplayClass64_0 P_2) { if (entrances.Any() && !entrances.Contains(P_2.nextDoor)) { return false; } if (exits.Contains(P_2.nextDoor)) { return false; } return true; } } internal static class DoorwaySistersRule { public class Data { public DoorwaySisters info; public List proxies; } public static Dictionary doorwayDictionary; public static Dictionary doorwayProxyDictionary; public static void UpdateCache(IEnumerable list) { if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) { return; } Plugin.logger.LogDebug((object)"Updating DoorwayProxy cache for DoorwaySistersRule"); doorwayDictionary = new Dictionary(); doorwayProxyDictionary = new Dictionary(); foreach (DoorwayProxy item in list) { Doorway doorwayComponent = item.DoorwayComponent; if (doorwayDictionary.TryGetValue(doorwayComponent, out var value)) { value.proxies.Add(item); doorwayProxyDictionary.Add(item, value); continue; } List list2 = new List(); list2.Add(item); Data value2 = new Data { info = ((Component)doorwayComponent).GetComponent(), proxies = list2 }; doorwayProxyDictionary.Add(item, value2); doorwayDictionary.Add(item.DoorwayComponent, value2); } } public static bool CanDoorwaysConnect(bool result, TileProxy tileA, TileProxy tileB, DoorwayProxy doorwayA, DoorwayProxy doorwayB) { if (!result) { return false; } if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) { return true; } DoorwaySisters info = doorwayProxyDictionary[doorwayA].info; DoorwaySisters info2 = doorwayProxyDictionary[doorwayB].info; if (CheckIfSisterActive(info, tileB)) { return false; } if (CheckIfSisterActive(info2, tileA)) { return false; } return true; } public static bool CheckIfSisterActive(DoorwaySisters info, TileProxy targetTile) { if ((Object)(object)info == (Object)null || info.sisters == null) { return false; } foreach (Doorway sister in info.sisters) { List proxies = doorwayDictionary[sister].proxies; foreach (DoorwayProxy item in proxies) { if (item.ConnectedDoorway != null && item.ConnectedDoorway.TileProxy == targetTile) { return true; } } } return false; } } } namespace DunGenPlus.DevTools { internal class DevDebugManager : MonoBehaviour { [Header("References")] public RuntimeDungeon dungeon; public GameObject devCamera; public BasePanel[] panels; public LayoutElement canvasLayoutElement; public TMP_Dropdown dungeonFlowSelectionDropDown; private ExtendedDungeonFlow[] dungeonFlows; internal ExtendedDungeonFlow selectedExtendedDungeonFlow; internal DungeonFlow selectedDungeonFlow; internal DungeonFlowCacheAssets selectedAssetCache; internal Dictionary cacheDictionary = new Dictionary(); public TextMeshProUGUI statusTextMesh; public TextMeshProUGUI statsTextMesh; private GameObject disabledGameObject; private RoundManager fakeRoundManager; private Camera lastMainCamera; private Vector3 lastCameraPosition; private Quaternion lastCameraRotation; private Vector2 cameraYRange; public bool canvasExtended; private bool canvasExtendedInAnimation; private float canvasWidthTarget; [Header("UI Prefabs")] [Header("UI")] public GameObject headerUIPrefab; public GameObject textUIPrefab; public GameObject spaceUIPrefab; public GameObject verticalLayoutUIPrefab; [Header("Input Fields")] public GameObject intInputFieldPrefab; public GameObject floatInputFieldPrefab; public GameObject boolInputFieldPrefab; public GameObject stringInputFieldPrefab; public GameObject vector3InputFieldPrefab; public GameObject intRangeInputFieldPrefab; public GameObject floatRangeInputFieldPrefab; public GameObject intSliderFieldPrefab; [Header("Special Fields")] public GameObject listUIPrefab; public GameObject optionsUIPrefab; public static DevDebugManager Instance { get; private set; } public static bool IsActive => (Object)(object)Instance != (Object)null; private void Awake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Instance = this; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; CacheMainCamera(); BeginDevCamera(); GetAllDungeonFlows(); BasePanel[] array = panels; foreach (BasePanel basePanel in array) { basePanel.AwakeCall(); } OpenPanel(0); UpdatePanels(); dungeon.Generator.OnGenerationStatusChanged += new GenerationStatusDelegate(OnDungeonFinished); disabledGameObject = new GameObject("Disabled GOBJ"); disabledGameObject.SetActive(false); disabledGameObject.transform.SetParent(((Component)this).transform); cameraYRange = new Vector2(devCamera.transform.position.y - 200f, devCamera.transform.position.y); canvasExtended = false; canvasWidthTarget = 440f; } private void OnDestroy() { Instance = null; MainPanel.Instance = null; DunFlowPanel.Instance = null; DunGenPlusPanel.Instance = null; AssetsPanel.Instance = null; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; EndDevCamera(); } private unsafe void Update() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) if (canvasExtendedInAnimation) { float preferredWidth = canvasLayoutElement.preferredWidth; if (Mathf.Abs(preferredWidth - canvasWidthTarget) < 4f) { canvasLayoutElement.preferredWidth = canvasWidthTarget; canvasExtendedInAnimation = false; } else { canvasLayoutElement.preferredWidth = Mathf.Lerp(preferredWidth, canvasWidthTarget, Time.deltaTime * 10f); } } TextMeshProUGUI obj = statusTextMesh; GenerationStatus status = dungeon.Generator.Status; ((TMP_Text)obj).text = ((object)(GenerationStatus)(ref status)).ToString(); if (!DevDebugOpen.IsSinglePlayerInShip()) { CloseDevDebug(); } if (Mouse.current.middleButton.isPressed) { Vector2 value = System.Runtime.CompilerServices.Unsafe.Read((void*)((InputControl)(object)((Pointer)Mouse.current).delta).value); Vector2 val = value; Transform transform = devCamera.transform; transform.position += new Vector3(0f - val.x, 0f, 0f - val.y); } float y = ((Vector2)((InputControl)(object)Mouse.current.scroll).value).y; if (y != 0f) { Vector3 position = devCamera.transform.position; position.y = Mathf.Clamp(position.y + y * -0.05f, cameraYRange.x, cameraYRange.y); devCamera.transform.position = position; } } public void OpenPanel(int index) { for (int i = 0; i < panels.Length; i++) { panels[i].SetPanelVisibility(i == index); } } public void ToggleCanvasExtended() { canvasExtendedInAnimation = true; canvasExtended = !canvasExtended; canvasWidthTarget = (canvasExtended ? 800f : 440f); } public void SelectDungeonFlow(int index) { selectedExtendedDungeonFlow = dungeonFlows[index]; selectedDungeonFlow = selectedExtendedDungeonFlow.DungeonFlow; dungeon.Generator.DungeonFlow = selectedDungeonFlow; if (!cacheDictionary.TryGetValue(selectedDungeonFlow, out var value)) { DunGenExtender dunGenExtender = API.GetDunGenExtender(selectedDungeonFlow); value = new DungeonFlowCacheAssets(selectedDungeonFlow, dunGenExtender); cacheDictionary.Add(selectedDungeonFlow, value); } selectedAssetCache = value; UpdatePanels(); Plugin.logger.LogInfo((object)("Selecting " + selectedExtendedDungeonFlow.DungeonName)); } public void GenerateDungeon() { DeleteDungeon(); Plugin.logger.LogInfo((object)$"Generating dungeon: {dungeon.Generator.IsGenerating}"); fakeRoundManager = disabledGameObject.AddComponent(); fakeRoundManager.dungeonGenerator = dungeon; selectedExtendedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); DungeonManager.GlobalDungeonEvents?.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); DunGenPlusGenerator.GenerateBranchBoostedPathsTime = 0f; DunGenPlusGenerator.GetTileResultTime = 0f; DunGenPlusGenerator.DoorwayPairTime = 0f; DunGenPlusGenerator.CalculateWeightTime = 0f; dungeon.Generate(); } public void DeleteDungeon() { Plugin.logger.LogInfo((object)"Deleting dungeon"); dungeon.Generator.Clear(true); dungeon.Generator.Cancel(); dungeon.Generator.RestrictDungeonToBounds = false; if (Object.op_Implicit((Object)(object)fakeRoundManager)) { Object.Destroy((Object)(object)fakeRoundManager); } ClearTransformChildren(dungeon.Root.transform); } public void ClearTransformChildren(Transform root) { int childCount = root.childCount; for (int num = childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)root.GetChild(num)).gameObject); } } public void CloseDevDebug() { DeleteDungeon(); Object.Destroy((Object)(object)((Component)this).gameObject); } public void OnDungeonFinished(DungeonGenerator generator, GenerationStatus status) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Invalid comparison between Unknown and I4 StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Initial seed: " + MainPanel.Instance.seedInputField.inputField.text); stringBuilder.AppendLine($"Last seed: {generator.ChosenSeed}"); if ((int)status == 8) { stringBuilder.AppendLine($"Tiles: {generator.CurrentDungeon.AllTiles.Count}"); stringBuilder.AppendLine($"Main Tiles: {generator.CurrentDungeon.MainPathTiles.Count}"); stringBuilder.AppendLine($"Branch Tiles: {generator.CurrentDungeon.BranchPathTiles.Count}"); stringBuilder.AppendLine($"Doors: {generator.CurrentDungeon.Doors.Count}"); } else if ((int)status == 9) { stringBuilder.AppendLine("Failed"); } stringBuilder.AppendLine(); GenerationStats generationStats = generator.GenerationStats; stringBuilder.AppendLine("DunGen"); stringBuilder.AppendLine($"Retrys: {generationStats.TotalRetries}"); stringBuilder.AppendLine($"Total Time: {generationStats.TotalTime:F2} ms"); stringBuilder.AppendLine(""); stringBuilder.AppendLine($"GenerateBranch Time: {DunGenPlusGenerator.GenerateBranchBoostedPathsTime:F2} ms"); stringBuilder.AppendLine($"GetTileResult Time: {DunGenPlusGenerator.GetTileResultTime:F2} ms"); stringBuilder.AppendLine($"DoorwayPair Time: {DunGenPlusGenerator.DoorwayPairTime:F2} ms"); stringBuilder.AppendLine($"CalculateWeight Time: {DunGenPlusGenerator.CalculateWeightTime:F2} ms"); ((TMP_Text)statsTextMesh).text = stringBuilder.ToString(); } public void RecordNewSeed(int seed) { MainPanel.Instance?.seedInputField.Set(seed); } private void UpdatePanels() { MainPanel.Instance?.UpdatePanel(); DunFlowPanel.Instance?.UpdatePanel(refreshPanel: true); DunGenPlusPanel.Instance?.UpdatePanel(refreshPanel: true); AssetsPanel.Instance?.UpdatePanel(refreshPanel: true); } public void UpdateDungeonBounds() { DunGenPlusPanel.Instance?.UpdateDungeonBoundsHelper(); } private void GetAllDungeonFlows() { dungeonFlows = PatchedContent.ExtendedDungeonFlows.ToArray(); dungeonFlowSelectionDropDown.options = ((IEnumerable)dungeonFlows).Select((Func)((ExtendedDungeonFlow d) => new OptionData(d.DungeonName))).ToList(); SelectDungeonFlow(0); } private void CacheMainCamera() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if (Object.op_Implicit((Object)(object)main)) { lastMainCamera = main; lastCameraPosition = ((Component)main).transform.position; lastCameraRotation = ((Component)main).transform.rotation; } } private void BeginDevCamera() { Camera obj = lastMainCamera; if (obj != null) { ((Component)obj).gameObject.SetActive(false); } devCamera.SetActive(true); } private void EndDevCamera() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) devCamera.SetActive(false); if (Object.op_Implicit((Object)(object)lastMainCamera)) { ((Component)lastMainCamera).transform.position = lastCameraPosition; ((Component)lastMainCamera).transform.rotation = lastCameraRotation; ((Component)lastMainCamera).gameObject.SetActive(true); } } public TextUIElement CreateHeaderUIField(Transform parentTransform, TitleParameter titleParameter) { GameObject val = Object.Instantiate(headerUIPrefab, parentTransform); TextUIElement component = val.GetComponent(); component.SetupBase(titleParameter); return component; } public TextUIElement CreateTextUIField(Transform parentTransform, TitleParameter titleParameter) { GameObject val = Object.Instantiate(textUIPrefab, parentTransform); TextUIElement component = val.GetComponent(); component.SetupBase(titleParameter); return component; } public void CreateSpaceUIField(Transform parentTransform) { Object.Instantiate(spaceUIPrefab, parentTransform); } public Transform CreateVerticalLayoutUIField(Transform parentTransform) { return Object.Instantiate(verticalLayoutUIPrefab, parentTransform).transform; } public IntInputField CreateIntInputField(Transform parentTransform, TitleParameter titleParameter, IntParameter intParameter, Action setAction) { GameObject val = Object.Instantiate(intInputFieldPrefab, parentTransform); IntInputField component = val.GetComponent(); component.SetupInputField(titleParameter, intParameter, setAction); return component; } public FloatInputField CreateFloatInputField(Transform parentTransform, TitleParameter titleParameter, FloatParameter floatParameter, Action setAction) { GameObject val = Object.Instantiate(floatInputFieldPrefab, parentTransform); FloatInputField component = val.GetComponent(); component.SetupInputField(titleParameter, floatParameter, setAction); return component; } public BoolInputField CreateBoolInputField(Transform parentTransform, TitleParameter titleParameter, bool baseValue, Action setAction) { GameObject val = Object.Instantiate(boolInputFieldPrefab, parentTransform); BoolInputField component = val.GetComponent(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public StringInputField CreateStringInputField(Transform parentTransform, TitleParameter titleParameter, string baseValue, Action setAction) { GameObject val = Object.Instantiate(stringInputFieldPrefab, parentTransform); StringInputField component = val.GetComponent(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public Vector3InputField CreateVector3InputField(Transform parentTransform, TitleParameter titleParameter, Vector3 baseValue, Action setAction) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(vector3InputFieldPrefab, parentTransform); Vector3InputField component = val.GetComponent(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public IntRangeInputField CreateIntRangeInputField(Transform parentTransform, TitleParameter titleParameter, IntRange baseValue, Action setAction) { GameObject val = Object.Instantiate(intRangeInputFieldPrefab, parentTransform); IntRangeInputField component = val.GetComponent(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public FloatRangeInputField CreateFloatRangeInputField(Transform parentTransform, TitleParameter titleParameter, FloatRange baseValue, Action setAction) { GameObject val = Object.Instantiate(floatRangeInputFieldPrefab, parentTransform); FloatRangeInputField component = val.GetComponent(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public IntSliderField CreateIntSliderField(Transform parentTransform, TitleParameter titleParameter, IntParameter intParameter, Action setAction) { GameObject val = Object.Instantiate(intSliderFieldPrefab, parentTransform); IntSliderField component = val.GetComponent(); component.SetupInputField(titleParameter, intParameter, setAction); return component; } public ListUIElement CreateListUIField(Transform parentTransform, TitleParameter titleParameter, List list, bool useAddRemove = true) { return CreateListSimpleUIField(parentTransform, titleParameter, list, useExtended: false, useAddRemove); } public ListUIElement CreateListExtendedUIField(Transform parentTransform, TitleParameter titleParameter, List list, bool useAddRemove = true) { return CreateListSimpleUIField(parentTransform, titleParameter, list, useExtended: true, useAddRemove); } private ListUIElement CreateListSimpleUIField(Transform parentTransform, TitleParameter titleParameter, List list, bool useExtended, bool useAddRemove) { GameObject val = Object.Instantiate(listUIPrefab, parentTransform); ListUIElement component = val.GetComponent(); component.SetupList(titleParameter, list, useExtended, useAddRemove); return component; } public DropdownInputField CreateOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction, Func convertIndex, IEnumerable options) { GameObject val = Object.Instantiate(optionsUIPrefab, parentTransform); DropdownInputField component = val.GetComponent(); component.SetupDropdown(titleParameter, baseValue, setAction, convertIndex, options); return component; } public DropdownInputField CreateLevelOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) { MainPanel mainPanel = MainPanel.Instance; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => mainPanel.levels[i], mainPanel.levelOptions); } public DropdownInputField CreateMainPathExtenderUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.mainPathExtenders.list[i].Item, assetCache.mainPathExtenders.options); } public DropdownInputField CreateTileOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.tiles.list[i].Item, assetCache.tiles.options); } public DropdownInputField CreateTileSetsOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.tileSets.list[i].Item, assetCache.tileSets.options); } public DropdownInputField CreateArchetypeOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.archetypes.list[i].Item, assetCache.archetypes.options); } public DropdownInputField CreateEnumOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action setAction) where T : Enum { string[] names = Enum.GetNames(typeof(T)); return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => (T)Enum.ToObject(typeof(T), i), names); } public DropdownInputField CreateAnimationCurveOptionsUIField(Transform parentTransform, TitleParameter titleParameter, AnimationCurve baseValue, Action setAction) { var (curves, options) = CreateAnimationCurves(baseValue); setAction(curves[0]); return CreateOptionsUIField(parentTransform, titleParameter, 0, setAction, (int i) => curves[i], options); } private (List animationCurves, List options) CreateAnimationCurves(AnimationCurve custom) { List list = new List(); List list2 = new List(); if (custom != null) { list.Add(custom); list2.Add("Custom"); } list.Add(AnimationCurve.Constant(0f, 1f, 1f)); list2.Add("Constant 1"); list.Add(AnimationCurve.Linear(0f, 0f, 1f, 1f)); list2.Add("Linear 0-1"); list.Add(AnimationCurve.Linear(1f, 1f, 0f, 0f)); list2.Add("Linear 1-0"); list.Add(AnimationCurve.EaseInOut(0f, 0f, 1f, 1f)); list2.Add("EaseInOut 0-1"); list.Add(AnimationCurve.EaseInOut(1f, 1f, 0f, 0f)); list2.Add("EaseInOut 1-0"); return (list, list2); } } internal class DevDebugOpen : MonoBehaviour { public static bool IsSinglePlayerInShip() { StartOfRound instance = StartOfRound.Instance; RoundManager instance2 = RoundManager.Instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance2)) { return instance.connectedPlayersAmount == 0 && instance.inShipPhase; } return false; } public void Update() { if (IfKeyPress(Keyboard.current.mKey, Keyboard.current.leftAltKey) && (Object)(object)DevDebugManager.Instance == (Object)null && IsSinglePlayerInShip()) { Object.Instantiate(Assets.DevDebugPrefab); } } private bool IfKeyPress(KeyControl key, KeyControl hold) { if (((ButtonControl)hold).isPressed && ((ButtonControl)key).wasPressedThisFrame) { return true; } return false; } } internal class PanelTab : MonoBehaviour { public bool active; [Header("References")] public RectTransform rectTransform; public Image image; private void Update() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) float num = (active ? 48f : 36f); Color val = (active ? new Color(20f / 51f, 20f / 51f, 20f / 51f, 1f) : new Color(10f / 51f, 10f / 51f, 10f / 51f, 1f)); Vector2 sizeDelta = rectTransform.sizeDelta; sizeDelta.y = Mathf.Lerp(sizeDelta.y, num, Time.deltaTime * 10f); rectTransform.sizeDelta = sizeDelta; Color color = ((Graphic)image).color; color = Color.Lerp(color, val, Time.deltaTime * 10f); ((Graphic)image).color = color; } } } namespace DunGenPlus.DevTools.UIElements { internal abstract class BaseInputField : BaseUIElement { public abstract void Set(T value); protected int ParseTextInt(string text, int defaultValue = 0) { if (int.TryParse(text, out var result)) { return result; } Plugin.logger.LogWarning((object)("Couldn't parse " + text + " into an int")); return defaultValue; } protected float ParseTextFloat(string text, float defaultValue = 0f) { if (float.TryParse(text, out var result)) { return result; } Plugin.logger.LogWarning((object)("Couldn't parse " + text + " into a float")); return defaultValue; } } internal abstract class BaseUIElement : MonoBehaviour { public TextMeshProUGUI titleTextMesh; internal string title; public LayoutElement layoutElement; internal float layoutOffset; internal float layoutWidthBase; public void SetupBase(TitleParameter titleParameter) { title = titleParameter.text; SetText(title); SetHoverText(titleParameter.hoverText); layoutOffset = titleParameter.offset; if (Object.op_Implicit((Object)(object)layoutElement)) { LayoutElement obj = layoutElement; obj.minWidth -= layoutOffset; layoutWidthBase = layoutElement.minWidth; } } private void Update() { if (Object.op_Implicit((Object)(object)layoutElement)) { float num = layoutWidthBase; if (DevDebugManager.Instance.canvasExtended) { num += 40f; } layoutElement.minWidth = Mathf.Lerp(layoutElement.minWidth, num, Time.deltaTime * 10f); } } public void SetText(string value) { ((TMP_Text)titleTextMesh).text = value; } public void SetHoverText(string value) { HoverUIChild componentInChildren = ((Component)this).GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.hoverText = value; } } } internal class BoolInputField : BaseInputField { public Toggle toggle; public void SetupInputField(TitleParameter titleParameter, bool baseValue, Action setAction) { SetupBase(titleParameter); ((UnityEvent)(object)toggle.onValueChanged).AddListener((UnityAction)delegate(bool t) { SetValue(setAction, t); }); Set(baseValue); } private void SetValue(Action setAction, bool state) { Plugin.logger.LogInfo((object)$"Setting {title} to {state}"); setAction(state); } public override void Set(bool state) { toggle.isOn = state; } } internal class DropdownInputField : BaseUIElement { public TMP_Dropdown dropDown; public void SetupDropdown(TitleParameter titleParameter, int baseValue, Action setAction, Func convertIndex, IEnumerable options) { SetupBase(titleParameter); int maxLength = (int)Mathf.LerpUnclamped(28f, 24f, layoutOffset / 24f); dropDown.options = options.Select((Func)((string c) => new OptionData(c.Substring(0, Math.Min(maxLength, c.Length))))).ToList(); ((UnityEvent)(object)dropDown.onValueChanged).AddListener((UnityAction)delegate(int t) { SetValue(setAction, convertIndex, t); }); dropDown.value = baseValue; } private void SetValue(Action setAction, Func convertIndex, int index) { T val = convertIndex(index); Plugin.logger.LogInfo((object)$"Setting {title} to {val}"); setAction(val); } } internal class FloatInputField : BaseInputField { public TMP_InputField inputField; internal float minValue; internal float maxValue; internal float defaultValue; public void SetupInputField(TitleParameter titleParameter, FloatParameter floatParameter, Action setAction) { SetupBase(titleParameter); minValue = floatParameter.minValue; maxValue = floatParameter.maxValue; defaultValue = floatParameter.defaultValue; ((UnityEvent)(object)inputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetValue(setAction, t); }); Set(floatParameter.baseValue); } private void SetValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + " to " + text)); float num = ParseTextFloat(text, defaultValue); setAction(Mathf.Clamp(num, minValue, maxValue)); } public override void Set(float value) { inputField.text = value.ToString(); } } internal class FloatRangeInputField : BaseInputField { public TMP_InputField minInputField; public TMP_InputField maxInputField; private FloatRange _value; public void SetupInputField(TitleParameter titleParameter, FloatRange baseValue, Action setAction) { SetupBase(titleParameter); ((UnityEvent)(object)minInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetMinValue(setAction, t); }); ((UnityEvent)(object)maxInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetMaxValue(setAction, t); }); Set(baseValue); } private void SetMinValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + ".min to " + text)); _value.Min = ParseTextFloat(text); setAction(_value); } private void SetMaxValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + ".max to " + text)); _value.Max = ParseTextFloat(text); setAction(_value); } public override void Set(FloatRange value) { _value = value; minInputField.text = value.Min.ToString(); maxInputField.text = value.Max.ToString(); } } internal class IntInputField : BaseInputField { public TMP_InputField inputField; internal int minValue; internal int maxValue; internal int defaultValue; public void SetupInputField(TitleParameter titleParameter, IntParameter intParameter, Action setAction) { SetupBase(titleParameter); minValue = intParameter.minValue; maxValue = intParameter.maxValue; defaultValue = intParameter.defaultValue; ((UnityEvent)(object)inputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetValue(setAction, t); }); Set(intParameter.baseValue); } private void SetValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + " to " + text)); int num = ParseTextInt(text, defaultValue); setAction(Mathf.Clamp(num, minValue, maxValue)); } public override void Set(int value) { inputField.text = value.ToString(); } } internal class IntRangeInputField : BaseInputField { public TMP_InputField minInputField; public TMP_InputField maxInputField; private IntRange _value; public void SetupInputField(TitleParameter titleParameter, IntRange baseValue, Action setAction) { SetupBase(titleParameter); ((UnityEvent)(object)minInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetMinValue(setAction, t); }); ((UnityEvent)(object)maxInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetMaxValue(setAction, t); }); Set(baseValue); } private void SetMinValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + ".min to " + text)); _value.Min = ParseTextInt(text); setAction(_value); } private void SetMaxValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + ".max to " + text)); _value.Max = ParseTextInt(text); setAction(_value); } public override void Set(IntRange value) { _value = value; minInputField.text = value.Min.ToString(); maxInputField.text = value.Max.ToString(); } } internal class IntSliderField : BaseInputField { public Slider inputField; public TextMeshProUGUI textMesh; public void SetupInputField(TitleParameter titleParameter, IntParameter intParameter, Action setAction) { SetupBase(titleParameter); inputField.minValue = inputField.minValue; inputField.maxValue = inputField.maxValue; ((UnityEvent)(object)inputField.onValueChanged).AddListener((UnityAction)delegate(float t) { SetValue(setAction, t); }); Set(intParameter.baseValue); } private void SetValue(Action setAction, float value) { Plugin.logger.LogInfo((object)$"Setting {title} to {value}"); setAction((int)value); ((TMP_Text)textMesh).text = value.ToString(); } public override void Set(int value) { inputField.value = value; ((TMP_Text)textMesh).text = value.ToString(); } } internal class ListUIElement : BaseUIElement { public GameObject templatePrefab; public Transform listTransform; public GameObject buttonsGameObject; internal IList list; internal Type listType; internal bool useExtended; public static readonly Dictionary typeDictionary = new Dictionary { { typeof(DungeonArchetype), new ListEntryDungeonArchetype() }, { typeof(TileSet), new ListEntryTileSet() }, { typeof(NodeArchetype), new ListEntryNodeArchetype() }, { typeof(AdditionalTileSetList), new ListEntryAdditionalTileSetList() }, { typeof(TileInjectionRule), new ListEntryTileInjectionRule() }, { typeof(GraphNode), new ListEntryGraphNode() }, { typeof(GraphLine), new ListEntryGraphLine() }, { typeof(GameObjectChance), new ListEntryGameObjectChance() }, { typeof(MainPathExtender), new ListEntryMainPathExtender() } }; public static readonly Dictionary typeExtendedDictionary = new Dictionary { { typeof(DungeonArchetype), new ListEntryDungeonArchetypeExtended() }, { typeof(TileSet), new ListEntryTileSetExtended() }, { typeof(GameObject), new ListEntryTileExtended() }, { typeof(MainPathExtender), new ListEntryMainPathExtenderExtended() } }; public void SetupList(TitleParameter titleParameter, List list, bool useExtended, bool useAddRemove) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) SetupBase(titleParameter); float num = Mathf.LerpUnclamped(0.4f, 0.6f, titleParameter.offset / 100f); ((Graphic)((Component)listTransform).GetComponent()).color = new Color(num, num, num, 1f); this.list = list; listType = typeof(T); this.useExtended = useExtended; if (!useAddRemove) { buttonsGameObject.SetActive(false); } for (int i = 0; i < list.Count; i++) { CreateEntry(i); } } public void AddElement() { object obj = null; Dictionary dictionary = (useExtended ? typeExtendedDictionary : typeDictionary); if (!dictionary.TryGetValue(listType, out var value)) { Plugin.logger.LogError((object)$"Type {listType} does not has a defined list UI display"); } obj = value.CreateEmptyObject(); list.Add(obj); CreateEntry(list.Count - 1); } public void RemoveElement() { if (list.Count != 0) { list.RemoveAt(list.Count - 1); Object.Destroy((Object)(object)((Component)listTransform.GetChild(listTransform.childCount - 1)).gameObject); } } public void CreateEntry(int index) { GameObject val = CreateCopy(index); Transform parentTransform = val.transform.Find("Items"); Dictionary dictionary = (useExtended ? typeExtendedDictionary : typeDictionary); if (!dictionary.TryGetValue(listType, out var value)) { Plugin.logger.LogError((object)$"Type {listType} does not has a defined list UI display"); } value.CreateEntry(list, index, parentTransform, layoutOffset + 24f); SetElementText(val, value, index); val.SetActive(true); } public GameObject CreateCopy(int index) { return Object.Instantiate(templatePrefab, listTransform); } public void SetElementText(GameObject elementGameObject, ListEntryType entryType, int index) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI component = ((Component)elementGameObject.transform.Find("Element")).GetComponent(); string text; if (entryType.UseCustomElementText()) { text = entryType.GetCustomElementText(list, index); ((TMP_Text)component).fontStyle = (FontStyles)(((TMP_Text)component).fontStyle | 4); } else { text = $"Element {index}"; } ((TMP_Text)component).text = text; } } internal class StringInputField : BaseInputField { public TMP_InputField inputField; public void SetupInputField(TitleParameter titleParameter, string baseValue, Action setAction) { SetupBase(titleParameter); ((UnityEvent)(object)inputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetValue(setAction, t); }); Set(baseValue); } private void SetValue(Action setAction, string text) { Plugin.logger.LogInfo((object)("Setting " + title + " to " + text)); setAction(text); } public override void Set(string value) { inputField.text = value; } } internal class TextUIElement : BaseUIElement { } internal class Vector3InputField : BaseInputField { public TMP_InputField xInputField; public TMP_InputField yInputField; public TMP_InputField zInputField; private Vector3 _value; public void SetupInputField(TitleParameter titleParameter, Vector3 baseValue, Action setAction) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) SetupBase(titleParameter); ((UnityEvent)(object)xInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetXValue(setAction, t); }); ((UnityEvent)(object)yInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetYValue(setAction, t); }); ((UnityEvent)(object)zInputField.onValueChanged).AddListener((UnityAction)delegate(string t) { SetZValue(setAction, t); }); Set(baseValue); } private void SetXValue(Action setAction, string text) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) Plugin.logger.LogInfo((object)("Setting " + title + ".x to " + text)); _value.x = ParseTextFloat(text); setAction(_value); } private void SetYValue(Action setAction, string text) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) Plugin.logger.LogInfo((object)("Setting " + title + ".y to " + text)); _value.y = ParseTextFloat(text); setAction(_value); } private void SetZValue(Action setAction, string text) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) Plugin.logger.LogInfo((object)("Setting " + title + ".z to " + text)); _value.z = ParseTextFloat(text); setAction(_value); } public override void Set(Vector3 value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _value = value; xInputField.text = value.x.ToString(); yInputField.text = value.y.ToString(); zInputField.text = value.z.ToString(); } } } namespace DunGenPlus.DevTools.UIElements.Collections { internal abstract class ListEntryType { public abstract object CreateEmptyObject(); public abstract void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset); public virtual bool UseCustomElementText() { return false; } public virtual string GetCustomElementText(IList list, int index) { return string.Empty; } } internal class ListEntryDungeonArchetype : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown DungeonArchetype val = (DungeonArchetype)list[index]; int baseValue = DevDebugManager.Instance.selectedAssetCache.archetypes.dictionary[val]; DevDebugManager.Instance.CreateArchetypeOptionsUIField(parentTransform, new TitleParameter("Archetype", layoutOffset), baseValue, delegate(DungeonArchetype t) { list[index] = t; }); } } internal class ListEntryDungeonArchetypeExtended : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected I4, but got Unknown DungeonArchetype entry = (DungeonArchetype)list[index]; DevDebugManager.Instance.CreateListUIField(parentTransform, "Tile Sets", entry.TileSets); DevDebugManager.Instance.CreateEnumOptionsUIField(parentTransform, (TitleParameter)"Branch Cap Type", (int)entry.BranchCapType, (Action)delegate(BranchCapType t) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) entry.BranchCapType = t; }); DevDebugManager.Instance.CreateListUIField(parentTransform, "Branch Cap Tile Sets", entry.BranchCapTileSets); DevDebugManager.Instance.CreateIntRangeInputField(parentTransform, "Branch Count", entry.BranchCount, delegate(IntRange t) { entry.BranchCount = t; }); DevDebugManager.Instance.CreateIntRangeInputField(parentTransform, "Branching Depth", entry.BranchingDepth, delegate(IntRange t) { entry.BranchingDepth = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Straigten Chance", new FloatParameter(entry.StraightenChance, 0f, 1f), delegate(float t) { entry.StraightenChance = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Unique", entry.Unique, delegate(bool t) { entry.Unique = t; }); DevDebugManager.Instance.CreateSpaceUIField(parentTransform); } public override bool UseCustomElementText() { return true; } public override string GetCustomElementText(IList list, int index) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown DungeonArchetype val = (DungeonArchetype)list[index]; return ((Object)val).name; } } internal class ListEntryTileSet : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown TileSet val = (TileSet)list[index]; int baseValue = DevDebugManager.Instance.selectedAssetCache.tileSets.dictionary[val]; DevDebugManager.Instance.CreateTileSetsOptionsUIField(parentTransform, new TitleParameter("Tile Set", layoutOffset), baseValue, delegate(TileSet t) { list[index] = t; }); } } internal class ListEntryTileExtended : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected I4, but got Unknown GameObject val = (GameObject)list[index]; Tile tile = val.GetComponent(); DevDebugManager.Instance.CreateEnumOptionsUIField(parentTransform, (TitleParameter)"Repeat Mode", (int)tile.RepeatMode, (Action)delegate(TileRepeatMode t) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) tile.RepeatMode = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Allow Imm. Repeats", tile.allowImmediateRepeats, delegate(bool t) { tile.allowImmediateRepeats = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Allow Rotation", tile.AllowRotation, delegate(bool t) { tile.AllowRotation = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Connection Chance", new FloatParameter(tile.ConnectionChance, 0f, 1f), delegate(float t) { tile.ConnectionChance = t; }); DevDebugManager.Instance.CreateSpaceUIField(parentTransform); } public override bool UseCustomElementText() { return true; } public override string GetCustomElementText(IList list, int index) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown GameObject val = (GameObject)list[index]; return ((Object)val).name; } } internal class ListEntryTileSetExtended : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown TileSet val = (TileSet)list[index]; List weights = val.TileWeights.Weights; DevDebugManager.Instance.CreateListUIField(parentTransform, "Weights", weights); DevDebugManager.Instance.CreateSpaceUIField(parentTransform); } public override bool UseCustomElementText() { return true; } public override string GetCustomElementText(IList list, int index) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown TileSet val = (TileSet)list[index]; return ((Object)val).name; } } internal class ListEntryGameObjectChance : ListEntryType { public override object CreateEmptyObject() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GameObjectChance val = new GameObjectChance(); val.TileSet = null; val.DepthWeightScale = null; return val; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown GameObjectChance entry = (GameObjectChance)list[index]; DevDebugManager.Instance.CreateTileOptionsUIField(parentTransform, "Tile", DevDebugManager.Instance.selectedAssetCache.tiles.dictionary[entry.Value], delegate(GameObject t) { entry.Value = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Main Path Weight", entry.MainPathWeight, delegate(float t) { entry.MainPathWeight = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Branch Path Weight", entry.BranchPathWeight, delegate(float t) { entry.BranchPathWeight = t; }); DevDebugManager.Instance.CreateAnimationCurveOptionsUIField(parentTransform, "Depth Weight Scale", entry.DepthWeightScale, delegate(AnimationCurve t) { entry.DepthWeightScale = t; }); } } internal class ListEntryMainPathExtender : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { MainPathExtender mainPathExtender = (MainPathExtender)list[index]; int baseValue = DevDebugManager.Instance.selectedAssetCache.mainPathExtenders.dictionary[mainPathExtender]; DevDebugManager.Instance.CreateMainPathExtenderUIField(parentTransform, new TitleParameter("Main Path Extender", layoutOffset), baseValue, delegate(MainPathExtender t) { list[index] = t; }); } } internal class ListEntryMainPathExtenderExtended : ListEntryType { public override object CreateEmptyObject() { return null; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected I4, but got Unknown MainPathExtender entry = (MainPathExtender)list[index]; Transform parentTransform2 = CreateOverrideTransform(entry.BranchMode, "Branch Mode Override"); DevDebugManager.Instance.CreateEnumOptionsUIField(parentTransform2, new TitleParameter("Branch Mode", layoutOffset), (int)entry.BranchMode.Value, (Action)delegate(BranchMode t) { //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) entry.BranchMode.Value = t; }); Transform parentTransform3 = CreateOverrideTransform(entry.BranchCount, "Branch Count Override"); DevDebugManager.Instance.CreateIntRangeInputField(parentTransform3, new TitleParameter("Branch Code", layoutOffset), entry.BranchCount.Value, delegate(IntRange t) { entry.BranchCount.Value = t; }); Transform parentTransform4 = CreateOverrideTransform(entry.Length, "Length Override"); DevDebugManager.Instance.CreateIntRangeInputField(parentTransform4, new TitleParameter("Length", layoutOffset), entry.Length.Value, delegate(IntRange t) { entry.Length.Value = t; }); Transform parentTransform5 = CreateOverrideTransform>(entry.Nodes, "Nodes Override"); DevDebugManager.Instance.CreateListUIField(parentTransform5, new TitleParameter("Nodes", layoutOffset), entry.Nodes.Value); Transform parentTransform6 = CreateOverrideTransform>(entry.Lines, "Lines Override"); DevDebugManager.Instance.CreateListUIField(parentTransform6, new TitleParameter("Lines", layoutOffset), entry.Lines.Value); Transform CreateOverrideTransform(PropertyOverride property, string title) { Transform transform = DevDebugManager.Instance.CreateVerticalLayoutUIField(parentTransform); DevDebugManager.Instance.CreateBoolInputField(parentTransform, new TitleParameter(title, layoutOffset), property.Override, delegate(bool t) { property.Override = t; ((Component)transform).gameObject.SetActive(t); }); transform.SetAsLastSibling(); return transform; } } public override bool UseCustomElementText() { return true; } public override string GetCustomElementText(IList list, int index) { MainPathExtender mainPathExtender = (MainPathExtender)list[index]; return ((Object)mainPathExtender).name; } } internal class ListEntryNodeArchetype : ListEntryType { public override object CreateEmptyObject() { return new NodeArchetype(); } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { NodeArchetype entry = (NodeArchetype)list[index]; DevDebugManager.Instance.CreateStringInputField(parentTransform, new TitleParameter("Label", "The normal node with this label will gain a randomly chosen archetype.\n\nIf empty, this becomes the default choice for any normal node without a NodeArchetype specified in this list.", layoutOffset), entry.Label, delegate(string t) { entry.Label = t; }); DevDebugManager.Instance.CreateListUIField(parentTransform, new TitleParameter("Archetypes", "The list of archetypes. One will be randomly chosen.", layoutOffset), entry.Archetypes); } } internal class ListEntryAdditionalTileSetList : ListEntryType { public override object CreateEmptyObject() { AdditionalTileSetList additionalTileSetList = new AdditionalTileSetList(); additionalTileSetList.DepthWeightScale = null; return additionalTileSetList; } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { AdditionalTileSetList entry = (AdditionalTileSetList)list[index]; DevDebugManager.Instance.CreateFloatInputField(parentTransform, new TitleParameter("Main Path Weight", "The weight for the tile spawning on the main path.", layoutOffset), entry.MainPathWeight, delegate(float t) { entry.MainPathWeight = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, new TitleParameter("Branch Path Weight", "The weight for the tile spawning on the branch path.", layoutOffset), entry.BranchPathWeight, delegate(float t) { entry.BranchPathWeight = t; }); DevDebugManager.Instance.CreateAnimationCurveOptionsUIField(parentTransform, new TitleParameter("Depth Weight Scale", "The weight based on the path's depth.", layoutOffset), entry.DepthWeightScale, delegate(AnimationCurve t) { entry.DepthWeightScale = t; }); DevDebugManager.Instance.CreateListUIField(parentTransform, new TitleParameter("Tile Sets", "List of tiles to be generated.", layoutOffset), entry.TileSets); } } internal class ListEntryTileInjectionRule : ListEntryType { public override object CreateEmptyObject() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown return (object)new TileInjectionRule(); } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown TileInjectionRule entry = (TileInjectionRule)list[index]; int baseValue = DevDebugManager.Instance.selectedAssetCache.tileSets.dictionary[entry.TileSet]; DevDebugManager.Instance.CreateTileSetsOptionsUIField(parentTransform, "Tile Set", baseValue, delegate(TileSet t) { entry.TileSet = t; }); DevDebugManager.Instance.CreateFloatRangeInputField(parentTransform, "Norm. Path Depth", entry.NormalizedPathDepth, delegate(FloatRange t) { entry.NormalizedPathDepth = t; }); DevDebugManager.Instance.CreateFloatRangeInputField(parentTransform, "Norm. Branch Depth", entry.NormalizedBranchDepth, delegate(FloatRange t) { entry.NormalizedBranchDepth = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Appear On Main Path", entry.CanAppearOnMainPath, delegate(bool t) { entry.CanAppearOnMainPath = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Appear On Branch Path", entry.CanAppearOnBranchPath, delegate(bool t) { entry.CanAppearOnBranchPath = t; }); DevDebugManager.Instance.CreateBoolInputField(parentTransform, "Is Required", entry.IsRequired, delegate(bool t) { entry.IsRequired = t; }); } } internal class ListEntryGraphNode : ListEntryType { public override object CreateEmptyObject() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return (object)new GraphNode(DevDebugManager.Instance.selectedDungeonFlow); } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected I4, but got Unknown GraphNode entry = (GraphNode)list[index]; DevDebugManager.Instance.CreateListUIField(parentTransform, "Tile Sets", entry.TileSets); DevDebugManager.Instance.CreateEnumOptionsUIField(parentTransform, (TitleParameter)"Node Type", (int)entry.NodeType, (Action)delegate(NodeType t) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) entry.NodeType = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Position", new FloatParameter(entry.Position, 0f, 1f), delegate(float t) { entry.Position = t; }); DevDebugManager.Instance.CreateStringInputField(parentTransform, "Label", entry.Label, delegate(string t) { entry.Label = t; }); } } internal class ListEntryGraphLine : ListEntryType { public override object CreateEmptyObject() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return (object)new GraphLine(DevDebugManager.Instance.selectedDungeonFlow); } public override void CreateEntry(IList list, int index, Transform parentTransform, float layoutOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown GraphLine entry = (GraphLine)list[index]; DevDebugManager.Instance.CreateListUIField(parentTransform, "Dungeon Archetypes", entry.DungeonArchetypes); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Position", new FloatParameter(entry.Position, 0f, 1f), delegate(float t) { entry.Position = t; }); DevDebugManager.Instance.CreateFloatInputField(parentTransform, "Length", new FloatParameter(entry.Length, 0f, 1f), delegate(float t) { entry.Length = t; }); } } internal struct TitleParameter { public string text; public float offset; public string hoverText; public TitleParameter(string text, float offset = 0f) { this.text = text; this.offset = offset; hoverText = null; } public TitleParameter(string text, string hoverText, float offset = 0f) { this.text = text; this.offset = offset; this.hoverText = hoverText; } public static implicit operator TitleParameter(string text) { return new TitleParameter(text); } public static implicit operator TitleParameter((string text, string hoverText) pair) { return new TitleParameter(pair.text, pair.hoverText); } } internal struct IntParameter { public int baseValue; public int minValue; public int maxValue; public int defaultValue; public IntParameter(int baseValue, int defaultValue = 0) { this.baseValue = baseValue; minValue = int.MinValue; maxValue = int.MaxValue; this.defaultValue = defaultValue; } public IntParameter(int baseValue, int minValue, int maxValue, int defaultValue = 0) { this.baseValue = baseValue; this.minValue = minValue; this.maxValue = maxValue; this.defaultValue = defaultValue; } public static implicit operator IntParameter(int baseValue) { return new IntParameter(baseValue); } } internal struct FloatParameter { public float baseValue; public float minValue; public float maxValue; public float defaultValue; public FloatParameter(float baseValue, float defaultValue = 0f) { this.baseValue = baseValue; minValue = -2.1474836E+09f; maxValue = 2.1474836E+09f; this.defaultValue = defaultValue; } public FloatParameter(float baseValue, float minValue, float maxValue, float defaultValue = 0f) { this.baseValue = baseValue; this.minValue = minValue; this.maxValue = maxValue; this.defaultValue = defaultValue; } public static implicit operator FloatParameter(float baseValue) { return new FloatParameter(baseValue); } } } namespace DunGenPlus.DevTools.HoverUI { internal class HoverUIChild : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public enum DisplayDirection { Up, Down, Left, Right } [Header("Display Values")] public DisplayDirection direction = DisplayDirection.Up; public float directionDistance = 16f; public RectTransform rectTransform; public bool hovering; [Header("Display")] [TextArea(2, 4)] public string hoverText; public string GetHoverString => hoverText; private void Reset() { rectTransform = ((Component)this).GetComponent(); } public void OnPointerEnter(PointerEventData eventData) { HoverUIManager.Instance.UpdateDisplay(this); hovering = true; } public void OnPointerExit(PointerEventData eventData) { HoverUIManager.Instance.ClearDisplay(this); hovering = false; } private void OnDisable() { HoverUIManager.Instance.ClearDisplay(this); hovering = false; } public (Vector2 pivot, Vector3 position) GetRenderPosition() { return GetRenderPosition(direction, directionDistance); } public (Vector2 pivot, Vector3 position) GetRenderPosition(DisplayDirection direction, float directionDistance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; rectTransform.GetWorldCorners(array); Vector2 zero = default(Vector2); Vector3 item; switch (direction) { case DisplayDirection.Up: ((Vector2)(ref zero))..ctor(0.5f, 0f); item = (array[1] + array[2]) * 0.5f + new Vector3(0f, directionDistance); break; case DisplayDirection.Down: ((Vector2)(ref zero))..ctor(0.5f, 1f); item = (array[0] + array[3]) * 0.5f - new Vector3(0f, directionDistance); break; case DisplayDirection.Left: ((Vector2)(ref zero))..ctor(1f, 0.5f); item = (array[0] + array[1]) * 0.5f - new Vector3(directionDistance, 0f); break; case DisplayDirection.Right: ((Vector2)(ref zero))..ctor(0f, 0.5f); item = (array[2] + array[3]) * 0.5f + new Vector3(directionDistance, 0f); break; default: zero = Vector2.zero; item = Vector3.zero; break; } return (zero, item); } } internal class HoverUIManager : MonoBehaviour { [Header("References/Default UI")] public RectTransform mainCanvasRectTransform; public Canvas canvas; public RectTransform background; public RectTransform textMeshRectTransform; public TextMeshProUGUI textMesh; public Vector2 preferredTextMeshSize = new Vector2(600f, 50f); [Header("Debug")] public HoverUIChild previousChild; public static HoverUIManager Instance { get; private set; } private void Awake() { Instance = this; } public void UpdateDisplay(HoverUIChild child) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) string getHoverString = child.GetHoverString; if (!string.IsNullOrWhiteSpace(getHoverString)) { previousChild = child; ((Behaviour)canvas).enabled = true; ((TMP_Text)textMesh).text = getHoverString; textMeshRectTransform.sizeDelta = preferredTextMeshSize; ((TMP_Text)textMesh).ForceMeshUpdate(false, false); Vector2 renderedValues = ((TMP_Text)textMesh).GetRenderedValues(); Vector4 margin = ((TMP_Text)textMesh).margin; Vector2 sizeDelta = renderedValues + new Vector2(margin.x + margin.z, margin.y + margin.w); (Vector2, Vector2) positionAndPivot = GetPositionAndPivot(sizeDelta); background.pivot = positionAndPivot.Item2; ((Transform)background).position = Vector2.op_Implicit(positionAndPivot.Item1); background.sizeDelta = sizeDelta; textMeshRectTransform.sizeDelta = sizeDelta; ((TMP_Text)textMesh).ForceMeshUpdate(false, false); } } public (Vector2 position, Vector2 pivot) GetPositionAndPivot(Vector2 sizeDelta) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)previousChild == (Object)null) { return (Vector2.zero, Vector2.zero); } return GetPositionAndPivot(sizeDelta, previousChild.GetRenderPosition()); } public (Vector2 position, Vector2 pivot) GetPositionAndPivot(Vector2 sizeDelta, (Vector2 pivot, Vector3 position) referencePos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Vector2 val = sizeDelta * ((Transform)mainCanvasRectTransform).localScale.x; Vector3 item = referencePos.position; Vector2 item2 = referencePos.pivot; Vector3[] array = (Vector3[])(object)new Vector3[4]; mainCanvasRectTransform.GetWorldCorners(array); float x = array[0].x; float y = array[0].y; float x2 = array[2].x; float y2 = array[2].y; item.x = Mathf.Clamp(item.x, x + val.x * item2.x, x2 - val.x * (1f - item2.x)); item.y = Mathf.Clamp(item.y, y + val.y * item2.y, y2 - val.y * (1f - item2.y)); return (Vector2.op_Implicit(item), item2); } public void RefreshDisplay() { if (Object.op_Implicit((Object)(object)previousChild)) { UpdateDisplay(previousChild); } } public void ClearDisplay(HoverUIChild child) { if (!((Object)(object)previousChild != (Object)(object)child)) { previousChild = null; ((Behaviour)canvas).enabled = false; } } } } namespace DunGenPlus.DevTools.Panels { internal class AssetsPanel : BasePanel { public static AssetsPanel Instance { get; internal set; } public override void AwakeCall() { Instance = this; } public override void SetPanelVisibility(bool visible) { base.SetPanelVisibility(visible); if (visible) { UpdatePanel(refreshPanel: false); } } public void UpdatePanel(bool refreshPanel) { if (refreshPanel) { ClearPanel(); SetupPanel(); } } public void SetupPanel() { Transform transform = mainGameObject.transform; base.manager.CreateListExtendedUIField(transform, "Archetypes", (from t in base.selectedAssetCache.archetypes.list select t.Item into t where (Object)(object)t != (Object)null select t).ToList(), useAddRemove: false); base.manager.CreateSpaceUIField(transform); base.manager.CreateListExtendedUIField(transform, "Tilesets", (from t in base.selectedAssetCache.tileSets.list select t.Item into t where (Object)(object)t != (Object)null select t).ToList(), useAddRemove: false); base.manager.CreateSpaceUIField(transform); base.manager.CreateListExtendedUIField(transform, "Tiles", (from t in base.selectedAssetCache.tiles.list select t.Item into t where (Object)(object)t != (Object)null select t).ToList(), useAddRemove: false); base.manager.CreateSpaceUIField(transform); base.manager.CreateListExtendedUIField(transform, "Main Paths", (from t in base.selectedAssetCache.mainPathExtenders.list select t.Item into t where (Object)(object)t != (Object)null select t).ToList(), useAddRemove: false); } public void ClearPanel() { base.manager.ClearTransformChildren(mainGameObject.transform); } } internal abstract class BasePanel : MonoBehaviour { [Header("Renders")] public GameObject mainGameObject; public PanelTab tab; public DevDebugManager manager => DevDebugManager.Instance; protected RuntimeDungeon dungeon => manager.dungeon; protected ExtendedDungeonFlow selectedExtendedDungeonFlow => manager.selectedExtendedDungeonFlow; protected DungeonFlow selectedDungeonFlow => manager.selectedDungeonFlow; protected DungeonFlowCacheAssets selectedAssetCache => manager.selectedAssetCache; public virtual void AwakeCall() { } public virtual void SetPanelVisibility(bool visible) { mainGameObject.SetActive(visible); tab.active = visible; } protected int ParseTextInt(string text, int defaultValue = 0) { if (int.TryParse(text, out var result)) { return result; } Plugin.logger.LogWarning((object)("Couldn't parse " + text + " into an int")); return defaultValue; } protected float ParseTextFloat(string text, float defaultValue = 0f) { if (float.TryParse(text, out var result)) { return result; } Plugin.logger.LogWarning((object)("Couldn't parse " + text + " into a float")); return defaultValue; } } internal class DunFlowPanel : BasePanel { private GameObject branchPathParentGameobject; public static DunFlowPanel Instance { get; internal set; } public override void AwakeCall() { Instance = this; } public override void SetPanelVisibility(bool visible) { base.SetPanelVisibility(visible); if (visible) { UpdatePanel(refreshPanel: false); } } public void UpdatePanel(bool refreshPanel) { if (refreshPanel) { ClearPanel(); SetupPanel(); } } public void SetupPanel() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected I4, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Invalid comparison between Unknown and I4 Transform transform = mainGameObject.transform; Transform val = base.manager.CreateVerticalLayoutUIField(transform); branchPathParentGameobject = ((Component)val).gameObject; base.manager.CreateHeaderUIField(transform, "Paths"); base.manager.CreateIntRangeInputField(transform, "Main Path Length", base.selectedDungeonFlow.Length, SetLength); base.manager.CreateEnumOptionsUIField(transform, (TitleParameter)"Branch Mode", (int)base.selectedDungeonFlow.BranchMode, (Action)SetBranchMode); base.manager.CreateIntRangeInputField(val, "Branch Path Count", base.selectedDungeonFlow.BranchCount, SetBranchCount); val.SetAsLastSibling(); base.manager.CreateSpaceUIField(transform); base.manager.CreateHeaderUIField(transform, "Generation"); base.manager.CreateListUIField(transform, "Tile Injection Rules", base.selectedDungeonFlow.TileInjectionRules); base.manager.CreateSpaceUIField(transform); base.manager.CreateListUIField(transform, "Nodes", base.selectedDungeonFlow.Nodes); base.manager.CreateSpaceUIField(transform); base.manager.CreateListUIField(transform, "Lines", base.selectedDungeonFlow.Lines); base.manager.CreateSpaceUIField(transform); branchPathParentGameobject.SetActive((int)base.selectedDungeonFlow.BranchMode == 1); } public void ClearPanel() { base.manager.ClearTransformChildren(mainGameObject.transform); } public void SetLength(IntRange value) { base.selectedDungeonFlow.Length = value; } public void SetBranchMode(BranchMode value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 base.selectedDungeonFlow.BranchMode = value; branchPathParentGameobject.SetActive((int)value == 1); } public void SetBranchCount(IntRange value) { base.selectedDungeonFlow.BranchCount = value; } } internal class DunGenPlusPanel : BasePanel { internal DunGenExtender selectedExtenderer; [Header("Panel References")] public GameObject createGameObject; public GameObject selectedGameObject; public GameObject selectedListGameObject; [Header("Dungeon Bounds Helper")] public GameObject dungeonBoundsHelperGameObject; private GameObject mainPathParentGameobject; private GameObject dungeonBoundsParentGameobject; private GameObject archetypesNodesParentGameobject; private GameObject forcedTilesParentGameobject; private GameObject branchLoopBoostParentGameobject; private GameObject maxShadowsParentGameobject; public bool eventCallbackValue = true; internal const string ActivateDunGenPlusTooltip = "If disabled, the dungeon generation will ignore this DunGenPlusExtender asset and simply create a vanilla dungeon instead when generating."; internal const string EventCallbackScenarioTooltip = "Sets the EventCallbackScenario.IsDevDebug value"; public static DunGenPlusPanel Instance { get; internal set; } public override void AwakeCall() { Instance = this; dungeonBoundsHelperGameObject.SetActive(false); } public override void SetPanelVisibility(bool visible) { base.SetPanelVisibility(visible); if (visible) { UpdatePanel(refreshPanel: false); } } public void CreateDunGenPlusExtenderer() { DunGenExtender dunGenExtender = API.CreateDunGenExtender(base.selectedDungeonFlow); base.selectedDungeonFlow.TileInjectionRules = new List(); API.AddDunGenExtender(dunGenExtender); UpdatePanel(refreshPanel: true); } public void UpdatePanel(bool refreshPanel) { bool flag = API.ContainsDungeonFlow(base.selectedDungeonFlow); selectedGameObject.SetActive(flag); createGameObject.SetActive(!flag); if (refreshPanel) { ClearPanel(); if (flag) { SetupPanel(); return; } selectedExtenderer = null; dungeonBoundsHelperGameObject.SetActive(false); } } public void SetupPanel() { //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) selectedExtenderer = API.GetDunGenExtender(base.selectedDungeonFlow); Transform transform = selectedListGameObject.transform; DunGenExtenderProperties properties = selectedExtenderer.Properties; base.manager.CreateBoolInputField(transform, ("Activate DunGenPlus", "If disabled, the dungeon generation will ignore this DunGenPlusExtender asset and simply create a vanilla dungeon instead when generating."), selectedExtenderer.Active, SetActivateDunGenPlus); base.manager.CreateBoolInputField(transform, ("EventCallbackScenario state", "Sets the EventCallbackScenario.IsDevDebug value"), eventCallbackValue, SetDebugCallbackState); base.manager.CreateSpaceUIField(transform); Transform val = base.manager.CreateVerticalLayoutUIField(transform); mainPathParentGameobject = ((Component)val).gameObject; base.manager.CreateHeaderUIField(transform, "Main Path"); base.manager.CreateIntSliderField(transform, ("Main Path Count", "The number of main paths.\n\n1 means no additional main paths\n3 means two additional main paths\netc."), new IntParameter(properties.MainPathProperties.MainPathCount, 1, 10), SetMainPathCount); val.SetAsLastSibling(); base.manager.CreateTileOptionsUIField(val, ("Main Room Tile Prefab", "The Tile prefab where the additional main paths will start from.\n\nCannot be null if MainPathCount is more than 1."), base.selectedAssetCache.tiles.dictionary[properties.MainPathProperties.MainRoomTilePrefab], SetMainRoom); base.manager.CreateEnumOptionsUIField(val, ("Copy Node Behaviour", "Defines how the nodes list is copied onto the additional main paths.\n\nCopyFromMainPathPosition: nodes will copy based on the MainRoomTilePrefab's position in the main path.\nCopyFromNodeList: nodes will copy based on the MainRoomTilePrefab's position in the node list + 1."), (int)properties.MainPathProperties.CopyNodeBehaviour, SetCopyNodeBehaviour); base.manager.CreateListUIField(val, ("Main Path Details", "Overrides certain DungeonFlow values during the main path generation.\n\nThe order of items in this list correspond to the order of the main paths being generated.\nThe first item in this list will activate for the first main path, the second item for the second main path, and so on. If there are more main paths than items in this list, the last item is used instead."), properties.MainPathProperties.MainPathDetails); base.manager.CreateSpaceUIField(transform); Transform val2 = base.manager.CreateVerticalLayoutUIField(transform); dungeonBoundsParentGameobject = ((Component)val2).gameObject; base.manager.CreateHeaderUIField(transform, "Dungeon Bounds"); base.manager.CreateBoolInputField(transform, ("Use Dungeon Bounds", "If enabled, restricts the dungeon's generation to the bounds described below.\n\nThis will help in condensing the dungeon, but it will increase the chance of dungeon generation failure (potentially guarantees failure if the bounds is too small)."), properties.DungeonBoundsProperties.UseDungeonBounds, SetUseDungeonBounds); val2.SetAsLastSibling(); base.manager.CreateVector3InputField(val2, ("Size Base", "The base size of the bounds."), properties.DungeonBoundsProperties.SizeBase, SetDungeonBoundsSizeBase); base.manager.CreateVector3InputField(val2, ("Size Factor", "The factor that's multiplied with the base size AND the dungeon's size. The resulting value is added to the base size of the bounds.\n\n0 means that the bound size is not influenced by the dungeon's size and is therefore a constant."), properties.DungeonBoundsProperties.SizeFactor, SetDungeonBoundsSizeFactor); base.manager.CreateVector3InputField(val2, ("Position Offset", "The base positional offset of the bounds."), properties.DungeonBoundsProperties.PositionOffset, SetDungeonBoundsPosOffset); base.manager.CreateVector3InputField(val2, ("Position Pivot", "The pivot of the bounds."), properties.DungeonBoundsProperties.PositionPivot, SetDungeonBoundsPosPivot); base.manager.CreateSpaceUIField(transform); Transform val3 = base.manager.CreateVerticalLayoutUIField(transform); archetypesNodesParentGameobject = ((Component)val3).gameObject; base.manager.CreateHeaderUIField(transform, "Archetypes Normal Nodes"); base.manager.CreateBoolInputField(transform, ("Add Archetypes", "If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths."), properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes, SetAddArchetypes); val3.SetAsLastSibling(); base.manager.CreateListUIField(val3, "Normal Node Archetypes", properties.NormalNodeArchetypesProperties.NormalNodeArchetypes); base.manager.CreateSpaceUIField(transform); Transform val4 = base.manager.CreateVerticalLayoutUIField(transform); forcedTilesParentGameobject = ((Component)val4).gameObject; base.manager.CreateHeaderUIField(transform, "Additional Tiles"); base.manager.CreateBoolInputField(transform, ("Use Additional Tiles", "If enabled, attempts to generate additional tiles from AdditionalTileSets after main and branching paths are generated."), properties.AdditionalTilesProperties.UseAdditionalTiles, SetUseForcedTiles); val4.SetAsLastSibling(); base.manager.CreateListUIField(val4, ("Additional Tile Sets", "The list of tiles that will be attempted to generate. Each entry will spawn only one tile from it's list.\n\nEven if the tile cannot be generated, the dungeon generation will not restart."), properties.AdditionalTilesProperties.AdditionalTileSets); base.manager.CreateSpaceUIField(transform); Transform val5 = base.manager.CreateVerticalLayoutUIField(transform); branchLoopBoostParentGameobject = ((Component)val5).gameObject; base.manager.CreateHeaderUIField(transform, "Branch Path Multi Sim"); base.manager.CreateBoolInputField(transform, ("Use Branch Path Multi Sim", "If enabled, dungeon generation will simulate a number of paths for each branch path, then choose the path based on the highest weight and generate it. The weight is decided by the following criteria below.\n\nCan slow down Branch Path Generation Times by a second or two."), properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim, SetUseBranchPathMultiSim); val5.SetAsLastSibling(); base.manager.CreateIntInputField(val5, ("Simulation Count", "The number of simulations per branch path.\n\nIncreasing this value can increase your chances of finding your desired path, but will increase Branch Path Times and vice versa."), new IntParameter(properties.BranchPathMultiSimulationProperties.SimulationCount, 1, 10, 1), SetSimulationCount); base.manager.CreateFloatInputField(val5, ("Length Weight Scale", "The weight scale for the branch path's length. The length of the branch path is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize very long branch paths."), new FloatParameter(properties.BranchPathMultiSimulationProperties.LengthWeightScale, 0f, 2f), SetLengthScale); base.manager.CreateFloatInputField(val5, ("Norm. Length Weight Scale", "The weight scale for the branch path's normalized length. The normalized length (0 -> 1) of the branch path (PathLength / MaxPathLength) is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who meet their maximum path length."), new FloatParameter(properties.BranchPathMultiSimulationProperties.NormalizedLengthWeightScale, 0f, 2f), SetNormalizedLengthScale); base.manager.CreateSpaceUIField(val5); base.manager.CreateTextUIField(val5, ("Same Path Connect", "Weight scale for branch paths that start from a main path and connect later to the same main path.")); base.manager.CreateFloatInputField(val5, ("Base Weight Scale", "The weight scale for the branch path's number of connections to the same main path. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops in their main path in general."), new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathBaseWeightScale, 0f, 2f), SamePathBaseConnectScale); base.manager.CreateFloatInputField(val5, ("Depth Weight Scale", "The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to their main paths."), new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathDepthWeightScale, 0f, 2f), SamePathConnectDepthScale); base.manager.CreateFloatInputField(val5, ("Norm. Depth Weight Scale", "The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to their main paths."), new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathNormalizedDepthWeightScale, 0f, 2f), SamePathConnectNormalizedDepthScale); base.manager.CreateSpaceUIField(val5); base.manager.CreateTextUIField(val5, ("Diff Path Connect", "Weight scale for branch paths that start from a main path and connect later to a different main path.")); base.manager.CreateFloatInputField(val5, ("Base Weight Scale", "The weight scale for the branch path's number of connections to other main paths. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops to other main paths in general."), new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathBaseWeightScale, 0f, 2f), DiffPathBaseConnectScale); base.manager.CreateFloatInputField(val5, ("Depth Weight Scale", "The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to other main paths."), new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathDepthWeightScale, 0f, 2f), DiffPathConnectDepthScale); base.manager.CreateFloatInputField(val5, ("Norm. Depth Weight Scale", "The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to other main paths."), new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathNormalizedDepthWeightScale, 0f, 2f), DiffPathConnectNormalizedDepthScale); base.manager.CreateSpaceUIField(val5); base.manager.CreateHeaderUIField(transform, "Miscellaneous"); Transform val6 = base.manager.CreateVerticalLayoutUIField(transform); maxShadowsParentGameobject = ((Component)val6).gameObject; base.manager.CreateBoolInputField(transform, ("Use Max Shadows Request", "If enabled, updates the MaxShadowsRequest to MaxShadowsRequestAmount when your dungeon loads.\n\nThis is designed for the scenario where your dungeon, for whatever reason, has too many lights nearby and causes the annoying 'Max shadow requests count reached' warning to spam the logs."), properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate, SetUseMaxShadows); base.manager.CreateIntInputField(val6, ("Shadows Request Amount", "The amount of MaxShadowsRequest.\n\n4 is the game's default value. I find 8 to be more than acceptable."), new IntParameter(properties.MiscellaneousProperties.MaxShadowsRequestCount, 4, 20, 4), SetMaxShadowsCount); val6.SetAsLastSibling(); base.manager.CreateBoolInputField(transform, ("Use Doorway Sisters", "If enabled, the DoorwaySisters component will become active.\n\nThe component prevents an intersecting doorway from generating if it's 'sister' doorway already generated and both doorways would lead to the same neighboring tile.\n\nThis is designed for the scenario where, two neighboring doorways would lead to the same tile, one doorway is a locked door and the other is an open doorway. This would defeat the purpose of the locked door, and such as, this feature exists if needed.\n\nThis feature slows down dungeon generation slightly when enabled."), properties.MiscellaneousProperties.UseDoorwaySisters, SetUseDoorwaySisters); base.manager.CreateBoolInputField(transform, ("Use Random Guaranteed Scrap", "If enabled, the RandomGuaranteedScrapSpawn component will be come active.\n\nThe component allows random scrap of a specified minimum value to always be spawned on a specific point."), properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn, SetUseRandomGuaranteedScrap); base.manager.CreateSpaceUIField(transform); mainPathParentGameobject.SetActive(properties.MainPathProperties.MainPathCount > 1); dungeonBoundsParentGameobject.SetActive(properties.DungeonBoundsProperties.UseDungeonBounds); dungeonBoundsHelperGameObject.SetActive(properties.DungeonBoundsProperties.UseDungeonBounds); archetypesNodesParentGameobject.SetActive(properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes); forcedTilesParentGameobject.SetActive(properties.AdditionalTilesProperties.UseAdditionalTiles); branchLoopBoostParentGameobject.SetActive(properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim); maxShadowsParentGameobject.SetActive(properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate); UpdateDungeonBoundsHelper(); } public void ClearPanel() { base.manager.ClearTransformChildren(selectedListGameObject.transform); } public void SetActivateDunGenPlus(bool state) { selectedExtenderer.Active = state; } public void SetDebugCallbackState(bool state) { eventCallbackValue = state; } public void SetMainPathCount(int value) { selectedExtenderer.Properties.MainPathProperties.MainPathCount = value; mainPathParentGameobject.SetActive(value > 1); } public void SetMainRoom(GameObject value) { selectedExtenderer.Properties.MainPathProperties.MainRoomTilePrefab = value; } public void SetCopyNodeBehaviour(DunGenExtenderProperties.CopyNodeBehaviour value) { selectedExtenderer.Properties.MainPathProperties.CopyNodeBehaviour = value; } public void SetUseDungeonBounds(bool state) { selectedExtenderer.Properties.DungeonBoundsProperties.UseDungeonBounds = state; dungeonBoundsHelperGameObject.SetActive(state); dungeonBoundsParentGameobject.SetActive(state); } public void UpdateDungeonBoundsHelper() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)selectedExtenderer == (Object)null)) { Transform transform = dungeonBoundsHelperGameObject.transform; Bounds dungeonBounds = selectedExtenderer.Properties.DungeonBoundsProperties.GetDungeonBounds(base.dungeon.Generator.LengthMultiplier); transform.localPosition = ((Bounds)(ref dungeonBounds)).center; transform.localScale = ((Bounds)(ref dungeonBounds)).size; } } public void SetDungeonBoundsSizeBase(Vector3 value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) selectedExtenderer.Properties.DungeonBoundsProperties.SizeBase = value; UpdateDungeonBoundsHelper(); } public void SetDungeonBoundsSizeFactor(Vector3 value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) selectedExtenderer.Properties.DungeonBoundsProperties.SizeFactor = value; UpdateDungeonBoundsHelper(); } public void SetDungeonBoundsPosOffset(Vector3 value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) selectedExtenderer.Properties.DungeonBoundsProperties.PositionOffset = value; UpdateDungeonBoundsHelper(); } public void SetDungeonBoundsPosPivot(Vector3 value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) selectedExtenderer.Properties.DungeonBoundsProperties.PositionPivot = value; UpdateDungeonBoundsHelper(); } public void SetAddArchetypes(bool state) { selectedExtenderer.Properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes = state; archetypesNodesParentGameobject.SetActive(state); } public void SetUseForcedTiles(bool state) { selectedExtenderer.Properties.AdditionalTilesProperties.UseAdditionalTiles = state; forcedTilesParentGameobject.SetActive(state); } public void SetUseBranchPathMultiSim(bool state) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim = state; branchLoopBoostParentGameobject.SetActive(state); } public void SetSimulationCount(int value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SimulationCount = value; } public void SetLengthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.LengthWeightScale = value; } public void SetNormalizedLengthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.NormalizedLengthWeightScale = value; } public void SamePathBaseConnectScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathBaseWeightScale = value; } public void DiffPathBaseConnectScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathBaseWeightScale = value; } public void SamePathConnectDepthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathDepthWeightScale = value; } public void DiffPathConnectDepthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathDepthWeightScale = value; } public void SamePathConnectNormalizedDepthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathNormalizedDepthWeightScale = value; } public void DiffPathConnectNormalizedDepthScale(float value) { selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathNormalizedDepthWeightScale = value; } public void SetUseMaxShadows(bool state) { selectedExtenderer.Properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate = state; maxShadowsParentGameobject.SetActive(state); } public void SetMaxShadowsCount(int value) { selectedExtenderer.Properties.MiscellaneousProperties.MaxShadowsRequestCount = value; } public void SetUseDoorwaySisters(bool state) { selectedExtenderer.Properties.MiscellaneousProperties.UseDoorwaySisters = state; } public void SetUseRandomGuaranteedScrap(bool state) { selectedExtenderer.Properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn = state; } public void RestoreOriginalState() { selectedExtenderer.Properties.CopyFrom(base.selectedAssetCache.originalProperties, DunGenExtender.CURRENT_VERSION); ClearPanel(); SetupPanel(); } } internal class MainPanel : BasePanel { internal IntInputField seedInputField; internal TextUIElement lengthMultiplierField; internal TextUIElement mapSizeMultiplierField; internal TextUIElement factorySizeMultiplierField; internal TextUIElement mapTileSizeField; internal ExtendedLevel[] levels; internal IEnumerable levelOptions; private ExtendedLevel selectedLevel; private GameObject asyncParentGameobject; public static MainPanel Instance { get; internal set; } public override void AwakeCall() { Instance = this; GetAllLevels(); DungeonGenerator generator = base.dungeon.Generator; Transform transform = mainGameObject.transform; base.manager.CreateHeaderUIField(transform, "Dungeon Generator"); seedInputField = base.manager.CreateIntInputField(transform, "Seed", generator.Seed, SetSeed); base.manager.CreateBoolInputField(transform, ("Randomize Seed", "If true, creates and saves a new seed when generating the dungeon."), generator.ShouldRandomizeSeed, SetRandomSeed); base.manager.CreateSpaceUIField(transform); base.manager.CreateIntInputField(transform, ("Max Attempts", "Maximum number of dungeon generation attempts before giving up."), new IntParameter(generator.MaxAttemptCount, 0, 500), SetMaxAttempts); base.manager.CreateSpaceUIField(transform); Transform val = base.manager.CreateVerticalLayoutUIField(transform); asyncParentGameobject = ((Component)val).gameObject; base.manager.CreateBoolInputField(transform, ("Generate Async", "If true, visually generates the dungeon tile by tile."), generator.GenerateAsynchronously, SetGenerateAsync); base.manager.CreateFloatInputField(val, "Max Async (ms)", new FloatParameter(generator.MaxAsyncFrameMilliseconds, 0f, float.MaxValue), SetMaxAsync); base.manager.CreateFloatInputField(val, "Pause Between Rooms", new FloatParameter(generator.PauseBetweenRooms, 0f, float.MaxValue), SetPauseBetweenRooms); val.SetAsLastSibling(); base.manager.CreateSpaceUIField(transform); base.manager.CreateHeaderUIField(transform, "Levels"); base.manager.CreateLevelOptionsUIField(transform, "Level", 0, SetLevel); lengthMultiplierField = base.manager.CreateTextUIField(transform, ("Length Multiplier", "Dungeon generation length multiplier based on the numerous factors.")); mapSizeMultiplierField = base.manager.CreateTextUIField(transform, ("Map Size Multiplier", "Map size multiplier based on the round manager (fixed).")); factorySizeMultiplierField = base.manager.CreateTextUIField(transform, ("Factory Size Multiplier", "Factory size multiplier based on the level.")); mapTileSizeField = base.manager.CreateTextUIField(transform, ("Map Tile Size", "Map tile size based on the dungeon.")); SetLevel(levels[0]); asyncParentGameobject.SetActive(generator.GenerateAsynchronously); } public void UpdatePanel() { SetLevel(selectedLevel); } public void SetSeed(int value) { base.dungeon.Generator.Seed = value; } public void SetRandomSeed(bool state) { base.dungeon.Generator.ShouldRandomizeSeed = state; } public void SetMaxAttempts(int value) { base.dungeon.Generator.MaxAttemptCount = value; } public void SetGenerateAsync(bool state) { base.dungeon.Generator.GenerateAsynchronously = state; asyncParentGameobject.SetActive(state); } public void SetMaxAsync(float value) { base.dungeon.Generator.MaxAsyncFrameMilliseconds = value; } public void SetPauseBetweenRooms(float value) { base.dungeon.Generator.PauseBetweenRooms = value; } private void GetAllLevels() { levels = PatchedContent.ExtendedLevels.ToArray(); levelOptions = levels.Select((ExtendedLevel l) => l.NumberlessPlanetName); } public void SetLevel(ExtendedLevel level) { (float, float, float, float) levelMultiplier = GetLevelMultiplier(level); base.dungeon.Generator.LengthMultiplier = levelMultiplier.Item1; base.manager.UpdateDungeonBounds(); string text = levelMultiplier.Item1.ToString("F2"); string text2 = levelMultiplier.Item2.ToString("F2"); string text3 = levelMultiplier.Item3.ToString("F2"); string text4 = levelMultiplier.Item4.ToString("F2"); lengthMultiplierField.SetText("Length multiplier: " + text + " [" + text2 + " / " + text4 + " * " + text3 + "]"); mapSizeMultiplierField.SetText("Map size multiplier: " + text2); factorySizeMultiplierField.SetText("Factory size multiplier: " + text3); mapTileSizeField.SetText("Map tile size: " + text4); selectedLevel = level; } private (float lengthMultiplier, float mapSizeMultiplier, float factorySizeMultiplier, float mapTileSize) GetLevelMultiplier(ExtendedLevel level) { RoundManager instance = RoundManager.Instance; float num = 1f; if ((Object)(object)instance != (Object)null) { num = instance.mapSizeMultiplier; } else { Plugin.logger.LogError((object)"RoundManager somehow null."); } float factorySizeMultiplier = level.SelectableLevel.factorySizeMultiplier; float mapTileSize = base.selectedExtendedDungeonFlow.MapTileSize; float num2 = num / mapTileSize * factorySizeMultiplier; num2 = (float)((double)Mathf.Round(num2 * 100f) / 100.0); return (num2, num, factorySizeMultiplier, mapTileSize); } } } namespace DunGenPlus.DevTools.Panels.Collections { internal class DungeonFlowCacheAssets { public struct Collection { public ReadOnlyCollection list; public ReadOnlyDictionary dictionary; public ReadOnlyCollection options; public Collection(List list) { this.list = new ReadOnlyCollection(list); Dictionary dictionary = new Dictionary(); for (int i = 0; i < list.Count; i++) { dictionary.Add(list[i], i); } this.dictionary = new ReadOnlyDictionary(dictionary); options = new ReadOnlyCollection(list.Select((T l) => l.ToString()).ToList()); } } public DunGenExtenderProperties originalProperties; public readonly Collection> tileSets; public readonly Collection> tiles; public readonly Collection> archetypes; public readonly Collection> mainPathExtenders; public DungeonFlowCacheAssets(DungeonFlow dungeonFlow, DunGenExtender extender) { if (Object.op_Implicit((Object)(object)extender)) { extender.Properties = extender.Properties.Copy(extender.Version); originalProperties = extender.Properties.Copy(extender.Version); } HashSet> tileSetsHashSet = new HashSet> { new NullObject(null) }; HashSet> tilesHashSet = new HashSet> { new NullObject(null) }; HashSet> archetypesHashSet = new HashSet> { new NullObject(null) }; HashSet> mainPathExtenderHashSet = new HashSet> { new NullObject(null) }; AddNodes(dungeonFlow.Nodes); AddLines(dungeonFlow.Lines); DungeonFlowCacheAssets.<.ctor>g__AddTileSets|6_4(dungeonFlow.TileInjectionRules.Select((TileInjectionRule n) => n.TileSet)); if (Object.op_Implicit((Object)(object)extender)) { DungeonFlowCacheAssets.<.ctor>g__AddArchetypes|6_5(extender.Properties.NormalNodeArchetypesProperties.NormalNodeArchetypes.SelectMany((NodeArchetype l) => l.Archetypes)); DungeonFlowCacheAssets.<.ctor>g__AddTileSets|6_4(extender.Properties.AdditionalTilesProperties.AdditionalTileSets.SelectMany((AdditionalTileSetList l) => l.TileSets)); AddTiles(extender.Properties.AssetCacheTileList); DungeonFlowCacheAssets.<.ctor>g__AddTileSets|6_4((IEnumerable)extender.Properties.AssetCacheTileSetList); DungeonFlowCacheAssets.<.ctor>g__AddArchetypes|6_5((IEnumerable)extender.Properties.AssetCacheArchetypeList); AddMainPathExtenders(extender.Properties.MainPathProperties.MainPathDetails); } tileSets = new Collection>(tileSetsHashSet.ToList()); tiles = new Collection>(tilesHashSet.ToList()); archetypes = new Collection>(archetypesHashSet.ToList()); mainPathExtenders = new Collection>(mainPathExtenderHashSet.ToList()); void AddLines(IEnumerable lines) { foreach (GraphLine line in lines) { AddArchetypes(line.DungeonArchetypes); void AddArchetypes(IEnumerable archetypes) { foreach (DungeonArchetype archetype in archetypes) { archetypesHashSet.Add(archetype); if ((Object)(object)archetype != (Object)null) { DungeonFlowCacheAssets.<.ctor>g__AddTileSets|6_4((IEnumerable)archetype.TileSets); DungeonFlowCacheAssets.<.ctor>g__AddTileSets|6_4((IEnumerable)archetype.BranchCapTileSets); } } } } } void AddMainPathExtenders(IEnumerable mainPaths) { foreach (MainPathExtender mainPath in mainPaths) { mainPathExtenderHashSet.Add(mainPath); if ((Object)(object)mainPath != (Object)null) { AddNodes(mainPath.Nodes.Value); AddLines(mainPath.Lines.Value); } } } void AddNodes(IEnumerable nodes) { foreach (GraphNode node in nodes) { AddTileSets(node.TileSets); void AddTileSets(IEnumerable tileSets) { foreach (TileSet tileSet in tileSets) { tileSetsHashSet.Add(tileSet); if ((Object)(object)tileSet != (Object)null) { AddTilesW(tileSet.TileWeights.Weights); } void AddTilesW(IEnumerable tiles) { foreach (GameObjectChance tile in tiles) { tilesHashSet.Add(tile.Value); } } } } } } void AddTiles(IEnumerable tiles) { foreach (GameObject tile2 in tiles) { tilesHashSet.Add(tile2); } } } } } namespace DunGenPlus.Components { public class DoorwaySisters : MonoBehaviour { private Doorway _self; [Tooltip("The list of 'sister' doorways.\n\nUseDoorwaySisters must be toggled in DunGenExtender for this component to be used.\n\nThis doorway will not generate if it's an intersecting doorway, any of it's 'sister' doorways are generated, and both this doorway and the 'sister' doorway lead to the same tile.")] public List sisters = new List(); public Doorway Self { get { if ((Object)(object)_self == (Object)null) { _self = ((Component)this).GetComponent(); } return _self; } } private void OnValidate() { IEnumerable enumerable = sisters.Select((Doorway s) => ((Component)s).GetComponent()); foreach (DoorwaySisters item in enumerable) { if (!((Object)(object)item == (Object)null)) { item.TryAddSisterDoorway(Self); } } } public void TryAddSisterDoorway(Doorway doorway) { if (!sisters.Contains(doorway)) { sisters.Add(doorway); } } public void OnDrawGizmosSelected() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position + Vector3.up; if (sisters == null) { return; } foreach (Doorway sister in sisters) { Vector3 val2 = ((Component)sister).transform.position + Vector3.up; DoorwaySisters component = ((Component)sister).GetComponent(); Doorway self = Self; if ((Object)(object)self == (Object)null) { Gizmos.color = Color.magenta; } else if ((Object)(object)component == (Object)null || component.sisters == null) { Gizmos.color = Color.yellow; } else if (!component.sisters.Contains(self)) { Gizmos.color = Color.red; } else { Gizmos.color = Color.green; } Gizmos.DrawLine(val, val2); Gizmos.DrawSphere((val + val2) * 0.5f, 0.25f); } } } public class MainRoomDoorwayGroups : MonoBehaviour { [Serializable] public class DoorwayList { [Tooltip("For organizing purposes. Has no effect.")] public string name; [Tooltip("The group of doorways.")] public List doorways; public bool Contains(Doorway target) { return doorways.Contains(target); } } public enum DoorwayGroupBehaviour { RemoveGroup, SetInOrder } [Tooltip("How the algorithm should treat these doorway groups during the main path(s) generation step.\n\nWith RemoveGroup, when a main path is being generated, it will get the doorway in this tile used to start the main path, find it's corresponding group below, and prevent the dungeon generation from using that group's doorways until all main paths are generated.\nThis is designed for the scenario where you would like the main paths to be generated more evenly throughout the MainRoomTilePrefab.\n\nWith SetInOrder, before a doorway is selected in this tile to start the main path, it will grab the first group below and only allow those doorways to start the main path. It will then select the next group for the next main path and repeat. If it cannot grab a next group, then the last group will be selected instead.\n\nIf you want this feature, this must be attached to the tile that will act as the MainRoomTilePrefab")] public DoorwayGroupBehaviour doorwayGroupBehaviour; public List doorwayLists; public static bool ModifyGroupBasedOnBehaviourSimpleOnce; public List doorwayListFirst => (doorwayLists.Count > 0) ? doorwayLists[0].doorways : null; public List GrabDoorwayGroup(int index) { int count = doorwayLists.Count; if (count == 0) { return null; } if (index < count) { return doorwayLists[index].doorways; } return doorwayLists[count - 1].doorways; } public List GrabDoorwayGroup(Doorway target) { foreach (DoorwayList doorwayList in doorwayLists) { if (doorwayList.Contains(target)) { return doorwayList.doorways; } } return null; } public void OnlyUnlockGroup(TileProxy tileProxy, DoorwayProxy fakeDoorwayProxy, List selectedDoorways) { if (selectedDoorways == null) { return; } foreach (DoorwayProxy doorway in tileProxy.Doorways) { if (selectedDoorways.Contains(doorway.DoorwayComponent)) { if (doorway.Used && doorway.ConnectedDoorway.Index == int.MaxValue) { doorway.ConnectedDoorway = null; } } else if (!doorway.Used) { doorway.ConnectedDoorway = fakeDoorwayProxy; } } } public void OnlyLockGroup(TileProxy tileProxy, DoorwayProxy fakeDoorwayProxy) { foreach (DoorwayProxy usedDoorway in tileProxy.UsedDoorways) { if (usedDoorway.ConnectedDoorway.Index == int.MaxValue) { continue; } List list = GrabDoorwayGroup(usedDoorway.DoorwayComponent); if (list == null) { continue; } foreach (DoorwayProxy unusedDoorway in tileProxy.UnusedDoorways) { if (list.Contains(unusedDoorway.DoorwayComponent)) { unusedDoorway.ConnectedDoorway = fakeDoorwayProxy; } } } } public static void ModifyGroupBasedOnBehaviour(TileProxy tileProxy, int groupIndex) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown MainRoomDoorwayGroups componentInChildren = tileProxy.Prefab.GetComponentInChildren(); if (!((Object)(object)componentInChildren == (Object)null)) { DoorwayProxy fakeDoorwayProxy = new DoorwayProxy(tileProxy, int.MaxValue, tileProxy.doorways[0].DoorwayComponent, Vector3.zero, Quaternion.identity); if (componentInChildren.doorwayGroupBehaviour == DoorwayGroupBehaviour.SetInOrder) { componentInChildren.OnlyUnlockGroup(tileProxy, fakeDoorwayProxy, componentInChildren.GrabDoorwayGroup(groupIndex)); } else { componentInChildren.OnlyLockGroup(tileProxy, fakeDoorwayProxy); } } } public static void ModifyGroupBasedOnBehaviourSimple(TileProxy tileProxy) { if (DunGenPlusGenerator.Active && !ModifyGroupBasedOnBehaviourSimpleOnce && tileProxy != null) { DunGenExtenderProperties properties = DunGenPlusGenerator.Properties; int num = properties.MainPathProperties.MainPathCount - 1; GameObject mainRoomTilePrefab = properties.MainPathProperties.MainRoomTilePrefab; if (num > 0 && !((Object)(object)mainRoomTilePrefab == (Object)null) && (Object)(object)tileProxy.Prefab == (Object)(object)mainRoomTilePrefab) { ModifyGroupBasedOnBehaviour(tileProxy, 0); ModifyGroupBasedOnBehaviourSimpleOnce = true; } } } public static void RemoveFakeDoorwayProxies(TileProxy tileProxy) { foreach (DoorwayProxy usedDoorway in tileProxy.UsedDoorways) { if (usedDoorway.ConnectedDoorway.Index == int.MaxValue) { usedDoorway.ConnectedDoorway = null; } } } } public class TileExtender : MonoBehaviour { public List entrances = new List(); public List exits = new List(); public bool entranctExitInterchangable; public List overlappingDoorways = new List(); } } namespace DunGenPlus.Components.Scripting { public class DoorwayScriptingParent : DunGenPlusScriptingParent { [Header("Scripting Debug")] public Doorway connectedDoorwayDebug; public override void Awake() { base.Awake(); if (!((Object)(object)targetReference == (Object)null)) { AddNamedReference("connectors", targetReference.ConnectorSceneObjects); targetReference.ConnectorSceneObjects = new List(); AddNamedReference("blockers", targetReference.BlockerSceneObjects); targetReference.BlockerSceneObjects = new List(); } } public override void Call() { if (!((Object)(object)targetReference == (Object)null)) { bool flag = (Object)(object)targetReference.connectedDoorway != (Object)null; SetNamedGameObjectState("connectors", flag); SetNamedGameObjectState("blockers", !flag); base.Call(); } } private Doorway GetDoorway(string name) { if (!(name == "self")) { if (name == "other") { return DunGenPlusScriptingParent.InDebugMode ? connectedDoorwayDebug : targetReference.ConnectedDoorway; } Utility.PrintLog(name + " is not valid doorway expression. Please use 'self' or 'other'", (LogLevel)2); return null; } return targetReference; } public override EvaluationContext CreateContext() { EvaluationContext evaluationContext = base.CreateContext(); evaluationContext.RegisterFunction("doorwaySpawnedGameObject", new FunctionRoutine(2, doorwaySpawnedGameObjectFunction)); return evaluationContext; } private ExpressionToken doorwaySpawnedGameObjectFunction(EvaluationContext context, ExpressionToken[] parameters) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown string value = parameters[0].Value; Doorway doorway = GetDoorway(value); if ((Object)(object)doorway != (Object)null) { string value2 = parameters[1].Value; foreach (Transform item in ((Component)doorway).transform) { Transform val = item; if (((Component)val).gameObject.activeSelf && ((Object)val).name.Contains(value2)) { return ExpressionToken.True; } } } return ExpressionToken.False; } public override (object, ValueTypeHint) GetFields(string field) { string[] array = field.Split(new char[1] { '.' }); if (array.Length <= 1) { Utility.PrintLog(field + " is not a valid field", (LogLevel)2); return (0, ValueTypeHint.Auto); } string name = array[0]; Doorway doorway = GetDoorway(name); string text = array[1]; string text2 = text; string text3 = text2; if (!(text3 == "priority")) { if (text3 == "exists") { return ((Object)(object)doorway != (Object)null, ValueTypeHint.Auto); } Utility.PrintLog(text + " is not a valid getter", (LogLevel)2); return (0, ValueTypeHint.Auto); } if ((Object)(object)doorway != (Object)null) { return (doorway.DoorPrefabPriority, ValueTypeHint.Auto); } return (0, ValueTypeHint.Auto); } } public enum ScriptActionType { SwitchToConnector, SwitchToBlocker, SetNamedReferenceState } [Serializable] public struct ScriptAction { public ScriptActionType type; public string namedReference; public bool boolValue; public void CallAction(IDunGenScriptingParent parent) { switch (type) { case ScriptActionType.SwitchToConnector: parent.SetNamedGameObjectState("connectors", state: true); parent.SetNamedGameObjectState("blockers", state: false); break; case ScriptActionType.SwitchToBlocker: parent.SetNamedGameObjectState("connectors", state: false); parent.SetNamedGameObjectState("blockers", state: true); break; case ScriptActionType.SetNamedReferenceState: parent.SetNamedGameObjectState(namedReference, boolValue); break; } } } public class DunGenPlusScript : MonoBehaviour { public static bool InDebugMode; public string expression; public List actions; public bool EvaluateExpression(IDunGenScriptingParent parent) { EvaluationContext context = parent.CreateContext(); Evaluator evaluator = new Evaluator(context); try { InDebugMode = false; ExpressionToken expressionToken = evaluator.Evaluate(expression, coerseToBoolean: true); return expressionToken.ToDouble(context) > 0.0; } catch (Exception ex) { Plugin.logger.LogError((object)("Expression [" + expression + "] could not be parsed. Returning false")); Plugin.logger.LogError((object)ex.ToString()); } return false; } [ContextMenu("Verify")] public void VerifyExpression() { EvaluationContext context = ((Component)this).GetComponent().CreateContext(); Evaluator evaluator = new Evaluator(context); try { InDebugMode = true; ExpressionToken expressionToken = evaluator.Evaluate(expression); Debug.Log((object)("Expression parsed successfully: " + expressionToken.ToString() + " (" + evaluator.ConvertTokenToFalseTrue(expressionToken).ToString() + ")")); } catch (Exception ex) { Debug.LogError((object)("Expression [" + expression + "] could not be parsed")); Debug.LogError((object)ex.ToString()); } } public void Call(IDunGenScriptingParent parent) { if (!EvaluateExpression(parent)) { return; } foreach (ScriptAction action in actions) { action.CallAction(parent); } } } public enum OverrideGameObjectState { None, Active, Disabled } [Serializable] public class NamedGameObjectReference { public string name; public List gameObjects; public OverrideGameObjectState overrideState; public NamedGameObjectReference(string name, List gameObjects) { this.name = name; this.gameObjects = gameObjects; } public void SetState(bool state) { foreach (GameObject gameObject in gameObjects) { if (gameObject != null) { gameObject.SetActive(state); } } } public void FixOverrideState() { if (overrideState != 0) { SetState(overrideState == OverrideGameObjectState.Active); } } public void DestroyInactiveGameObjects() { foreach (GameObject gameObject in gameObjects) { if (Object.op_Implicit((Object)(object)gameObject) && !gameObject.activeSelf) { Object.DestroyImmediate((Object)(object)gameObject, false); } } } } public enum DunGenScriptingHook { SetLevelObjectVariables, OnMainEntranceTeleportSpawned } public interface IDunGenScriptingParent { DunGenScriptingHook GetScriptingHook { get; } List GetNamedReferences { get; } void Call(); void AddNamedReference(string name, List gameObjects); void SetNamedGameObjectState(string name, bool state); void SetNamedGameObjectOverrideState(string name, OverrideGameObjectState state); EvaluationContext CreateContext(); } public abstract class DunGenPlusScriptingParent : MonoBehaviour, IDunGenScriptingParent, IDungeonCompleteReceiver where T : Component { [Header("REQUIRED")] [Tooltip("The target reference.")] public T targetReference; public DunGenScriptingHook callHook = DunGenScriptingHook.OnMainEntranceTeleportSpawned; [Header("Named References")] [Tooltip("Provide a variable name for a list of gameObjects. Used in DunGenScripting.")] public List namedReferences = new List(); public Dictionary namedDictionary = new Dictionary(); public static bool InDebugMode => DunGenPlusScript.InDebugMode; public DunGenScriptingHook GetScriptingHook => callHook; public List GetNamedReferences => namedReferences; public void OnDungeonComplete(Dungeon dungeon) { DoorwayManager.AddDunGenScriptHook(this); } public virtual void Awake() { foreach (NamedGameObjectReference namedReference in namedReferences) { namedDictionary.Add(namedReference.name, namedReference); } } public virtual void Call() { DunGenPlusScript[] componentsInChildren = ((Component)this).GetComponentsInChildren(); DunGenPlusScript[] array = componentsInChildren; foreach (DunGenPlusScript dunGenPlusScript in array) { dunGenPlusScript.Call(this); } foreach (NamedGameObjectReference namedReference in namedReferences) { namedReference.FixOverrideState(); } foreach (NamedGameObjectReference namedReference2 in namedReferences) { DestroyInactiveGameObjects(namedReference2.gameObjects); } } public void AddNamedReference(string name, List gameObjects) { NamedGameObjectReference namedGameObjectReference = new NamedGameObjectReference(name, gameObjects); namedReferences.Add(namedGameObjectReference); namedDictionary.Add(name, namedGameObjectReference); } public void SetNamedGameObjectState(string name, bool state) { if (namedDictionary.TryGetValue(name, out var value)) { value.SetState(state); } else { Plugin.logger.LogError((object)("Named reference: " + name + " does not exist")); } } public NamedGameObjectReference GetNamedGameObject(string name) { if (namedDictionary.TryGetValue(name, out var value)) { return value; } return null; } public void SetNamedGameObjectOverrideState(string name, OverrideGameObjectState state) { if (namedDictionary.TryGetValue(name, out var value)) { value.overrideState = state; } } public void DestroyInactiveGameObjects(IEnumerable gameObjects) { foreach (GameObject gameObject in gameObjects) { if (Object.op_Implicit((Object)(object)gameObject) && !gameObject.activeSelf) { Object.DestroyImmediate((Object)(object)gameObject, false); } } } public virtual EvaluationContext CreateContext() { EvaluationContext evaluationContext = new EvaluationContext(GetFields); evaluationContext.RegisterFunction("isAnyActive", new FunctionRoutine(1, isAnyActiveFunction)); evaluationContext.RegisterFunction("isAllActive", new FunctionRoutine(1, isAllActiveFunction)); return evaluationContext; } public virtual (object, ValueTypeHint) GetFields(string field) { return default((object, ValueTypeHint)); } private ExpressionToken isAnyActiveFunction(EvaluationContext context, ExpressionToken[] parameters) { string value = parameters[0].Value; NamedGameObjectReference namedGameObject = GetNamedGameObject(value); if (namedGameObject != null) { return namedGameObject.gameObjects.Any((GameObject x) => (Object)(object)x != (Object)null && x.activeSelf) ? ExpressionToken.True : ExpressionToken.False; } return ExpressionToken.False; } private ExpressionToken isAllActiveFunction(EvaluationContext context, ExpressionToken[] parameters) { string value = parameters[0].Value; NamedGameObjectReference namedGameObject = GetNamedGameObject(value); if (namedGameObject != null) { return namedGameObject.gameObjects.All((GameObject x) => (Object)(object)x != (Object)null && x.activeSelf) ? ExpressionToken.True : ExpressionToken.False; } return ExpressionToken.False; } } internal class GenericScriptingParent : DunGenPlusScriptingParent { } } namespace DunGenPlus.Components.Scrap { public class RandomGuaranteedScrapSpawn : MonoBehaviour { [Tooltip("Chance for the loot to even spawn.")] [Range(0f, 1f)] public float spawnChance = 1f; [Tooltip("Minimum scrap value of the scrap item.")] public int minimumScrapValue = 0; [Tooltip("Maximum scrap value of the scrap item.")] public int maximumScrapValue = 100; [Tooltip("Forces this item in particular to spawn. Overrides min/max scrap values")] public string specificScrapTarget; internal static Dictionary<(int, int), IEnumerable> scrapItemRarityValueCache; internal static Dictionary> scrapItemRarityNameCache; internal static void ResetCache() { scrapItemRarityValueCache = new Dictionary<(int, int), IEnumerable>(); scrapItemRarityNameCache = new Dictionary>(); } internal static IEnumerable GetCachedItemList(List allMoonItems, int minScrapValue, int maxScrapValue) { (int, int) key = (minScrapValue, maxScrapValue); if (!scrapItemRarityValueCache.TryGetValue(key, out var value)) { value = allMoonItems.Where((SpawnableItemWithRarity i) => i.spawnableItem.minValue >= minScrapValue && maxScrapValue <= i.spawnableItem.minValue).ToArray(); scrapItemRarityValueCache.Add(key, value); } return value; } internal static IEnumerable GetCachedItemList(List allMoonItems, string scrapName) { scrapName = scrapName.ToLowerInvariant(); if (!scrapItemRarityNameCache.TryGetValue(scrapName, out var value)) { value = allMoonItems.Where((SpawnableItemWithRarity i) => ((Object)i.spawnableItem).name.ToLowerInvariant().Contains(scrapName) || i.spawnableItem.itemName.ToLowerInvariant().Contains(scrapName)).ToArray(); scrapItemRarityNameCache.Add(scrapName, value); } return value; } internal IEnumerable GetCachedItemList(List allMoonItems) { if (string.IsNullOrWhiteSpace(specificScrapTarget)) { return GetCachedItemList(allMoonItems, minimumScrapValue, maximumScrapValue); } return GetCachedItemList(allMoonItems, specificScrapTarget); } internal static Item GetRandomItem(IEnumerable list) { int[] array = new int[list.Count()]; for (int i = 0; i < array.Length; i++) { array[i] = list.ElementAt(i).rarity; } int randomWeightedIndex = RoundManager.Instance.GetRandomWeightedIndex(array, (Random)null); return list.ElementAt(randomWeightedIndex).spawnableItem; } internal (NetworkObject itemReference, int scrapValue) CreateItem(RoundManager roundManager, List allMoonItems) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Random anomalyRandom = roundManager.AnomalyRandom; if (anomalyRandom.NextDouble() >= (double)spawnChance) { return (null, 0); } IEnumerable cachedItemList = GetCachedItemList(allMoonItems); if (cachedItemList.Count() == 0) { return (null, 0); } Item randomItem = GetRandomItem(cachedItemList); int num = (int)((float)anomalyRandom.Next(randomItem.minValue, randomItem.maxValue) * roundManager.scrapValueMultiplier); GameObject val = Object.Instantiate(randomItem.spawnPrefab, ((Component)this).transform.position, Quaternion.identity, roundManager.spawnedScrapContainer); GrabbableObject component = val.GetComponent(); val.transform.rotation = Quaternion.Euler(randomItem.restingRotation); component.fallTime = 0f; component.scrapValue = num; NetworkObject component2 = val.GetComponent(); component2.Spawn(false); return (component2, num); } } } namespace DunGenPlus.Components.Props { public class SpawnSyncedObjectCycle : MonoBehaviour, IDungeonCompleteReceiver { internal static int cycle; internal static Dictionary cycleDictionary; [Tooltip("The SpawnSyncedObject reference.\n\nWhen the dungeon generation finishes, the spawnPrefab of the referenced SpawnSyncedObject will change to one of the Props based on a cycle. The starting value is random.\n\nThis is designed for the scenario where you have multiple very similar networked gameobjects that serve the same purpose, and you just want them all to spawn equally for diversity sake.")] public SpawnSyncedObject Spawn; [Tooltip("The unique id for this script's cycle.\n\nWhen the dungeon generation finishes, a random cycle value is calculated for each Id. Each script will reference their Id's corresponding cycle value to determine their Prop, and advance the cycle value by 1.")] public int Id; [Tooltip("The list of props that would selected based on a cycle.")] public List Props = new List(); private void Reset() { Spawn = ((Component)this).GetComponent(); } internal static void UpdateCycle(int value) { Plugin.logger.LogDebug((object)$"Updating SpawnSyncedObject start cycle to {value}"); cycle = value; cycleDictionary = new Dictionary(); } internal int GetCycle(int id) { if (!cycleDictionary.TryGetValue(id, out var value)) { value = cycle; cycleDictionary.Add(id, value); } cycleDictionary[id] = value + 1; Plugin.logger.LogDebug((object)$"Cycle{id}: {value}"); return value; } public void OnDungeonComplete(Dungeon dungeon) { int index = GetCycle(Id) % Props.Count; GameObject spawnPrefab = Props[index]; Spawn.spawnPrefab = spawnPrefab; } } } namespace DunGenPlus.Collections { [Serializable] public class DetailedGlobalPropSettings { internal const string MinimumDistanceTooltip = "The minimum distance between each Global Props of this id."; internal const string GlobalCountMustBeReachedTooltip = "If true, when the global limit is not reached due to minimum distance, ignore it and try to reach the global limit anyway."; public int ID; [Space] [Tooltip("The minimum distance between each Global Props of this id.")] public float MinimumDistance; public bool GlobalCountMustBeReached = true; public DetailedGlobalPropSettings(int id, float minimumDistance, bool globalCountMustBeReached) { ID = id; MinimumDistance = minimumDistance; GlobalCountMustBeReached = globalCountMustBeReached; } } [Serializable] public class DunGenExtenderEvents { public ExtenderEvent OnModifyDunGenExtenderProperties = new ExtenderEvent(); public ExtenderModifier OnModifyDoorwayPairWeight = new ExtenderModifier(); } public struct DoorwayPairCollection { public TileProxy previousTile; public TileProxy nextTile; public DoorwayProxy previousDoor; public DoorwayProxy nextDoor; public DoorwayPairCollection(TileProxy previousTile, TileProxy nextTile, DoorwayProxy previousDoor, DoorwayProxy nextDoor) { this.previousTile = previousTile; this.nextTile = nextTile; this.previousDoor = previousDoor; this.nextDoor = nextDoor; } } [Serializable] public class MainPathProperties { internal const string MainPathCountTooltip = "The number of main paths.\n\n1 means no additional main paths\n3 means two additional main paths\netc."; internal const string MainRoomTilePrefabTooltip = "The Tile prefab where the additional main paths will start from.\n\nCannot be null if MainPathCount is more than 1."; internal const string CopyNodeBehaviourTooltip = "Defines how the nodes list is copied onto the additional main paths.\n\nCopyFromMainPathPosition: nodes will copy based on the MainRoomTilePrefab's position in the main path.\nCopyFromNodeList: nodes will copy based on the MainRoomTilePrefab's position in the node list + 1."; internal const string MainPathDetailsTooltip = "Overrides certain DungeonFlow values during the main path generation.\n\nThe order of items in this list correspond to the order of the main paths being generated.\nThe first item in this list will activate for the first main path, the second item for the second main path, and so on. If there are more main paths than items in this list, the last item is used instead."; internal const string DetailedGlobalPropSettingsTooltip = "Additional settings for how Global Props spawn."; [Tooltip("The number of main paths.\n\n1 means no additional main paths\n3 means two additional main paths\netc.")] [Range(1f, 9f)] public int MainPathCount = 1; [Tooltip("The Tile prefab where the additional main paths will start from.\n\nCannot be null if MainPathCount is more than 1.")] public GameObject MainRoomTilePrefab; [Tooltip("Defines how the nodes list is copied onto the additional main paths.\n\nCopyFromMainPathPosition: nodes will copy based on the MainRoomTilePrefab's position in the main path.\nCopyFromNodeList: nodes will copy based on the MainRoomTilePrefab's position in the node list + 1.")] public DunGenExtenderProperties.CopyNodeBehaviour CopyNodeBehaviour = DunGenExtenderProperties.CopyNodeBehaviour.CopyFromMainPathPosition; [Tooltip("Overrides certain DungeonFlow values during the main path generation.\n\nThe order of items in this list correspond to the order of the main paths being generated.\nThe first item in this list will activate for the first main path, the second item for the second main path, and so on. If there are more main paths than items in this list, the last item is used instead.")] public List MainPathDetails = new List(); [Tooltip("Additional settings for how Global Props spawn.")] public List DetailedGlobalPropSettings = new List(); public MainPathExtender GetMainPathDetails(int index) { int count = MainPathDetails.Count; if (count == 0) { return null; } if (index < count) { return MainPathDetails[index]; } return MainPathDetails[count - 1]; } internal void CopyFrom(MainPathProperties props) { MainPathCount = props.MainPathCount; MainRoomTilePrefab = props.MainRoomTilePrefab; CopyNodeBehaviour = props.CopyNodeBehaviour; MainPathDetails = props.MainPathDetails; DetailedGlobalPropSettings = props.DetailedGlobalPropSettings; } internal MainPathProperties Copy() { MainPathProperties mainPathProperties = new MainPathProperties(); mainPathProperties.CopyFrom(this); return mainPathProperties; } } [Serializable] public class DungeonBoundsProperties { internal const string UseDungeonBoundsTooltip = "If enabled, restricts the dungeon's generation to the bounds described below.\n\nThis will help in condensing the dungeon, but it will increase the chance of dungeon generation failure (potentially guarantees failure if the bounds is too small)."; internal const string SizeBaseTooltip = "The base size of the bounds."; internal const string SizeFactorTooltip = "The factor that's multiplied with the base size AND the dungeon's size. The resulting value is added to the base size of the bounds.\n\n0 means that the bound size is not influenced by the dungeon's size and is therefore a constant."; internal const string PositionOffsetTooltip = "The base positional offset of the bounds."; internal const string PositionPivotTooltip = "The pivot of the bounds."; [Tooltip("If enabled, restricts the dungeon's generation to the bounds described below.\n\nThis will help in condensing the dungeon, but it will increase the chance of dungeon generation failure (potentially guarantees failure if the bounds is too small).")] public bool UseDungeonBounds = false; [Tooltip("The base size of the bounds.")] public Vector3 SizeBase = new Vector3(120f, 40f, 80f); [Tooltip("The factor that's multiplied with the base size AND the dungeon's size. The resulting value is added to the base size of the bounds.\n\n0 means that the bound size is not influenced by the dungeon's size and is therefore a constant.")] public Vector3 SizeFactor = new Vector3(1f, 0.5f, 1f); [Tooltip("The base positional offset of the bounds.")] public Vector3 PositionOffset = Vector3.zero; [Tooltip("The pivot of the bounds.")] public Vector3 PositionPivot = new Vector3(0.5f, 0.5f, 0.5f); internal void CopyFrom(DungeonBoundsProperties props) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) UseDungeonBounds = props.UseDungeonBounds; SizeBase = props.SizeBase; SizeFactor = props.SizeFactor; PositionOffset = props.PositionOffset; PositionPivot = props.PositionPivot; } internal DungeonBoundsProperties Copy() { DungeonBoundsProperties dungeonBoundsProperties = new DungeonBoundsProperties(); dungeonBoundsProperties.CopyFrom(this); return dungeonBoundsProperties; } internal Bounds GetDungeonBounds(float dungeonScale) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector3 val = SizeBase + Vector3.Scale(SizeBase * (dungeonScale - 1f), SizeFactor); Vector3 val2 = PositionOffset + Vector3.Scale(val, PositionPivot - Vector3.one * 0.5f); return new Bounds(val2, val); } } [Serializable] public class NormalNodeArchetypesProperties { internal const string AddArchetypesToNormalNodesTooltip = "If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths."; [Tooltip("If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths.")] public bool AddArchetypesToNormalNodes = false; public List NormalNodeArchetypes = new List(); internal Dictionary _normalNodeArchetypesDictioanry; internal NodeArchetype _defaultNodeArchetype; internal void CopyFrom(NormalNodeArchetypesProperties props) { AddArchetypesToNormalNodes = props.AddArchetypesToNormalNodes; NormalNodeArchetypes = props.NormalNodeArchetypes; } internal NormalNodeArchetypesProperties Copy() { NormalNodeArchetypesProperties normalNodeArchetypesProperties = new NormalNodeArchetypesProperties(); normalNodeArchetypesProperties.CopyFrom(this); return normalNodeArchetypesProperties; } internal void SetupProperties(DungeonGenerator generator) { _normalNodeArchetypesDictioanry = new Dictionary(); _defaultNodeArchetype = null; foreach (NodeArchetype normalNodeArchetype in NormalNodeArchetypes) { if (_normalNodeArchetypesDictioanry.ContainsKey(normalNodeArchetype.Label)) { Plugin.logger.LogError((object)("Label " + normalNodeArchetype.Label + " already exists. Ignoring latest entry.")); continue; } _normalNodeArchetypesDictioanry.Add(normalNodeArchetype.Label, normalNodeArchetype); if (string.IsNullOrWhiteSpace(normalNodeArchetype.Label)) { _defaultNodeArchetype = normalNodeArchetype; } } } internal DungeonArchetype GetRandomArchetype(string label, RandomStream randomStream) { if (!_normalNodeArchetypesDictioanry.TryGetValue(label, out var value)) { value = _defaultNodeArchetype; } if (value != null) { List archetypes = value.Archetypes; int count = archetypes.Count; if (count == 0) { return null; } int index = randomStream.Next(0, count); return archetypes[index]; } return null; } } [Serializable] public class ForcedTilesProperties { internal const string UseForcedTilesTooltip = "If enabled, attempts to forcefully spawn tiles from ForcedTileSets after branching paths are generated."; internal const string ForcedTileSetsTooltip = "The list of tiles that will be attempted to forcefully spawn. Each entry will spawn only one tile from it's list.\n\nIf the tile cannot be forcefully spawned, the dungeon generation will not restart."; [Tooltip("If enabled, attempts to forcefully spawn tiles from ForcedTileSets after branching paths are generated.")] public bool UseForcedTiles = false; [Tooltip("The list of tiles that will be attempted to forcefully spawn. Each entry will spawn only one tile from it's list.\n\nIf the tile cannot be forcefully spawned, the dungeon generation will not restart.")] public List ForcedTileSets = new List(); internal void CopyFrom(ForcedTilesProperties props) { UseForcedTiles = props.UseForcedTiles; ForcedTileSets = props.ForcedTileSets; } internal ForcedTilesProperties Copy() { ForcedTilesProperties forcedTilesProperties = new ForcedTilesProperties(); forcedTilesProperties.CopyFrom(this); return forcedTilesProperties; } } [Serializable] public class AdditionalTilesProperties { internal const string UseAdditionalTilesTooltip = "If enabled, attempts to generate additional tiles from AdditionalTileSets after main and branching paths are generated."; internal const string AdditionalTileSetsTooltip = "The list of tiles that will be attempted to generate. Each entry will spawn only one tile from it's list.\n\nEven if the tile cannot be generated, the dungeon generation will not restart."; [Tooltip("If enabled, attempts to generate additional tiles from AdditionalTileSets after main and branching paths are generated.")] public bool UseAdditionalTiles = false; [Tooltip("The list of tiles that will be attempted to generate. Each entry will spawn only one tile from it's list.\n\nEven if the tile cannot be generated, the dungeon generation will not restart.")] public List AdditionalTileSets = new List(); internal void CopyFrom(AdditionalTilesProperties props) { UseAdditionalTiles = props.UseAdditionalTiles; AdditionalTileSets = props.AdditionalTileSets; } internal void CopyFrom(ForcedTilesProperties props) { UseAdditionalTiles = props.UseForcedTiles; AdditionalTileSets = ((IEnumerable)props.ForcedTileSets).Select((Func)((ForcedTileSetList t) => t)).ToList(); } internal AdditionalTilesProperties Copy() { AdditionalTilesProperties additionalTilesProperties = new AdditionalTilesProperties(); additionalTilesProperties.CopyFrom(this); return additionalTilesProperties; } } [Serializable] public class BranchPathMultiSimulationProperties { internal const string UseBranchPathMultiSimTooltip = "If enabled, dungeon generation will simulate a number of paths for each branch path, then choose the path based on the highest weight and generate it. The weight is decided by the following criteria below.\n\nCan slow down Branch Path Generation Times by a second or two."; internal const string SimulationCountTooltip = "The number of simulations per branch path.\n\nIncreasing this value can increase your chances of finding your desired path, but will increase Branch Path Times and vice versa."; internal const string LengthWeightScaleTooltip = "The weight scale for the branch path's length. The length of the branch path is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize very long branch paths."; internal const string NormalizedLengthWeightScaleTooltip = "The weight scale for the branch path's normalized length. The normalized length (0 -> 1) of the branch path (PathLength / MaxPathLength) is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who meet their maximum path length."; [Tooltip("If enabled, dungeon generation will simulate a number of paths for each branch path, then choose the path based on the highest weight and generate it. The weight is decided by the following criteria below.\n\nCan slow down Branch Path Generation Times by a second or two.")] public bool UseBranchPathMultiSim = false; [Tooltip("The number of simulations per branch path.\n\nIncreasing this value can increase your chances of finding your desired path, but will increase Branch Path Times and vice versa.")] public int SimulationCount = 5; [Space] [Tooltip("The weight scale for the branch path's length. The length of the branch path is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize very long branch paths.")] public float LengthWeightScale = 0.125f; [Tooltip("The weight scale for the branch path's normalized length. The normalized length (0 -> 1) of the branch path (PathLength / MaxPathLength) is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who meet their maximum path length.")] public float NormalizedLengthWeightScale = 1f; internal const string SamePathBaseWeightScaleTooltip = "The weight scale for the branch path's number of connections to the same main path. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops in their main path in general."; internal const string SamePathDepthWeightScaleTooltip = "The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to their main paths."; internal const string SamePathNormalizedDepthWeightTooltip = "The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to their main paths."; [Space] [Header("Same Path")] [Tooltip("The weight scale for the branch path's number of connections to the same main path. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops in their main path in general.")] public float SamePathBaseWeightScale = 0.125f; [Tooltip("The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to their main paths.")] public float SamePathDepthWeightScale = 0.125f; [Tooltip("The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to their main paths.")] public float SamePathNormalizedDepthWeightScale = 1f; internal const string DiffPathBaseWeightScaleTooltip = "The weight scale for the branch path's number of connections to other main paths. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops to other main paths in general."; internal const string DiffPathDepthWeightScaleTooltip = "The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to other main paths."; internal const string DiffPathNormalizedDepthWeightTooltip = "The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to other main paths."; [Space] [Header("Different Path")] [Tooltip("The weight scale for the branch path's number of connections to other main paths. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops to other main paths in general.")] public float DiffPathBaseWeightScale = 0.25f; [Tooltip("The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to other main paths.")] public float DiffPathDepthWeightScale = 0.25f; [Tooltip("The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to other main paths.")] public float DiffPathNormalizedDepthWeightScale = 2f; public float GetWeightBase(float length, float normalizedLength) { float num = 0f; num += length * LengthWeightScale; return num + normalizedLength * NormalizedLengthWeightScale; } public float GetWeightPathConnection(bool samePath, float depthDifference, float normalizedDepthDifference) { float num = 0f; if (samePath) { num += SamePathBaseWeightScale; num += depthDifference * SamePathDepthWeightScale; return num + normalizedDepthDifference * SamePathNormalizedDepthWeightScale; } num += DiffPathBaseWeightScale; num += depthDifference * DiffPathDepthWeightScale; return num + normalizedDepthDifference * DiffPathNormalizedDepthWeightScale; } internal void CopyFrom(BranchPathMultiSimulationProperties props) { UseBranchPathMultiSim = props.UseBranchPathMultiSim; SimulationCount = props.SimulationCount; LengthWeightScale = props.LengthWeightScale; NormalizedLengthWeightScale = props.NormalizedLengthWeightScale; SamePathBaseWeightScale = props.SamePathBaseWeightScale; DiffPathBaseWeightScale = props.DiffPathBaseWeightScale; SamePathDepthWeightScale = props.SamePathDepthWeightScale; DiffPathDepthWeightScale = props.DiffPathDepthWeightScale; SamePathNormalizedDepthWeightScale = props.SamePathNormalizedDepthWeightScale; DiffPathNormalizedDepthWeightScale = props.DiffPathNormalizedDepthWeightScale; } internal BranchPathMultiSimulationProperties Copy() { BranchPathMultiSimulationProperties branchPathMultiSimulationProperties = new BranchPathMultiSimulationProperties(); branchPathMultiSimulationProperties.CopyFrom(this); return branchPathMultiSimulationProperties; } } [Serializable] public class LineRandomizerProperties { internal const string UseLineRandomizerTooltip = "If enabled, every archetype in LineRandomizerArchetypes will have the last LineRandomizerTakeCount tilesets replaced by a randomly selected set of tilesets from LineRandomizerTileSets. This applies for both archetype's TileSets and BranchCapTileSets.\n\nThis is designed for the scenario where dungeon generation takes a long time due to the combination of too many tiles and/or doorways in those tiles. This can reduce dungeon generation time while keeping some of the randomness of dungeon generation.\n\nAs stated previously, this WILL replace the last LineRandomizerTakeCount tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced."; internal const string ArchetypesTooltip = "The archetypes whose tilesets will be replaced.\n\nThese archetypes should ideally used in the Lines section of DungeonFlow, but it's a free country."; internal const string TileSetsTooltip = "The tilesets that will be used for replacement."; internal const string TileSetsTakeCountTooltip = "The amount of tilesets that will be replaced from the archetypes, starting from the last element to the first element.\n\nAs stated previously, this WILL replace the tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced."; [Tooltip("If enabled, every archetype in LineRandomizerArchetypes will have the last LineRandomizerTakeCount tilesets replaced by a randomly selected set of tilesets from LineRandomizerTileSets. This applies for both archetype's TileSets and BranchCapTileSets.\n\nThis is designed for the scenario where dungeon generation takes a long time due to the combination of too many tiles and/or doorways in those tiles. This can reduce dungeon generation time while keeping some of the randomness of dungeon generation.\n\nAs stated previously, this WILL replace the last LineRandomizerTakeCount tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")] public bool UseLineRandomizer = false; [Tooltip("The archetypes whose tilesets will be replaced.\n\nThese archetypes should ideally used in the Lines section of DungeonFlow, but it's a free country.")] public List Archetypes = new List(); [Tooltip("The tilesets that will be used for replacement.")] public List TileSets = new List(); [Tooltip("The amount of tilesets that will be replaced from the archetypes, starting from the last element to the first element.\n\nAs stated previously, this WILL replace the tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")] public int TileSetsTakeCount = 3; internal void CopyFrom(LineRandomizerProperties props) { UseLineRandomizer = props.UseLineRandomizer; Archetypes = props.Archetypes; TileSets = props.TileSets; } internal LineRandomizerProperties Copy() { LineRandomizerProperties lineRandomizerProperties = new LineRandomizerProperties(); lineRandomizerProperties.CopyFrom(this); return lineRandomizerProperties; } } [Serializable] public class MiscellaneousProperties { internal const string UseMaxShadowsRequestUpdateTooltip = "If enabled, updates the MaxShadowsRequest to MaxShadowsRequestAmount when your dungeon loads.\n\nThis is designed for the scenario where your dungeon, for whatever reason, has too many lights nearby and causes the annoying 'Max shadow requests count reached' warning to spam the logs."; internal const string MaxShadowsRequestCountTooltip = "The amount of MaxShadowsRequest.\n\n4 is the game's default value. I find 8 to be more than acceptable."; internal const string UseDoorwaySistersTooltip = "If enabled, the DoorwaySisters component will become active.\n\nThe component prevents an intersecting doorway from generating if it's 'sister' doorway already generated and both doorways would lead to the same neighboring tile.\n\nThis is designed for the scenario where, two neighboring doorways would lead to the same tile, one doorway is a locked door and the other is an open doorway. This would defeat the purpose of the locked door, and such as, this feature exists if needed.\n\nThis feature slows down dungeon generation slightly when enabled."; internal const string UseRandomGuaranteedScrapSpawnTooltip = "If enabled, the RandomGuaranteedScrapSpawn component will be come active.\n\nThe component allows random scrap of a specified minimum value to always be spawned on a specific point."; [Tooltip("If enabled, updates the MaxShadowsRequest to MaxShadowsRequestAmount when your dungeon loads.\n\nThis is designed for the scenario where your dungeon, for whatever reason, has too many lights nearby and causes the annoying 'Max shadow requests count reached' warning to spam the logs.")] public bool UseMaxShadowsRequestUpdate = false; [Tooltip("The amount of MaxShadowsRequest.\n\n4 is the game's default value. I find 8 to be more than acceptable.")] public int MaxShadowsRequestCount = 8; [Tooltip("If enabled, the DoorwaySisters component will become active.\n\nThe component prevents an intersecting doorway from generating if it's 'sister' doorway already generated and both doorways would lead to the same neighboring tile.\n\nThis is designed for the scenario where, two neighboring doorways would lead to the same tile, one doorway is a locked door and the other is an open doorway. This would defeat the purpose of the locked door, and such as, this feature exists if needed.\n\nThis feature slows down dungeon generation slightly when enabled.")] public bool UseDoorwaySisters = false; [Tooltip("If enabled, the RandomGuaranteedScrapSpawn component will be come active.\n\nThe component allows random scrap of a specified minimum value to always be spawned on a specific point.")] public bool UseRandomGuaranteedScrapSpawn = false; internal void CopyFrom(MiscellaneousProperties props) { UseMaxShadowsRequestUpdate = props.UseMaxShadowsRequestUpdate; MaxShadowsRequestCount = props.MaxShadowsRequestCount; UseDoorwaySisters = props.UseDoorwaySisters; UseRandomGuaranteedScrapSpawn = props.UseRandomGuaranteedScrapSpawn; } internal MiscellaneousProperties Copy() { MiscellaneousProperties miscellaneousProperties = new MiscellaneousProperties(); miscellaneousProperties.CopyFrom(this); return miscellaneousProperties; } } public struct EventCallbackScenario { public bool IsDevDebug; public EventCallbackScenario(bool isDevDebug) { IsDevDebug = isDevDebug; } } public class ExtenderEvent { public delegate void ParameterEvent(T param1, EventCallbackScenario param2); internal event ParameterEvent onParameterEvent; public void Invoke(T param1, EventCallbackScenario param2) { this.onParameterEvent?.Invoke(param1, param2); } public void AddListener(ParameterEvent listener) { onParameterEvent += listener; } public void RemoveListener(ParameterEvent listener) { onParameterEvent -= listener; } } public class ExtenderModifier { public delegate void ParameterEvent(ref T param1, U param2, EventCallbackScenario param3); internal event ParameterEvent onParameterEvent; public void Invoke(ref T param1, U param2, EventCallbackScenario param3) { this.onParameterEvent?.Invoke(ref param1, param2, param3); } public void AddListener(ParameterEvent listener) { onParameterEvent += listener; } public void RemoveListener(ParameterEvent listener) { onParameterEvent -= listener; } } [Serializable] public class ForcedTileSetList { internal const string TileSetsTooltip = "List of tiles to be forcefully spawned."; internal const string DepthWeightScaleTooltip = "The weight based on the path's depth."; internal const string MainPathWeightTooltip = "The weight for the tile spawning on the main path."; internal const string BranchPathWeightTooltip = "The weight for the tile spawning on the branch path."; [Tooltip("List of tiles to be forcefully spawned.")] public List TileSets = new List(); [Tooltip("The weight based on the path's depth.")] public AnimationCurve DepthWeightScale = new AnimationCurve(); [Tooltip("The weight for the tile spawning on the main path.")] public float MainPathWeight = 1f; [Tooltip("The weight for the tile spawning on the branch path.")] public float BranchPathWeight = 1f; } [Serializable] public class AdditionalTileSetList { internal const string TileSetsTooltip = "List of tiles to be generated."; internal const string DepthWeightScaleTooltip = "The weight based on the path's depth."; internal const string MainPathWeightTooltip = "The weight for the tile spawning on the main path."; internal const string BranchPathWeightTooltip = "The weight for the tile spawning on the branch path."; [Tooltip("List of tiles to be generated.")] public List TileSets = new List(); [Tooltip("The weight based on the path's depth.")] public AnimationCurve DepthWeightScale = new AnimationCurve(); [Tooltip("The weight for the tile spawning on the main path.")] public float MainPathWeight = 1f; [Tooltip("The weight for the tile spawning on the branch path.")] public float BranchPathWeight = 1f; public static implicit operator AdditionalTileSetList(ForcedTileSetList item) { AdditionalTileSetList additionalTileSetList = new AdditionalTileSetList(); additionalTileSetList.TileSets = item.TileSets; additionalTileSetList.DepthWeightScale = item.DepthWeightScale; additionalTileSetList.MainPathWeight = item.MainPathWeight; additionalTileSetList.BranchPathWeight = item.BranchPathWeight; return additionalTileSetList; } } [Serializable] public class LocalGlobalPropSettings { internal const string GlobalPropLimitTooltip = "If true, when PostProcess reaches the local limit of Global Props for all main paths but does not reach the global limit, use the remaining props in this main path to reach the global limit."; public int ID; [Space] public IntRange Count; [Tooltip("If true, when PostProcess reaches the local limit of Global Props for all main paths but does not reach the global limit, use the remaining props in this main path to reach the global limit.")] public bool UseToReachGlobalPropLimit; public LocalGlobalPropSettings(int id, IntRange count, bool useToReachGlobalPropLimit = false) { ID = id; Count = count; UseToReachGlobalPropLimit = useToReachGlobalPropLimit; } } [Serializable] public class NodeArchetype { internal const string LabelTooltip = "The normal node with this label will gain a randomly chosen archetype.\n\nIf empty, this becomes the default choice for any normal node without a NodeArchetype specified in this list."; internal const string ArchetypesTooltip = "The list of archetypes. One will be randomly chosen."; [Tooltip("The normal node with this label will gain a randomly chosen archetype.\n\nIf empty, this becomes the default choice for any normal node without a NodeArchetype specified in this list.")] public string Label; [Tooltip("The list of archetypes. One will be randomly chosen.")] public List Archetypes = new List(); } internal struct NullObject where T : Object { public T Item; private bool isNull; public NullObject(T item, bool isNull) { Item = item; this.isNull = isNull; } public NullObject(T item) : this(item, (Object)(object)item == (Object)null) { } public static implicit operator T(NullObject nullObject) { return nullObject.Item; } public static implicit operator NullObject(T item) { return new NullObject(item); } public override string ToString() { return ((Object)(object)Item != (Object)null) ? ((Object)Item).name : "NULL"; } public override bool Equals(object obj) { if (obj == null) { return isNull; } if (!(obj is NullObject nullObject)) { return false; } if (isNull) { return nullObject.isNull; } if (nullObject.isNull) { return false; } return ((object)Item).Equals((object?)nullObject.Item); } public override int GetHashCode() { if (isNull) { return 0; } int num = ((object)Item).GetHashCode(); if (num >= 0) { num++; } return num; } } internal class TileExtenderProxy { public TileProxy TileProxy { get; internal set; } public TileExtender PrefabTileExtender { get; internal set; } public List Entrances { get; internal set; } public List Exits { get; internal set; } public List OverlappingDoorways { get; internal set; } public bool EntranceExitInterchangable { get; internal set; } public TileExtenderProxy(TileProxy tileProxy, TileExtenderProxy existingTileExtenderProxy) { TileProxy = tileProxy; PrefabTileExtender = existingTileExtenderProxy.PrefabTileExtender; Entrances = new List(); Exits = new List(); OverlappingDoorways = new List(); EntranceExitInterchangable = existingTileExtenderProxy.EntranceExitInterchangable; TileProxy tileProxy2 = existingTileExtenderProxy.TileProxy; for (int i = 0; i < tileProxy.doorways.Count; i++) { DoorwayProxy item = tileProxy.doorways[i]; DoorwayProxy item2 = tileProxy2.doorways[i]; if (existingTileExtenderProxy.Entrances.Contains(item2)) { Entrances.Add(item); } if (existingTileExtenderProxy.Exits.Contains(item2)) { Exits.Add(item); } if (existingTileExtenderProxy.OverlappingDoorways.Contains(item2)) { OverlappingDoorways.Add(item); } } } public TileExtenderProxy(TileProxy tileProxy) { TileProxy = tileProxy; PrefabTileExtender = tileProxy.Prefab.GetComponent(); Entrances = new List(); Exits = new List(); OverlappingDoorways = new List(); if ((Object)(object)PrefabTileExtender == (Object)null) { if (tileProxy.Entrances != null) { Entrances.AddRange(tileProxy.Entrances); } if (tileProxy.Exits != null) { Exits.AddRange(tileProxy.Exits); } EntranceExitInterchangable = false; return; } foreach (DoorwayProxy doorway in tileProxy.doorways) { if (PrefabTileExtender.entrances.Contains(doorway.DoorwayComponent)) { Entrances.Add(doorway); } if (PrefabTileExtender.exits.Contains(doorway.DoorwayComponent)) { Exits.Add(doorway); } if (PrefabTileExtender.overlappingDoorways.Contains(doorway.DoorwayComponent)) { OverlappingDoorways.Add(doorway); } } EntranceExitInterchangable = PrefabTileExtender.entranctExitInterchangable; } } [Serializable] public class DunGenExtenderProperties { public enum CopyNodeBehaviour { CopyFromMainPathPosition, CopyFromNodeList } public MainPathProperties MainPathProperties = new MainPathProperties(); public DungeonBoundsProperties DungeonBoundsProperties = new DungeonBoundsProperties(); public NormalNodeArchetypesProperties NormalNodeArchetypesProperties = new NormalNodeArchetypesProperties(); public AdditionalTilesProperties AdditionalTilesProperties = new AdditionalTilesProperties(); [HideInInspector] [Obsolete("Variable field renamed to AdditionalTilesProperties. This field will be removed in future updates.")] public ForcedTilesProperties ForcedTilesProperties = new ForcedTilesProperties(); public BranchPathMultiSimulationProperties BranchPathMultiSimulationProperties = new BranchPathMultiSimulationProperties(); public LineRandomizerProperties LineRandomizerProperties = new LineRandomizerProperties(); public MiscellaneousProperties MiscellaneousProperties = new MiscellaneousProperties(); [Header("Asset Cache (FOR DEV DEBUG PURPOSES ONLY)")] public List AssetCacheTileList = new List(); public List AssetCacheTileSetList = new List(); public List AssetCacheArchetypeList = new List(); internal void CopyFrom(DunGenExtenderProperties props, string version) { MainPathProperties = props.MainPathProperties.Copy(); DungeonBoundsProperties = props.DungeonBoundsProperties.Copy(); NormalNodeArchetypesProperties = props.NormalNodeArchetypesProperties.Copy(); ForcedTilesProperties = props.ForcedTilesProperties.Copy(); AdditionalTilesProperties = props.AdditionalTilesProperties.Copy(); if (version == "0") { AdditionalTilesProperties.CopyFrom(ForcedTilesProperties); } BranchPathMultiSimulationProperties = props.BranchPathMultiSimulationProperties.Copy(); LineRandomizerProperties = props.LineRandomizerProperties.Copy(); MiscellaneousProperties = props.MiscellaneousProperties.Copy(); } internal DunGenExtenderProperties Copy(string version) { DunGenExtenderProperties dunGenExtenderProperties = new DunGenExtenderProperties(); dunGenExtenderProperties.CopyFrom(this, version); return dunGenExtenderProperties; } } } namespace DunGenPlus.Attributes { public class ReadOnlyAttribute : PropertyAttribute { } }