Decompiled source of Tierless v1.1.6

Tierless.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Chubrel")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyInformationalVersion("1.1.6+a5ea41028b57b7f487ed3a5c8a04bbacc60aba86")]
[assembly: AssemblyProduct("Tierless")]
[assembly: AssemblyTitle("Tierless")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tierless
{
	public readonly struct CountAndScore
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private readonly int <count>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private readonly float <score>P;

		public int Count => <count>P;

		public float Score => <score>P;

		public CountAndScore RawIncremented => new CountAndScore(<count>P + 1, <score>P);

		public CountAndScore RawDecremented => new CountAndScore(<count>P - 1, <score>P);

		public CountAndScore(int count, float score)
		{
			<count>P = count;
			<score>P = score;
		}
	}
	public class DefaultDictionary<TK, TV> : Dictionary<TK, TV>
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Func<TV> <defaultFactory>P;

		public new TV this[TK key]
		{
			get
			{
				if (!TryGetValue(key, out var value))
				{
					return <defaultFactory>P();
				}
				return value;
			}
			set
			{
				base[key] = value;
			}
		}

		public DefaultDictionary(Func<TV> defaultFactory)
		{
			<defaultFactory>P = defaultFactory;
			base..ctor();
		}
	}
	public record DefaultEnemySetupData(EnemyName Name, int Tier, params Vector2[] Parameters) : IEnemySetupData, IEqualityComparer<IEnemySetupData>
	{
		public DefaultEnemySetupData(string rawEnemyName, int tier, params Vector2[] parameters)
			: this(EnemyName.FromAnyName(rawEnemyName), tier, parameters)
		{
		}

		public static float ScoreWithPoints(Vector2 point1, Vector2 point2, float x)
		{
			//IL_0001: 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)
			//IL_000d: 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)
			return Mathf.LerpUnclamped(point1.y, point2.y, Mathf.InverseLerp(point1.x, point2.x, x));
		}

		public float ScoreWithFormula(int count)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0048: 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_0058: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			switch (Parameters.Length)
			{
			case 0:
				return 1f;
			case 1:
				return Parameters[0].y;
			default:
			{
				Vector2 val = Parameters[0];
				int num = 1;
				Vector2 point;
				do
				{
					point = val;
					val = Parameters[num];
				}
				while (!((float)count <= val.x) && ++num < Parameters.Length);
				return ScoreWithPoints(point, val, count);
			}
			}
		}

		public int EvaluateMaxCount(float score)
		{
			throw new NotImplementedException();
		}

		public static DefaultEnemySetupData Default(EnemyName enemyName, int tier)
		{
			//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_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)
			float num = Mathf.Pow(2f, (float)(tier - 1));
			return new DefaultEnemySetupData(enemyName, tier, new Vector2(1f, num), new Vector2(2f, 2f * num));
		}

		public static DefaultEnemySetupData Default(string rawEnemyName, int tier)
		{
			return Default(EnemyName.FromAnyName(rawEnemyName), tier);
		}

		public Func<EnemyName, IEnemySetupData> GetDefaultFactory(int tier)
		{
			return (EnemyName enemyName) => Default(enemyName, tier);
		}
	}
	public record DefaultLevelSetupData : ILevelSetupData
	{
		public int MinLevel { get; }

		public int MaxLevel { get; }

		public float TargetScore { get; }

		public int MinEnemyTypeCount { get; }

		public int MaxEnemyTypeCount { get; }

		public static readonly DefaultLevelSetupData Default = new DefaultLevelSetupData(0, -1, 20f, -1, -1);

		public DefaultLevelSetupData(int MinLevel, int MaxLevel, float TargetScore, int MinEnemyTypeCount, int MaxEnemyTypeCount)
		{
			this.MinLevel = MinLevel;
			this.MaxLevel = MaxLevel;
			this.TargetScore = TargetScore;
			this.MinEnemyTypeCount = MinEnemyTypeCount;
			this.MaxEnemyTypeCount = ((MaxEnemyTypeCount < 0) ? int.MaxValue : MaxEnemyTypeCount);
			base..ctor();
		}

		public bool IsForLevel(int level)
		{
			return level >= MinLevel && (MaxLevel < 0 || level <= MaxLevel);
		}

		[CompilerGenerated]
		protected DefaultLevelSetupData(DefaultLevelSetupData original)
		{
			MinLevel = original.MinLevel;
			MaxLevel = original.MaxLevel;
			TargetScore = original.TargetScore;
			MinEnemyTypeCount = original.MinEnemyTypeCount;
			MaxEnemyTypeCount = original.MaxEnemyTypeCount;
		}

		[CompilerGenerated]
		public void Deconstruct(out int MinLevel, out int MaxLevel, out float TargetScore, out int MinEnemyTypeCount, out int MaxEnemyTypeCount)
		{
			MinLevel = this.MinLevel;
			MaxLevel = this.MaxLevel;
			TargetScore = this.TargetScore;
			MinEnemyTypeCount = this.MinEnemyTypeCount;
			MaxEnemyTypeCount = this.MaxEnemyTypeCount;
		}
	}
	public class DereferencePreventer
	{
		private static DereferencePreventer? _instance;

		private readonly Dictionary<string, HashSet<object>> _preventDereference = new Dictionary<string, HashSet<object>>();

		public static DereferencePreventer Instance => _instance ?? (_instance = new DereferencePreventer());

		public bool IsGroupCreated(string group)
		{
			return _preventDereference.ContainsKey(group);
		}

		public bool DoesGroupHaveItems(string group)
		{
			_preventDereference.TryGetValue(group, out HashSet<object> value);
			return value != null && value.Count > 0;
		}

		public void Add(string group, object endangered)
		{
			_preventDereference.TryGetValue(group, out HashSet<object> value);
			if (value == null)
			{
				value = new HashSet<object>();
				_preventDereference[group] = value;
			}
			value.Add(endangered);
		}

		public bool Remove(string group, object endangered)
		{
			_preventDereference.TryGetValue(group, out HashSet<object> value);
			return value?.Remove(endangered) ?? false;
		}

		public void Clear(string group)
		{
			_preventDereference.TryGetValue(group, out HashSet<object> value);
			value?.Clear();
		}
	}
	public record EnemyData(GameObject GameObject, IEnemySetupData Data) : IEqualityComparer<EnemyData>
	{
		public bool Equals(EnemyData? x, EnemyData? y)
		{
			if ((object)x == y)
			{
				return true;
			}
			if ((object)x == null)
			{
				return false;
			}
			if ((object)y == null)
			{
				return false;
			}
			return x.GetType() == y.GetType() && x.Data.Equals(y.Data);
		}

		public int GetHashCode(EnemyData obj)
		{
			return obj.Data.GetHashCode();
		}
	}
	public class EnemyDataContext : IEqualityComparer<EnemyDataContext>
	{
		public static readonly EnemyDataContext Empty = new EnemyDataContext();

		public IDictionary<EnemyData, CountAndScore> EnemyDataCounter { get; }

		public int TypeCount { get; set; }

		public float TotalScore { get; set; }

		public EnemyDataContext(IDictionary<EnemyData, CountAndScore> enemyDataCounter, int typeCount, float totalScore)
		{
			EnemyDataCounter = enemyDataCounter;
			TypeCount = typeCount;
			TotalScore = totalScore;
			base..ctor();
		}

		public EnemyDataContext()
			: this(new Dictionary<EnemyData, CountAndScore>(), 0, 0f)
		{
		}

		public bool HasEnemy(EnemyData enemyData)
		{
			EnemyDataCounter.TryGetValue(enemyData, out var value);
			return value.Count > 0;
		}

		public CountAndScore CountAndScore(EnemyData enemyData)
		{
			EnemyDataCounter.TryGetValue(enemyData, out var value);
			return value;
		}

		public int Count(EnemyData enemyData)
		{
			return CountAndScore(enemyData).Count;
		}

		public float Score(EnemyData enemyData)
		{
			return CountAndScore(enemyData).Score;
		}

		public void JustAdd(EnemyData enemyData)
		{
			EnemyDataCounter.TryGetValue(enemyData, out var value);
			EnemyDataCounter[enemyData] = enemyData.Data.IncrementAndCountAndScore(value);
		}

		public void AddAndUpdate(EnemyData enemyData, int typeCount, float totalScore)
		{
			JustAdd(enemyData);
			UpdateCount();
			UpdateScore();
		}

		public void AddAndUpdate(EnemyData enemyData, int typeCount)
		{
			JustAdd(enemyData);
			TypeCount = typeCount;
			UpdateScore();
		}

		public void AddAndUpdate(EnemyData enemyData, float totalScore)
		{
			JustAdd(enemyData);
			UpdateCount();
			TotalScore = totalScore;
		}

		public void AddAndUpdate(EnemyData enemyData)
		{
			JustAdd(enemyData);
			UpdateCount();
			UpdateScore();
		}

		public void UpdateScore()
		{
			TotalScore = 0f;
			foreach (KeyValuePair<EnemyData, CountAndScore> item in EnemyDataCounter)
			{
				TotalScore += item.Value.Score;
			}
		}

		public void UpdateCount()
		{
			TypeCount = 0;
			foreach (KeyValuePair<EnemyData, CountAndScore> item in EnemyDataCounter)
			{
				if (item.Value.Count > 0)
				{
					TypeCount++;
				}
			}
		}

		public EnemyDataContext Copy(int typeCount, float totalScore)
		{
			return new EnemyDataContext(EnemyDataCounter.ToDictionary<KeyValuePair<EnemyData, CountAndScore>, EnemyData, CountAndScore>((KeyValuePair<EnemyData, CountAndScore> entry) => entry.Key, (KeyValuePair<EnemyData, CountAndScore> entry) => entry.Value), typeCount, totalScore);
		}

		public EnemyDataContext Copy(int typeCount)
		{
			return Copy(typeCount, TotalScore);
		}

		public EnemyDataContext Copy(float totalScore)
		{
			return Copy(TypeCount, totalScore);
		}

		public EnemyDataContext Copy()
		{
			return Copy(TypeCount, TotalScore);
		}

		public EnemyDataContext CopyAndAdd(EnemyData enemyData)
		{
			EnemyDataContext enemyDataContext = Copy();
			enemyDataContext.AddAndUpdate(enemyData);
			return enemyDataContext;
		}

		public IReadOnlyList<int> Counts()
		{
			return EnemyDataCounter.Aggregate<KeyValuePair<EnemyData, CountAndScore>, List<int>>(new List<int>(), delegate(List<int> list, KeyValuePair<EnemyData, CountAndScore> entries)
			{
				list.Add(entries.Value.Count);
				return list;
			});
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(Counts());
		}

		public bool Equals(EnemyDataContext? x, EnemyDataContext? y)
		{
			if (x == y)
			{
				return true;
			}
			if (x == null)
			{
				return false;
			}
			if (y == null)
			{
				return false;
			}
			return x.GetType() == y.GetType() && x.Counts().Equals(y.Counts());
		}

		public int GetHashCode(EnemyDataContext obj)
		{
			return HashCode.Combine(obj.EnemyDataCounter, obj.TotalScore);
		}

		public IEnumerable<EnemyData> EnemyDataEnumerable()
		{
			return EnemyDataCounter.Select<KeyValuePair<EnemyData, CountAndScore>, EnemyData>((KeyValuePair<EnemyData, CountAndScore> entry) => entry.Key);
		}
	}
	[HarmonyPatch(typeof(EnemyDirector))]
	public static class EnemyDirectorPatch
	{
		public static void AddEnemies(ICollection<EnemyData> uniqueEnemies, ICollection<GameObject> directors, int tier, IEnumerable<EnemySetup> enemySetups)
		{
			foreach (EnemySetup enemySetup in enemySetups)
			{
				foreach (GameObject spawnObject in enemySetup.spawnObjects)
				{
					string name = ((Object)spawnObject).name;
					if (!EnemyName.IsEnemyGroup(name))
					{
						EnemyName name2 = EnemyName.FromAnyName(name);
						if (EnemyName.IsEnemyDirector(name))
						{
							directors.Add(spawnObject);
							continue;
						}
						EnemyData item = new EnemyData(spawnObject, EnemySetupDataManager.Instance.GetOrDefault(name2, tier));
						uniqueEnemies.Add(item);
					}
				}
			}
		}

		public static EnemyDataContext ChooseEnemies(ICollection<EnemyData> uniqueEnemies)
		{
			if (uniqueEnemies.Count == 0)
			{
				Tierless.Instance.Logger.LogWarning((object)"No enemies were found!");
				return EnemyDataContext.Empty;
			}
			int level = RunManager.instance.levelsCompleted + 1;
			ILevelSetupData orDefault = LevelSetupDataManager.Instance.GetOrDefault(level);
			int num = orDefault.MaxEnemyTypeCountLimited(uniqueEnemies.Count) + 1;
			int num2 = (Random.RandomRangeInt(orDefault.MinEnemyTypeCount, num) + Random.RandomRangeInt(orDefault.MinEnemyTypeCount, num)) / 2;
			List<EnemyData> list = uniqueEnemies.ToList();
			ListExtension.Shuffle<EnemyData>((IList<EnemyData>)list);
			EnemyDataContext enemyDataContext = new EnemyDataContext();
			foreach (EnemyData item in list)
			{
				float num3 = enemyDataContext.TotalScore + item.Data.ScoreWithFormula(1);
				if (!(num3 > orDefault.TargetScore))
				{
					enemyDataContext.AddAndUpdate(item, enemyDataContext.TypeCount + 1, num3);
					if (enemyDataContext.TypeCount >= num2)
					{
						break;
					}
				}
			}
			bool flag;
			do
			{
				flag = false;
				foreach (EnemyData item2 in enemyDataContext.EnemyDataEnumerable())
				{
					CountAndScore countAndScore = enemyDataContext.CountAndScore(item2);
					float num4 = enemyDataContext.TotalScore - countAndScore.Score + item2.Data.ScoreWithFormula(countAndScore.Count + 1);
					if (num4 > orDefault.TargetScore)
					{
						continue;
					}
					flag = true;
					enemyDataContext.AddAndUpdate(item2, countAndScore.Count + 1, num4);
					break;
				}
			}
			while (flag);
			if (enemyDataContext.TypeCount == 0)
			{
				Tierless.Instance.Logger.LogWarning((object)"No enemies were chosen!");
			}
			return enemyDataContext;
		}

		[HarmonyPrefix]
		[HarmonyPatch("PickEnemies")]
		public static bool PickEnemies_Prefix(EnemyDirector __instance, List<EnemySetup> _enemiesList)
		{
			if (__instance.enemyListCurrent.Count != 0)
			{
				return false;
			}
			HashSet<EnemyData> uniqueEnemies = new HashSet<EnemyData>();
			List<GameObject> list = new List<GameObject>();
			AddEnemies(uniqueEnemies, list, 1, __instance.enemiesDifficulty1);
			AddEnemies(uniqueEnemies, list, 2, __instance.enemiesDifficulty2);
			AddEnemies(uniqueEnemies, list, 3, __instance.enemiesDifficulty3);
			EnemySetup val = ScriptableObject.CreateInstance<EnemySetup>();
			EnemyDataContext enemyDataContext = ChooseEnemies(uniqueEnemies);
			val.spawnObjects = enemyDataContext.EnemyDataCounter.Aggregate<KeyValuePair<EnemyData, CountAndScore>, List<GameObject>>(new List<GameObject>(), delegate(List<GameObject> result, KeyValuePair<EnemyData, CountAndScore> entry)
			{
				for (int i = 0; i < entry.Value.Count; i++)
				{
					result.Add(entry.Key.GameObject);
				}
				return result;
			});
			val.spawnObjects.AddRange(list);
			__instance.enemyList.Add(val);
			__instance.enemyListCurrent.Add(val);
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("AmountSetup")]
		public static void AmountSetup_Postfix(EnemyDirector __instance)
		{
			__instance.totalAmount = __instance.enemyListCurrent.Count;
		}
	}
	public record EnemyName(string ShortName) : IEqualityComparer<EnemyName>
	{
		public string FullName => "Enemy - " + ShortName;

		public const string FullNamePrefix = "Enemy - ";

		public const string IsEnemyGroupRegex = "((\\bEnemy\\s+Group\\s*-)|(-\\s*((\\d+.+)|(.+\\d+))))";

		public const string Director = "Director";

		public static EnemyName FromShortName(string shortName)
		{
			return new EnemyName(shortName.Trim());
		}

		public static EnemyName FromAnyName(string anyName)
		{
			int num = anyName.IndexOf('-');
			if (num == -1)
			{
				return FromShortName(anyName);
			}
			string text = anyName;
			int num2 = num + 1;
			string text2 = text.Substring(num2, text.Length - num2).TrimEnd();
			if (text2.EndsWith("Director"))
			{
				text = text2;
				num2 = "Director".Length;
				return FromShortName(text.Substring(0, text.Length - num2));
			}
			return FromShortName(text2);
		}

		public static bool IsEnemyGroup(string name)
		{
			return Regex.IsMatch(name, "((\\bEnemy\\s+Group\\s*-)|(-\\s*((\\d+.+)|(.+\\d+))))", RegexOptions.IgnoreCase);
		}

		public static bool IsEnemyDirector(string name)
		{
			return name.Contains("Director");
		}

		public override int GetHashCode()
		{
			return ShortName.GetHashCode();
		}

		public bool Equals(EnemyName? x, EnemyName? y)
		{
			if ((object)x == y)
			{
				return true;
			}
			if ((object)x == null)
			{
				return false;
			}
			if ((object)y == null)
			{
				return false;
			}
			if (x.GetType() != y.GetType())
			{
				return false;
			}
			return x.ShortName == y.ShortName;
		}

		public int GetHashCode(EnemyName obj)
		{
			return obj.ShortName.GetHashCode();
		}

		[CompilerGenerated]
		protected EnemyName(EnemyName original)
		{
			ShortName = original.ShortName;
		}
	}
	public class EnemySetupDataManager
	{
		private static EnemySetupDataManager? _instance;

		private readonly Dictionary<EnemyName, IEnemySetupData> _dataByName = new Dictionary<EnemyName, IEnemySetupData>();

		public static EnemySetupDataManager Instance => _instance ?? (_instance = new EnemySetupDataManager());

		public void Add(IEnemySetupData enemySetupData)
		{
			_dataByName[enemySetupData.Name] = enemySetupData;
		}

		public IEnemySetupData? Get(EnemyName name)
		{
			_dataByName.TryGetValue(name, out IEnemySetupData value);
			return value;
		}

		public IEnemySetupData? Get(string name)
		{
			return Get(EnemyName.FromAnyName(name));
		}

		public IEnemySetupData GetOrDefault(EnemyName name, int tier)
		{
			return Get(name) ?? GetDefault(name, tier);
		}

		public IEnemySetupData GetOrDefault(string name, int tier)
		{
			return Get(name) ?? GetDefault(name, tier);
		}

		public static IEnemySetupData GetDefault(EnemyName name, int tier)
		{
			return DefaultEnemySetupData.Default(name, tier);
		}

		public static IEnemySetupData GetDefault(string name, int tier)
		{
			return DefaultEnemySetupData.Default(name, tier);
		}

		public void InitializeDefaults()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00b8: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0101: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0593: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0658: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_0689: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			Add(new DefaultEnemySetupData("Head", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Robe", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Runner", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Hunter", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Beamer", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Slow Walker", 3, new Vector2(1f, 4f), new Vector2(4f, 20f)));
			Add(new DefaultEnemySetupData("Animal", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(16f, 20f)));
			Add(new DefaultEnemySetupData("Bowtie", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(8f, 20f)));
			Add(new DefaultEnemySetupData("Floater", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(12f, 20f)));
			Add(new DefaultEnemySetupData("Hidden", 2, new Vector2(1f, 2f), new Vector2(2f, 4f), new Vector2(8f, 20f)));
			Add(new DefaultEnemySetupData("Tumbler", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(16f, 20f)));
			Add(new DefaultEnemySetupData("Upscream", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(12f, 20f)));
			Add(new DefaultEnemySetupData("Valuable Thrower", 2, new Vector2(1f, 2f), new Vector2(3f, 4f), new Vector2(10f, 20f)));
			Add(new DefaultEnemySetupData("Bang", 2, new Vector2(1f, 2f / 3f), new Vector2(3f, 2f), new Vector2(6f, 4f), new Vector2(24f, 20f)));
			Add(new DefaultEnemySetupData("Ceiling Eye", 1, new Vector2(1f, 2f / 3f), new Vector2(3f, 4f), new Vector2(6f, 11f), new Vector2(10f, 20f)));
			Add(new DefaultEnemySetupData("Duck", 1, new Vector2(1f, 1f), new Vector2(4f, 4f), new Vector2(12f, 11f), new Vector2(24f, 20f)));
			Add(new DefaultEnemySetupData("Slow Mouth", 1, new Vector2(1f, 1f), new Vector2(4f, 4f), new Vector2(8f, 11f), new Vector2(12f, 20f)));
			Add(new DefaultEnemySetupData("Thin Man", 1, new Vector2(1f, 1f), new Vector2(4f, 4f), new Vector2(8f, 11f), new Vector2(18f, 20f)));
			Add(new DefaultEnemySetupData("Gnome", 1, new Vector2(1f, 0.5f), new Vector2(4f, 1f), new Vector2(10f, 4f), new Vector2(20f, 11f), new Vector2(40f, 20f)));
		}
	}
	public record EnemyWithDirector(GameObject? Enemy, GameObject? Director)
	{
		public bool IsReady => Enemy != null && Director != null;

		public EnemyWithDirector()
			: this(null, null)
		{
		}

		public void Set()
		{
			GameObject? director = Director;
			if (director != null)
			{
				Transform transform = director.transform;
				GameObject? enemy = Enemy;
				transform.SetParent((enemy != null) ? enemy.transform : null);
			}
		}
	}
	public interface IEnemySetupData : IEqualityComparer<IEnemySetupData>
	{
		EnemyName Name { get; }

		int Tier { get; }

		float ScoreWithFormula(int count);

		float ScoreWithFormula(CountAndScore countAndScore)
		{
			return ScoreWithFormula(countAndScore.Count);
		}

		CountAndScore CountAndScoreWithFormula(int count)
		{
			return new CountAndScore(count, ScoreWithFormula(count));
		}

		CountAndScore CountAndScoreWithFormula(CountAndScore countAndScore)
		{
			return CountAndScoreWithFormula(countAndScore.Count);
		}

		CountAndScore IncrementAndCountAndScore(CountAndScore countAndScore)
		{
			return CountAndScoreWithFormula(countAndScore.Count + 1);
		}

		CountAndScore DecrementAndCountAndScoreWithFormula(CountAndScore countAndScore)
		{
			return CountAndScoreWithFormula(countAndScore.Count - 1);
		}

		int EvaluateMaxCount(float score);

		int EvaluateMaxCount(CountAndScore countAndScore)
		{
			return EvaluateMaxCount(countAndScore.Score);
		}

		CountAndScore EvaluateMaxCountAndScore(float score)
		{
			return CountAndScoreWithFormula(EvaluateMaxCount(score));
		}

		CountAndScore EvaluateMaxCountAndScore(CountAndScore countAndScore)
		{
			return EvaluateMaxCountAndScore(countAndScore.Score);
		}

		bool IEqualityComparer<IEnemySetupData>.Equals(IEnemySetupData? x, IEnemySetupData? y)
		{
			if (x == y)
			{
				return true;
			}
			if (x == null)
			{
				return false;
			}
			if (y == null)
			{
				return false;
			}
			return x.GetType() == y.GetType() && x.Name.Equals(y.Name);
		}

		int IEqualityComparer<IEnemySetupData>.GetHashCode(IEnemySetupData obj)
		{
			return obj.Name.GetHashCode();
		}
	}
	public interface ILevelSetupData
	{
		float TargetScore { get; }

		int MinEnemyTypeCount { get; }

		int MaxEnemyTypeCount { get; }

		bool IsForLevel(int level);

		int MaxEnemyTypeCountLimited(int enemyTypeCount)
		{
			return Mathf.Min(MaxEnemyTypeCount, enemyTypeCount);
		}
	}
	public class LevelSetupDataManager
	{
		public const int StartLevelCount = 10;

		public const float StartTargetScore = 3.5f;

		public const float LastTargetScore = 20f;

		private static LevelSetupDataManager? _instance;

		private readonly IList<ILevelSetupData> _data = new List<ILevelSetupData>();

		public static LevelSetupDataManager Instance => _instance ?? (_instance = new LevelSetupDataManager());

		public void Add(ILevelSetupData data)
		{
			_data.Add(data);
		}

		public ILevelSetupData? Get(int level)
		{
			return _data.Reverse().FirstOrDefault((ILevelSetupData levelSetupData) => levelSetupData.IsForLevel(level));
		}

		public ILevelSetupData GetOrDefault(int level)
		{
			return Get(level) ?? DefaultLevelSetupData.Default;
		}

		public void InitializeDefaults()
		{
			Add(new DefaultLevelSetupData(1, 1, 3.5f, 2, 2));
			Add(new DefaultLevelSetupData(2, 2, 5f, 2, 3));
			Add(new DefaultLevelSetupData(3, 3, 6.5f, 2, 3));
			Add(new DefaultLevelSetupData(4, 4, 8f, 2, 4));
			Add(new DefaultLevelSetupData(5, 5, 9.5f, 2, 5));
			Add(new DefaultLevelSetupData(6, 6, 11f, 3, 5));
			Add(new DefaultLevelSetupData(7, 7, 12.5f, 3, 6));
			Add(new DefaultLevelSetupData(8, 8, 14f, 3, 7));
			Add(new DefaultLevelSetupData(9, 9, 16f, 2, 7));
			Add(new DefaultLevelSetupData(10, 10, 18f, 2, 8));
			Add(new DefaultLevelSetupData(11, 0, 20f, 1, -1));
		}
	}
	public record OptimizedEnemyDataContext(CountAndScore[] CountsAndScores, float TotalScore);
	public class RandomRemoveCollection<T> : IList, ICollection, IEnumerable, IList<T>, ICollection<T>, IEnumerable<T>, ISet<T>
	{
		private readonly IList<T> _list = new List<T>();

		private readonly IDictionary<T, int> _dictionary = new Dictionary<T, int>();

		public int Count => _list.Count;

		public bool IsSynchronized => false;

		public object SyncRoot
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		public T this[int index]
		{
			get
			{
				return _list[index];
			}
			set
			{
				throw new NotSupportedException("This collection does not support setting values in positions");
			}
		}

		public int this[T key] => _dictionary[key];

		public bool IsFixedSize => false;

		public bool IsReadOnly => false;

		object IList.this[int index]
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		public RandomRemoveCollection()
		{
		}

		public RandomRemoveCollection(IEnumerable<T> enumerable)
			: this()
		{
			int num = 0;
			foreach (T item in enumerable)
			{
				_list.Add(item);
				_dictionary.Add(item, num++);
			}
		}

		public IEnumerator<T> GetEnumerator()
		{
			return _list.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public void CopyTo(Array array, int index)
		{
			for (int i = index; i < _list.Count; i++)
			{
				array.SetValue(_list[i], i);
			}
		}

		public bool Remove(T item)
		{
			if (!_dictionary.TryGetValue(item, out var value))
			{
				return false;
			}
			IList<T> list = _list;
			int index = value;
			IList<T> list2 = _list;
			list[index] = list2[list2.Count - 1];
			_list.RemoveAt(_list.Count - 1);
			_dictionary.Remove(item);
			return true;
		}

		int IList.Add(object? value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value", "This collection does not support null values");
			}
			return AddNotNull(value);
		}

		private int AddNotNull(object value)
		{
			throw new NotImplementedException();
		}

		public void Add(T item)
		{
			_dictionary[item] = _dictionary.Count;
			_list.Add(item);
		}

		public void ExceptWith(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public void IntersectWith(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool IsProperSubsetOf(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool IsProperSupersetOf(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool IsSubsetOf(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool IsSupersetOf(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool Overlaps(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public bool SetEquals(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public void SymmetricExceptWith(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		public void UnionWith(IEnumerable<T> other)
		{
			throw new NotImplementedException();
		}

		bool ISet<T>.Add(T item)
		{
			throw new NotImplementedException();
		}

		void ICollection<T>.Clear()
		{
			throw new NotImplementedException();
		}

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

		public void CopyTo(T[] array, int arrayIndex)
		{
			CopyTo((Array)array, arrayIndex);
		}

		void IList.Clear()
		{
			throw new NotImplementedException();
		}

		bool IList.Contains(object? value)
		{
			throw new NotImplementedException();
		}

		public int IndexOf(object value)
		{
			throw new NotImplementedException();
		}

		public void Insert(int index, object value)
		{
			throw new NotImplementedException();
		}

		void IList.Remove(object value)
		{
			throw new NotImplementedException();
		}

		public int IndexOf(T item)
		{
			throw new NotImplementedException();
		}

		public void Insert(int index, T item)
		{
			throw new NotImplementedException();
		}

		void IList<T>.RemoveAt(int index)
		{
			throw new NotImplementedException();
		}

		void IList.RemoveAt(int index)
		{
			throw new NotImplementedException();
		}

		public int RandomIndex()
		{
			return Random.RandomRangeInt(0, Count);
		}

		public T RandomItem()
		{
			return _list[RandomIndex()];
		}

		public void Shuffle()
		{
			ListExtension.Shuffle<T>(_list);
			for (int i = 0; i < Count; i++)
			{
				_dictionary[_list[i]] = i;
			}
		}
	}
	[BepInPlugin("com.github.chubrel.Tierless", "Tierless", "1.1.6")]
	public class Tierless : BaseUnityPlugin
	{
		public const string Version = "1.1.6";

		public const string Guid = "com.github.chubrel.Tierless";

		public const string Name = "Tierless";

		public static readonly string SaveDirectorsID = FullID("SaveDirectors");

		public static Tierless Instance { get; private set; } = null;


		public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		private Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			LevelSetupDataManager.Instance.InitializeDefaults();
			EnemySetupDataManager.Instance.InitializeDefaults();
			Patch();
		}

		public void Patch()
		{
			//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_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		public void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		public static string FullID(string suffix)
		{
			return Utils.FullID("com.github.chubrel.Tierless", suffix);
		}
	}
	public static class Utils
	{
		public static string FullID(string guid, string suffix)
		{
			return guid + ":" + suffix;
		}

		public static void AppendExpression(this StringBuilder stringBuilder, Expression<Func<object>> expression)
		{
			Expression body = expression.Body;
			if (1 == 0)
			{
			}
			string text;
			if (!(body is MemberExpression memberExpression))
			{
				if (body is UnaryExpression unaryExpression)
				{
					Expression operand = unaryExpression.Operand;
					if (operand is MemberExpression memberExpression2)
					{
						text = memberExpression2.Member.Name;
						goto IL_0067;
					}
				}
				text = body.ToString();
			}
			else
			{
				text = memberExpression.Member.Name;
			}
			goto IL_0067;
			IL_0067:
			if (1 == 0)
			{
			}
			string value = text;
			object value2 = expression.Compile()();
			stringBuilder.Append(value);
			stringBuilder.Append(" = ");
			stringBuilder.Append(value2);
		}

		public static void LogExpressions(this ManualLogSource logger, string logName, params Expression<Func<object>>[] args)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(logName);
			stringBuilder.Append(" <");
			if (args.Length != 0)
			{
				stringBuilder.AppendExpression(args[0]);
				for (int i = 1; i < args.Length; i++)
				{
					stringBuilder.Append(", ");
					stringBuilder.AppendExpression(args[i]);
				}
				stringBuilder.Append(">");
			}
			logger.LogWarning((object)stringBuilder.ToString());
		}

		public static string ToStringInDetails(this object arg, int maxDepth = 3, string depthIndent = "    ", string lineSeparator = "\n")
		{
			HashSet<object> visited = new HashSet<object>();
			StringBuilder stringBuilder = new StringBuilder();
			ToStringInDetailsImplementation(arg, stringBuilder, 0, maxDepth, visited, depthIndent, lineSeparator, toIndent: true);
			return stringBuilder.ToString();
		}

		private static void ToStringInDetailsImplementation(object? arg, StringBuilder stringBuilder, int depth, int maxDepth, HashSet<object> visited, string depthIndent, string lineSeparator, bool toIndent)
		{
			StringBuilder stringBuilder2 = new StringBuilder();
			for (int i = 0; i < depth; i++)
			{
				stringBuilder2.Append(depthIndent);
			}
			if (toIndent)
			{
				stringBuilder.Append(stringBuilder2);
			}
			if (arg == null)
			{
				stringBuilder.Append("null");
				stringBuilder.Append(lineSeparator);
				return;
			}
			Type type = arg.GetType();
			if (visited.Contains(arg))
			{
				stringBuilder.Append("<Circular Reference to ");
				stringBuilder.Append(type.Name);
				stringBuilder.Append(">");
				stringBuilder.Append(lineSeparator);
				return;
			}
			if (type.IsPrimitive || arg is string || arg is DateTime || arg is decimal)
			{
				stringBuilder.Append(arg);
				stringBuilder.Append(lineSeparator);
				return;
			}
			if (depth >= maxDepth)
			{
				stringBuilder.Append("<");
				stringBuilder.Append(type.Name);
				stringBuilder.Append("...>");
				stringBuilder.Append(lineSeparator);
				return;
			}
			visited.Add(arg);
			stringBuilder.Append(type.Name);
			stringBuilder.Append(" {");
			stringBuilder.Append(lineSeparator);
			if (arg is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					ToStringInDetailsImplementation(item, stringBuilder, depth + 1, maxDepth, visited, depthIndent, lineSeparator, toIndent: true);
				}
			}
			else
			{
				PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
				foreach (PropertyInfo propertyInfo in properties)
				{
					object arg2;
					try
					{
						arg2 = propertyInfo.GetValue(arg);
					}
					catch
					{
						arg2 = "<error>";
					}
					stringBuilder.Append(stringBuilder2);
					stringBuilder.Append(propertyInfo.Name);
					stringBuilder.Append(" = ");
					ToStringInDetailsImplementation(arg2, stringBuilder, depth + 1, maxDepth, visited, depthIndent, lineSeparator, toIndent: false);
				}
			}
			stringBuilder.Append(stringBuilder2);
			stringBuilder.Append("}");
			visited.Remove(arg);
			stringBuilder.Append(lineSeparator);
		}
	}
}