Decompiled source of PeakAchiever v0.4.0

plugins/Altaks.PeakAchiever.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using PeakAchiever.Controls;
using PeakAchiever.Game;
using PeakAchiever.Hud;
using PeakAchiever.Localization;
using PeakAchiever.PauseMenu;
using PeakAchiever.Pinning;
using PeakAchiever.Settings;
using PeakAchiever.Team;
using PeakAchiever.Tracking;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Localization;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Core;
using Zorro.Settings;
using Zorro.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Altaks.PeakAchiever")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0+7068c1ad71b1ca815bc08c12d8ce13a6ce5d1f75")]
[assembly: AssemblyProduct("Altaks.PeakAchiever")]
[assembly: AssemblyTitle("PeakAchiever")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Altaks/PeakAchiever")]
[assembly: InternalsVisibleTo("PeakAchiever.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

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

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

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

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

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

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

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

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

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

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

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

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

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

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

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

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

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

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace PeakAchiever
{
	[BepInPlugin("Altaks.PeakAchiever", "PeakAchiever", "0.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "Altaks.PeakAchiever";

		internal static ManualLogSource Log { get; private set; }

		internal static PinnedBadgesStore Pins { get; private set; }

		internal static PinnedBadgeTracker Tracker { get; private set; }

		internal static SplitHistoryStore Splits { get; private set; }

		internal static TrackerToggleKey ToggleKey { get; private set; }

		internal static TrackerHud Hud { get; private set; }

		internal static ConfigEntry<bool> ShowMarkers { get; private set; }

		public static string Name => "PeakAchiever";

		public static string Version => "0.4.0";

		private void Awake()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Pins = new PinnedBadgesStore(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			Tracker = new PinnedBadgeTracker(Pins.Board);
			Splits = new SplitHistoryStore(Paths.ConfigPath, ((BaseUnityPlugin)this).Logger);
			ToggleKey = new TrackerToggleKey(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			ShowMarkers = ((BaseUnityPlugin)this).Config.Bind<bool>("Tracker", "ShowMarkers", true, "Shows a marker over what a pinned badge's locator points at (a belltower, an antlion, the Mesa tomb).");
			GameObject val = new GameObject("PeakAchiever.Overlay");
			Object.DontDestroyOnLoad((Object)(object)val);
			Hud = val.AddComponent<TrackerHud>();
			Hud.Init(Tracker, ToggleKey);
			new Harmony("Altaks.PeakAchiever").PatchAll(typeof(Plugin).Assembly);
			if (SettingsHandler.Instance != null)
			{
				SettingsPatches.AddModSettings(SettingsHandler.Instance);
			}
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}
	}
}
namespace PeakAchiever.Tracking
{
	internal sealed class BadgeCompatibility
	{
		public static readonly BadgeCompatibility Unconstrained = new BadgeCompatibility(Array.Empty<IReadOnlyCollection<BiomeType>>());

		private readonly IReadOnlyList<IReadOnlyCollection<BiomeType>> _maps;

		private readonly HashSet<BiomeType> _listedBiomes;

		public BadgeCompatibility(IReadOnlyList<IReadOnlyCollection<BiomeType>> maps)
		{
			_maps = maps;
			_listedBiomes = maps.SelectMany((IReadOnlyCollection<BiomeType> map) => map).ToHashSet();
		}

		public bool CanShareARun(ACHIEVEMENTTYPE first, ACHIEVEMENTTYPE second)
		{
			//IL_0017: 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)
			if (_maps.Count == 0)
			{
				return true;
			}
			IReadOnlyCollection<BiomeType>[] requirements = ProvenRequirements(first).Concat(ProvenRequirements(second)).ToArray();
			return _maps.Any((IReadOnlyCollection<BiomeType> map) => requirements.All((IReadOnlyCollection<BiomeType> anyOf) => anyOf.Any(((IEnumerable<BiomeType>)map).Contains<BiomeType>)));
		}

		public ACHIEVEMENTTYPE? FirstConflict(ACHIEVEMENTTYPE badge, IEnumerable<ACHIEVEMENTTYPE> pinned)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			foreach (ACHIEVEMENTTYPE item in pinned)
			{
				if (!CanShareARun(badge, item))
				{
					return item;
				}
			}
			return null;
		}

		public IReadOnlyCollection<BiomeType> MissingOn(ACHIEVEMENTTYPE badge, IReadOnlyCollection<BiomeType> map)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return (IReadOnlyCollection<BiomeType>)(((object)ProvenRequirements(badge).FirstOrDefault((IReadOnlyCollection<BiomeType> anyOf) => !anyOf.Any(((IEnumerable<BiomeType>)map).Contains<BiomeType>))) ?? ((object)Array.Empty<BiomeType>()));
		}

		private IEnumerable<IReadOnlyCollection<BiomeType>> ProvenRequirements(ACHIEVEMENTTYPE badge)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return BadgeRules.For(badge).BiomeRequirements.Where((IReadOnlyCollection<BiomeType> anyOf) => anyOf.All(_listedBiomes.Contains));
		}
	}
	internal abstract record BadgeDetail
	{
		public sealed record RunClock(float ElapsedSeconds, IReadOnlyList<ComparedSplit> Splits, float? EtaSeconds, bool EtaOverLimit) : BadgeDetail()
		{
			public bool Equals(RunClock? other)
			{
				if ((object)other != null && ElapsedSeconds.Equals(other.ElapsedSeconds) && Splits.SequenceEqual(other.Splits) && EtaSeconds.Equals(other.EtaSeconds))
				{
					return EtaOverLimit == other.EtaOverLimit;
				}
				return false;
			}

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

		public sealed record Checklist(IReadOnlyList<ChecklistItem> Items) : BadgeDetail()
		{
			public bool Equals(Checklist? other)
			{
				if ((object)other != null)
				{
					return Items.SequenceEqual(other.Items);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return Items.Count;
			}
		}

		public sealed record BiomeAhead(BiomeType Biome, int StretchesAhead) : BadgeDetail()
		{
			[CompilerGenerated]
			public void Deconstruct(out BiomeType Biome, out int StretchesAhead)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected I4, but got Unknown
				Biome = (BiomeType)(int)this.Biome;
				StretchesAhead = this.StretchesAhead;
			}
		}

		private BadgeDetail()
		{
		}
	}
	internal readonly record struct ChecklistItem(ushort ItemId, bool Eaten, bool OnMap);
	internal interface IDetailSource
	{
		BadgeDetail? Describe(RunFacts facts);
	}
	internal sealed class EatenItemsSource(RunCollection collection) : IDetailSource
	{
		private static readonly IReadOnlyCollection<ushort> NothingEaten = (IReadOnlyCollection<ushort>)(object)Array.Empty<ushort>();

		public BadgeDetail? Describe(RunFacts facts)
		{
			IReadOnlyCollection<ushort> value;
			IReadOnlyCollection<ushort> eaten = (facts.EatenItems.TryGetValue(collection, out value) ? value : NothingEaten);
			IReadOnlyList<ushort> readOnlyList2;
			if (!facts.CollectionCandidates.TryGetValue(collection, out IReadOnlyList<ushort> value2))
			{
				IReadOnlyList<ushort> readOnlyList = Array.Empty<ushort>();
				readOnlyList2 = readOnlyList;
			}
			else
			{
				readOnlyList2 = value2;
			}
			IReadOnlyList<ushort> source = readOnlyList2;
			return new BadgeDetail.Checklist(source.Select(delegate(ushort item)
			{
				bool flag = eaten.Contains(item);
				bool onMap = flag || facts.ItemsOnMap == null || facts.ItemsOnMap.Contains(item);
				return new ChecklistItem(item, flag, onMap);
			}).ToArray());
		}
	}
	internal sealed class RunClockSource(float limitSeconds) : IDetailSource
	{
		public BadgeDetail? Describe(RunFacts facts)
		{
			float? num = RunEta.Estimate(facts);
			return new BadgeDetail.RunClock(facts.SecondsSinceRunStarted, facts.BiomeSplits.Select((BiomeSplit split) => ComparedSplit.Against(split, facts.BiomeMedians)).ToArray(), num, num > limitSeconds);
		}
	}
	internal sealed class BiomeAheadSource(params BiomeType[] biomes) : IDetailSource
	{
		public BadgeDetail? Describe(RunFacts facts)
		{
			//IL_0050: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int? currentSegmentIndex = facts.CurrentSegmentIndex;
			if (currentSegmentIndex.HasValue)
			{
				int valueOrDefault = currentSegmentIndex.GetValueOrDefault();
				IReadOnlyList<BiomeType> segmentBiomes = facts.SegmentBiomes;
				int num = 0;
				for (int i = valueOrDefault; i < segmentBiomes.Count; i++)
				{
					if (i > valueOrDefault && segmentBiomes[i] != segmentBiomes[i - 1])
					{
						num++;
					}
					if (biomes.Contains(segmentBiomes[i]))
					{
						return new BadgeDetail.BiomeAhead(segmentBiomes[i], num);
					}
				}
				return null;
			}
			return null;
		}
	}
	internal enum NeedKind
	{
		All,
		OneOf
	}
	internal readonly record struct NeededItem(string ItemName, int Count = 1);
	internal sealed record BadgeNeed(NeedKind Kind, IReadOnlyList<NeededItem> Items, IReadOnlyList<NeededItem> Helps);
	internal static class BadgeNeeds
	{
		public static readonly IReadOnlyDictionary<ACHIEVEMENTTYPE, BadgeNeed> Needs;

		private static BadgeNeed All(params NeededItem[] items)
		{
			return new BadgeNeed(NeedKind.All, items, Array.Empty<NeededItem>());
		}

		private static BadgeNeed OneOf(params NeededItem[] items)
		{
			return new BadgeNeed(NeedKind.OneOf, items, Array.Empty<NeededItem>());
		}

		private static BadgeNeed HelpedBy(params NeededItem[] items)
		{
			return new BadgeNeed(NeedKind.All, Array.Empty<NeededItem>(), items);
		}

		private static NeededItem I(string itemName, int count = 1)
		{
			return new NeededItem(itemName, count);
		}

		public static BadgeNeed? For(ACHIEVEMENTTYPE badge)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!Needs.TryGetValue(badge, out BadgeNeed value))
			{
				return null;
			}
			return value;
		}

		static BadgeNeeds()
		{
			Dictionary<ACHIEVEMENTTYPE, BadgeNeed> dictionary = new Dictionary<ACHIEVEMENTTYPE, BadgeNeed>
			{
				[(ACHIEVEMENTTYPE)46] = All(I("Ancient Idol")),
				[(ACHIEVEMENTTYPE)45] = OneOf(I("Balloon", 6), I("Balloon Bunch", 2)),
				[(ACHIEVEMENTTYPE)24] = OneOf(I("Bugle"), I("Bugle of Friendship"), I("Scoutmaster's Bugle")),
				[(ACHIEVEMENTTYPE)59] = All(I("THEBOOKOFBONES")),
				[(ACHIEVEMENTTYPE)25] = HelpedBy(I("anti-rope spool"), I("rope cannon")),
				[(ACHIEVEMENTTYPE)71] = HelpedBy(I("Fortified Milk"), I("AMULET_HEALING"), I("Ancient Idol"), I("Bandages"), I("First Aid Kit")),
				[(ACHIEVEMENTTYPE)49] = All(I("Binoculars")),
				[(ACHIEVEMENTTYPE)18] = All(I("Bing Bong")),
				[(ACHIEVEMENTTYPE)8] = All(I("Piton")),
				[(ACHIEVEMENTTYPE)57] = All(I("Fortified Milk")),
				[(ACHIEVEMENTTYPE)58] = All(I("Hot Dog", 3)),
				[(ACHIEVEMENTTYPE)61] = All(I("Mandrake")),
				[(ACHIEVEMENTTYPE)47] = All(I("Scout Cannon")),
				[(ACHIEVEMENTTYPE)56] = All(I("Rescue Claw")),
				[(ACHIEVEMENTTYPE)28] = OneOf(I("Bandages"), I("First Aid Kit")),
				[(ACHIEVEMENTTYPE)70] = OneOf(I("Candlestick"), I("Faerie Lantern"), I("Portable Stove")),
				[(ACHIEVEMENTTYPE)22] = OneOf(I("Bandages"), I("First Aid Kit")),
				[(ACHIEVEMENTTYPE)66] = All(I("Glider")),
				[(ACHIEVEMENTTYPE)27] = OneOf(I("rope spool"), I("anti-rope spool"), I("rope cannon"), I("anti-rope cannon"))
			};
			NeededItem[] items = new NeededItem[1] { I("RitualDagger") };
			dictionary[(ACHIEVEMENTTYPE)69] = All(items)with
			{
				Helps = new <>z__ReadOnlySingleElementList<NeededItem>(I("Blowgun"))
			};
			dictionary[(ACHIEVEMENTTYPE)48] = HelpedBy(I("Fortified Milk"), I("AMULET_HEALING"), I("anti-rope cannon"), I("VOIDLAUNCHER"));
			NeededItem[] items2 = new NeededItem[1] { I("Bounce Fungus") };
			dictionary[(ACHIEVEMENTTYPE)60] = All(items2)with
			{
				Helps = new <>z__ReadOnlyArray<NeededItem>(new NeededItem[2]
				{
					I("Balloon"),
					I("Rescue Claw")
				})
			};
			dictionary[(ACHIEVEMENTTYPE)44] = All(I("Cactus", 5));
			dictionary[(ACHIEVEMENTTYPE)40] = OneOf(I("Bird"));
			dictionary[(ACHIEVEMENTTYPE)72] = All(I("AMULET_DOUBLEJUMP"), I("AMULET_HEALING"), I("AMULET_CLONE"), I("AMULET_INFINITESTAM"), I("Strange Gem"), I("ScoutsHonor"));
			dictionary[(ACHIEVEMENTTYPE)9] = OneOf(I("Antidote"), I("Cure-All"), I("First Aid Kit"), I("Medicinal Root"));
			dictionary[(ACHIEVEMENTTYPE)42] = All(I("Frisbee"));
			dictionary[(ACHIEVEMENTTYPE)64] = All(I("EARLYWORM"));
			Needs = dictionary;
		}
	}
	internal sealed class BadgeRule
	{
		private readonly bool _isCleanRun;

		private readonly IReadOnlyList<IBlocker> _blockers;

		private readonly IDetailSource? _detailSource;

		public IProgressMeasure? ProgressMeasure { get; }

		public bool IsCleanRun => _isCleanRun;

		public ItemTraits ForbiddenItems { get; }

		public IEnumerable<IReadOnlyCollection<BiomeType>> BiomeRequirements => from requirement in _blockers.OfType<IBiomeRequirement>()
			select requirement.AnyOf;

		private BadgeRule(IProgressMeasure? progressMeasure, bool isCleanRun, IReadOnlyList<IBlocker> blockers, ItemTraits forbiddenItems = ItemTraits.None, IDetailSource? detailSource = null)
		{
			ProgressMeasure = progressMeasure;
			_isCleanRun = isCleanRun;
			_blockers = blockers;
			ForbiddenItems = forbiddenItems;
			_detailSource = detailSource;
		}

		public static BadgeRule Counted(IProgressMeasure progressMeasure, params IBlocker[] blockers)
		{
			return new BadgeRule(progressMeasure, isCleanRun: false, blockers);
		}

		public static BadgeRule CleanRun(params IBlocker[] blockers)
		{
			return new BadgeRule(null, isCleanRun: true, blockers);
		}

		public static BadgeRule CleanRun(IProgressMeasure progressMeasure, params IBlocker[] blockers)
		{
			return new BadgeRule(progressMeasure, isCleanRun: true, blockers);
		}

		public static BadgeRule CleanRunForbidding(ItemTraits forbiddenItems, params IBlocker[] blockers)
		{
			return new BadgeRule(null, isCleanRun: true, blockers, forbiddenItems);
		}

		public static BadgeRule OneOff(params IBlocker[] blockers)
		{
			return new BadgeRule(null, isCleanRun: false, blockers);
		}

		public BadgeRule WithDetail(IDetailSource detailSource)
		{
			return new BadgeRule(ProgressMeasure, _isCleanRun, _blockers, ForbiddenItems, detailSource);
		}

		public BadgeDetail? Detail(RunFacts facts)
		{
			return _detailSource?.Describe(facts);
		}

		public TrackedStatus Evaluate(RunFacts facts, bool isUnlocked)
		{
			Progress? progress = ProgressMeasure?.Measure(facts);
			if (isUnlocked)
			{
				return new TrackedStatus.Achieved(progress);
			}
			foreach (IBlocker blocker in _blockers)
			{
				UnattainableReason unattainableReason = blocker.FindBlock(facts);
				if ((object)unattainableReason != null)
				{
					return new TrackedStatus.Unattainable(unattainableReason);
				}
			}
			if (facts.RunLost)
			{
				return new TrackedStatus.Unattainable(new UnattainableReason.ConditionBroken(BrokenCondition.RunLost));
			}
			if (!_isCleanRun)
			{
				return new TrackedStatus.Attainable(progress);
			}
			return new TrackedStatus.Holding(progress);
		}
	}
	internal static class BadgeRules
	{
		private const int RopeMetersForKnotTying = 100;

		private const int RevivesForClutch = 3;

		private const int LuggageForPlunderer = 15;

		private const int HealsForFirstAid = 20;

		private const int ClownLuggageForJester = 2;

		private const int ArrowsForArchery = 10;

		private const int MealsForCooking = 20;

		private const int MoraleBoostsForHappyCamper = 5;

		private const int PitonsForBouldering = 10;

		private const int PoisonHealedForToxicology = 200;

		private const int MetersForAscender = 5000;

		private const int MilkBlocksForCalciumIntake = 100;

		private const int DishesForGourmand = 4;

		internal static readonly Dictionary<ACHIEVEMENTTYPE, BadgeRule> Rules = new Dictionary<ACHIEVEMENTTYPE, BadgeRule>
		{
			[(ACHIEVEMENTTYPE)27] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)1, 100)),
			[(ACHIEVEMENTTYPE)14] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)2, 3)),
			[(ACHIEVEMENTTYPE)30] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)6, 15)),
			[(ACHIEVEMENTTYPE)22] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)8, 20)),
			[(ACHIEVEMENTTYPE)65] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)15, 2)),
			[(ACHIEVEMENTTYPE)71] = BadgeRule.Counted(new RunValueTarget((RUNBASEDVALUETYPE)17, 10)),
			[(ACHIEVEMENTTYPE)10] = BadgeRule.Counted(new RunCollectionTarget(RunCollection.DifferentBerriesEaten, 5)).WithDetail(new EatenItemsSource(RunCollection.DifferentBerriesEaten)),
			[(ACHIEVEMENTTYPE)55] = BadgeRule.Counted(new RunCollectionTarget(RunCollection.DifferentShroomBerriesEaten, 5)).WithDetail(new EatenItemsSource(RunCollection.DifferentShroomBerriesEaten)),
			[(ACHIEVEMENTTYPE)21] = BadgeRule.Counted(new RunCollectionTarget(RunCollection.DifferentNonToxicMushroomsEaten, 4)).WithDetail(new EatenItemsSource(RunCollection.DifferentNonToxicMushroomsEaten)),
			[(ACHIEVEMENTTYPE)20] = BadgeRule.Counted(new RunCollectionTarget(RunCollection.GourmandDishesEaten, 4)).WithDetail(new EatenItemsSource(RunCollection.GourmandDishesEaten)),
			[(ACHIEVEMENTTYPE)6] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)1, 20)),
			[(ACHIEVEMENTTYPE)7] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)2, 5)),
			[(ACHIEVEMENTTYPE)8] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)3, 10)),
			[(ACHIEVEMENTTYPE)9] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)4, 200)),
			[(ACHIEVEMENTTYPE)29] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)5, 5000)),
			[(ACHIEVEMENTTYPE)31] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)16, 8)),
			[(ACHIEVEMENTTYPE)57] = BadgeRule.Counted(new LifetimeStatTarget((STEAMSTATTYPE)24, 100)),
			[(ACHIEVEMENTTYPE)15] = BadgeRule.CleanRun(new RunValueCeiling((RUNBASEDVALUETYPE)3, 0f, BrokenCondition.TookFallDamage)),
			[(ACHIEVEMENTTYPE)19] = BadgeRule.CleanRunForbidding(ItemTraits.PackagedFood, new RunValueCeiling((RUNBASEDVALUETYPE)4, 0f, BrokenCondition.AtePackagedFood)),
			[(ACHIEVEMENTTYPE)23] = BadgeRule.CleanRun(new RunValueCeiling((RUNBASEDVALUETYPE)5, 0f, BrokenCondition.PassedOut)),
			[(ACHIEVEMENTTYPE)16] = BadgeRule.CleanRunForbidding(ItemTraits.PlacesPermanentObject, new RunValueCeiling((RUNBASEDVALUETYPE)7, 0f, BrokenCondition.PlacedPermanentItem)),
			[(ACHIEVEMENTTYPE)13] = BadgeRule.CleanRun(),
			[(ACHIEVEMENTTYPE)17] = BadgeRule.CleanRun(new RunDurationTarget(3600f), new RunDurationCeiling(3600f)).WithDetail(new RunClockSource(3600f)),
			[(ACHIEVEMENTTYPE)43] = BadgeRule.CleanRun(new RunRateTarget((RUNBASEDVALUETYPE)10, 0.1f, (STATUSTYPE)8), new BiomeOnMap((BiomeType)6), new RunValueCeiling((RUNBASEDVALUETYPE)10, 0.1f, BrokenCondition.TooMuchHeat)),
			[(ACHIEVEMENTTYPE)50] = BadgeRule.CleanRun(new RunRateTarget((RUNBASEDVALUETYPE)11, 0.2f, (STATUSTYPE)2), new BiomeOnMap((BiomeType)2), new RunValueCeiling((RUNBASEDVALUETYPE)11, 0.2f, BrokenCondition.TooMuchCold)),
			[(ACHIEVEMENTTYPE)52] = BadgeRule.CleanRun(new RunRateTarget((RUNBASEDVALUETYPE)12, 0.25f, (STATUSTYPE)10), new BiomeOnMap((BiomeType)7), new RunValueCeiling((RUNBASEDVALUETYPE)12, 0.25f, BrokenCondition.TooManySpores)),
			[(ACHIEVEMENTTYPE)68] = BadgeRule.CleanRun(new BiomeOnMap((BiomeType)8), new RunValueCeiling((RUNBASEDVALUETYPE)16, 0f, BrokenCondition.HitByTrap)),
			[(ACHIEVEMENTTYPE)2] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)0)).WithDetail(new BiomeAheadSource(default(BiomeType))),
			[(ACHIEVEMENTTYPE)3] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)1)).WithDetail(new BiomeAheadSource((BiomeType)1)),
			[(ACHIEVEMENTTYPE)4] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)2)).WithDetail(new BiomeAheadSource((BiomeType)2)),
			[(ACHIEVEMENTTYPE)41] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)6)).WithDetail(new BiomeAheadSource((BiomeType)6)),
			[(ACHIEVEMENTTYPE)51] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)7)).WithDetail(new BiomeAheadSource((BiomeType)7)),
			[(ACHIEVEMENTTYPE)62] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)8)).WithDetail(new BiomeAheadSource((BiomeType)8)),
			[(ACHIEVEMENTTYPE)5] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)3)).WithDetail(new BiomeAheadSource((BiomeType)3)),
			[(ACHIEVEMENTTYPE)49] = BadgeRule.OneOff(new InBiome((BiomeType)6)).WithDetail(new BiomeAheadSource((BiomeType)6)),
			[(ACHIEVEMENTTYPE)48] = BadgeRule.OneOff(new InBiome((BiomeType)6)).WithDetail(new BiomeAheadSource((BiomeType)6)),
			[(ACHIEVEMENTTYPE)47] = BadgeRule.OneOff(new InBiome((BiomeType)6)).WithDetail(new BiomeAheadSource((BiomeType)6)),
			[(ACHIEVEMENTTYPE)53] = BadgeRule.OneOff(new InBiome((BiomeType)7)).WithDetail(new BiomeAheadSource((BiomeType)7)),
			[(ACHIEVEMENTTYPE)63] = BadgeRule.Counted(new LitBellsTarget(5), new InBiome((BiomeType)8)),
			[(ACHIEVEMENTTYPE)24] = BadgeRule.OneOff(new InBiome((BiomeType)2, (BiomeType)6)).WithDetail(new BiomeAheadSource((BiomeType)2, (BiomeType)6)),
			[(ACHIEVEMENTTYPE)25] = BadgeRule.OneOff(new InBiome((BiomeType)1, (BiomeType)7)).WithDetail(new BiomeAheadSource((BiomeType)1, (BiomeType)7)),
			[(ACHIEVEMENTTYPE)12] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)1] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)18] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)11] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)40] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)32] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)45] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)42] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)58] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)28] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)46] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)26] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)59] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)69] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)66] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)56] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)44] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)54] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)60] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)70] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)61] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)64] = BadgeRule.OneOff(),
			[(ACHIEVEMENTTYPE)72] = BadgeRule.OneOff()
		};

		public static readonly STEAMSTATTYPE[] LifetimeStats = (from target in Rules.Values.Select((BadgeRule rule) => rule.ProgressMeasure).OfType<LifetimeStatTarget>()
			select target.Stat).ToArray();

		private static readonly BadgeRule Unproven = BadgeRule.OneOff();

		public static BadgeRule For(ACHIEVEMENTTYPE badge)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!Rules.TryGetValue(badge, out BadgeRule value))
			{
				return Unproven;
			}
			return value;
		}
	}
	internal readonly record struct BiomeSplit(BiomeType Biome, float Seconds, bool IsCurrent, bool IsWhole = true)
	{
		[CompilerGenerated]
		public void Deconstruct(out BiomeType Biome, out float Seconds, out bool IsCurrent, out bool IsWhole)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			Biome = (BiomeType)(int)this.Biome;
			Seconds = this.Seconds;
			IsCurrent = this.IsCurrent;
			IsWhole = this.IsWhole;
		}
	}
	internal readonly record struct ComparedSplit(BiomeSplit Split, float? DeltaSeconds)
	{
		public static ComparedSplit Against(BiomeSplit split, IReadOnlyDictionary<BiomeType, float> medians)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!split.IsWhole || !medians.TryGetValue(split.Biome, out var value))
			{
				return new ComparedSplit(split, null);
			}
			float num = split.Seconds - value;
			return new ComparedSplit(split, (split.IsCurrent && num <= 0f) ? ((float?)null) : new float?(num));
		}
	}
	internal static class BiomeTimeline
	{
		public static IReadOnlyList<BiomeSplit> Split(IReadOnlyList<(BiomeType Biome, float Seconds)> samples, float secondsSinceRunStarted, bool joinedMidRun)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0058: 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_0078: 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)
			List<BiomeSplit> list = new List<BiomeSplit>();
			if (samples.Count == 0)
			{
				return list;
			}
			BiomeType val = samples[0].Biome;
			float num = (joinedMidRun ? samples[0].Seconds : 0f);
			foreach (var (val2, num2) in samples)
			{
				if (val2 != val)
				{
					list.Add(new BiomeSplit(val, num2 - num, IsCurrent: false, list.Count > 0 || !joinedMidRun));
					val = val2;
					num = num2;
				}
			}
			list.Add(new BiomeSplit(val, secondsSinceRunStarted - num, IsCurrent: true, list.Count > 0 || !joinedMidRun));
			return list;
		}
	}
	internal interface IBlocker
	{
		UnattainableReason? FindBlock(RunFacts facts);
	}
	internal interface IBiomeRequirement
	{
		IReadOnlyCollection<BiomeType> AnyOf { get; }
	}
	internal sealed class BiomeOnMap(BiomeType biome) : IBlocker, IBiomeRequirement
	{
		public IReadOnlyCollection<BiomeType> AnyOf { get; } = new <>z__ReadOnlySingleElementList<BiomeType>(biome);

		public UnattainableReason? FindBlock(RunFacts facts)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			if (!facts.PresentBiomes.Contains(biome))
			{
				return new UnattainableReason.BiomeAbsent((BiomeType)(int)biome);
			}
			return null;
		}
	}
	internal sealed class InBiome(params BiomeType[] biomes) : IBlocker, IBiomeRequirement
	{
		public IReadOnlyCollection<BiomeType> AnyOf => (IReadOnlyCollection<BiomeType>)(object)biomes;

		public UnattainableReason? FindBlock(RunFacts facts)
		{
			BiomeType[] array = biomes.Where(((IEnumerable<BiomeType>)facts.PresentBiomes).Contains<BiomeType>).ToArray();
			if (array.Length == 0)
			{
				return new UnattainableReason.BiomeAbsent(biomes);
			}
			if (array.All(facts.HasLeft))
			{
				return new UnattainableReason.BiomeLeft(array);
			}
			return null;
		}
	}
	internal sealed class RunValueCeiling(RUNBASEDVALUETYPE value, float ceiling, BrokenCondition condition) : IBlocker
	{
		public UnattainableReason? FindBlock(RunFacts facts)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			if (!(facts.RunValue(value) > ceiling))
			{
				return null;
			}
			return new UnattainableReason.ConditionBroken(condition);
		}
	}
	internal sealed class RunDurationCeiling(float maxSeconds) : IBlocker
	{
		public UnattainableReason? FindBlock(RunFacts facts)
		{
			if (!(Math.Floor(facts.SecondsSinceRunStarted) > (double)maxSeconds))
			{
				return null;
			}
			return new UnattainableReason.ConditionBroken(BrokenCondition.RunTooLong);
		}
	}
	internal sealed class FoldedCards
	{
		public const float FoldDelaySeconds = 5f;

		private readonly Dictionary<ACHIEVEMENTTYPE, float> _earnedAt = new Dictionary<ACHIEVEMENTTYPE, float>();

		private readonly HashSet<ACHIEVEMENTTYPE> _seen = new HashSet<ACHIEVEMENTTYPE>();

		public IReadOnlyCollection<ACHIEVEMENTTYPE> Update(IReadOnlyList<TrackedBadge> tracked, float now)
		{
			//IL_0021: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			HashSet<ACHIEVEMENTTYPE> hashSet = new HashSet<ACHIEVEMENTTYPE>();
			foreach (TrackedBadge item in tracked)
			{
				bool flag = _seen.Add(item.Badge);
				if (!(item.Status is TrackedStatus.Achieved) || item.ForAlly || item.ForTeam)
				{
					_earnedAt.Remove(item.Badge);
					continue;
				}
				if (!_earnedAt.ContainsKey(item.Badge))
				{
					_earnedAt[item.Badge] = (flag ? (now - 5f) : now);
				}
				if (now - _earnedAt[item.Badge] >= 5f)
				{
					hashSet.Add(item.Badge);
				}
			}
			_seen.IntersectWith(tracked.Select((TrackedBadge badge) => badge.Badge));
			return hashSet;
		}
	}
	internal static class ItemRestrictions
	{
		public static ItemTraits ForbiddenBy(IEnumerable<TrackedBadge> tracked)
		{
			ItemTraits itemTraits = ItemTraits.None;
			foreach (TrackedBadge item in tracked)
			{
				if (item.Status is TrackedStatus.Holding)
				{
					itemTraits |= item.Rule.ForbiddenItems;
				}
			}
			return itemTraits;
		}
	}
	internal static class ItemSources
	{
		public static IReadOnlyCollection<ushort> Reachable(IEnumerable<ushort> direct, IReadOnlyDictionary<ushort, IReadOnlyCollection<ushort>> spawnsOnUse)
		{
			HashSet<ushort> hashSet = new HashSet<ushort>();
			Stack<ushort> stack = new Stack<ushort>(direct);
			while (stack.Count > 0)
			{
				ushort num = stack.Pop();
				if (!hashSet.Add(num) || !spawnsOnUse.TryGetValue(num, out IReadOnlyCollection<ushort> value))
				{
					continue;
				}
				foreach (ushort item in value)
				{
					stack.Push(item);
				}
			}
			return hashSet;
		}
	}
	[Flags]
	internal enum ItemTraits
	{
		None = 0,
		PackagedFood = 1,
		PlacesPermanentObject = 2
	}
	internal static class PinSuggestions
	{
		public static IReadOnlyList<ACHIEVEMENTTYPE> For(IEnumerable<ACHIEVEMENTTYPE> unearned, IReadOnlyCollection<ACHIEVEMENTTYPE> pinned, int freeSlots, IReadOnlyCollection<BiomeType> map, BadgeCompatibility compatibility)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			List<ACHIEVEMENTTYPE> list = new List<ACHIEVEMENTTYPE>();
			IEnumerable<ACHIEVEMENTTYPE> enumerable = unearned.Where((ACHIEVEMENTTYPE badge) => !pinned.Contains(badge) && compatibility.MissingOn(badge, map).Count == 0).OrderBy(Rank);
			foreach (ACHIEVEMENTTYPE item in enumerable)
			{
				if (list.Count >= freeSlots)
				{
					break;
				}
				if (!compatibility.FirstConflict(item, pinned.Concat(list)).HasValue)
				{
					list.Add(item);
				}
			}
			return list;
		}

		private static int Rank(ACHIEVEMENTTYPE badge)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			BadgeRule badgeRule = BadgeRules.For(badge);
			if (badgeRule.BiomeRequirements.Any())
			{
				return 0;
			}
			if (!badgeRule.IsCleanRun)
			{
				return 2;
			}
			return 1;
		}
	}
	internal interface IProgressMeasure
	{
		Progress Measure(RunFacts facts);
	}
	internal sealed class RunValueTarget(RUNBASEDVALUETYPE value, int target) : IProgressMeasure
	{
		public Progress Measure(RunFacts facts)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new Progress((int)facts.RunValue(value), target, ProgressScope.ThisRun);
		}
	}
	internal sealed class RunCollectionTarget(RunCollection collection, int target) : IProgressMeasure
	{
		public Progress Measure(RunFacts facts)
		{
			return new Progress(facts.CollectionCount(collection), target, ProgressScope.ThisRun);
		}
	}
	internal sealed class LitBellsTarget(int target) : IProgressMeasure
	{
		public Progress Measure(RunFacts facts)
		{
			return new Progress(facts.LitBells, target, ProgressScope.ThisRun);
		}
	}
	internal sealed class RunDurationTarget(float maxSeconds) : IProgressMeasure
	{
		public Progress Measure(RunFacts facts)
		{
			return new Progress((int)facts.SecondsSinceRunStarted, (int)maxSeconds, ProgressScope.ThisRun, ProgressUnit.Duration);
		}
	}
	internal sealed class RunRateTarget(RUNBASEDVALUETYPE value, float ceiling, STATUSTYPE affliction) : IProgressMeasure
	{
		private const float PercentPerFraction = 100f;

		public Progress Measure(RunFacts facts)
		{
			//IL_0002: 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)
			return new Progress(ToPercent(facts.RunValue(value)), ToPercent(ceiling), ProgressScope.ThisRun, ProgressUnit.Percent, affliction);
		}

		private static int ToPercent(float fraction)
		{
			return (int)Math.Round(fraction * 100f);
		}
	}
	internal sealed class LifetimeStatTarget(STEAMSTATTYPE stat, int target) : IProgressMeasure
	{
		public STEAMSTATTYPE Stat => stat;

		public Progress Measure(RunFacts facts)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new Progress(facts.LifetimeStat(stat), target, ProgressScope.Lifetime);
		}
	}
	internal enum RunCollection
	{
		DifferentBerriesEaten,
		DifferentShroomBerriesEaten,
		DifferentNonToxicMushroomsEaten,
		GourmandDishesEaten
	}
	internal static class RunCollections
	{
		public static IEnumerable<RunCollection> CountingItem(ItemTags tags, bool poisons)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			bool berry = ((Enum)tags).HasFlag((Enum)(object)(ItemTags)4);
			bool mushroom = ((Enum)tags).HasFlag((Enum)(object)(ItemTags)8);
			if (berry)
			{
				yield return RunCollection.DifferentBerriesEaten;
			}
			if (berry && mushroom)
			{
				yield return RunCollection.DifferentShroomBerriesEaten;
			}
			if (mushroom && !berry && !poisons)
			{
				yield return RunCollection.DifferentNonToxicMushroomsEaten;
			}
			if (((Enum)tags).HasFlag((Enum)(object)(ItemTags)32))
			{
				yield return RunCollection.GourmandDishesEaten;
			}
		}
	}
	internal static class RunEta
	{
		public static float? Estimate(RunFacts facts)
		{
			//IL_0054: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (facts.BiomeSplits.Count != 0)
			{
				int? currentSegmentIndex = facts.CurrentSegmentIndex;
				if (currentSegmentIndex.HasValue)
				{
					int valueOrDefault = currentSegmentIndex.GetValueOrDefault();
					BiomeSplit biomeSplit = facts.BiomeSplits[facts.BiomeSplits.Count - 1];
					if (!facts.BiomeMedians.TryGetValue(biomeSplit.Biome, out var value))
					{
						return null;
					}
					float num = facts.SecondsSinceRunStarted - biomeSplit.Seconds + Math.Max(value, biomeSplit.Seconds);
					foreach (BiomeType item in BiomesAhead(facts.SegmentBiomes, valueOrDefault))
					{
						if (!facts.BiomeMedians.TryGetValue(item, out var value2))
						{
							return null;
						}
						num += value2;
					}
					return num;
				}
			}
			return null;
		}

		private static IEnumerable<BiomeType> BiomesAhead(IReadOnlyList<BiomeType> segmentBiomes, int segment)
		{
			BiomeType val = segmentBiomes[segment];
			foreach (BiomeType biome in segmentBiomes.Skip(segment + 1))
			{
				if (biome != val)
				{
					yield return biome;
				}
				val = biome;
			}
		}
	}
	internal sealed class RunFacts
	{
		public IReadOnlyDictionary<RUNBASEDVALUETYPE, float> RunValues { get; }

		public IReadOnlyDictionary<RunCollection, IReadOnlyCollection<ushort>> EatenItems { get; }

		public IReadOnlyDictionary<RunCollection, IReadOnlyList<ushort>> CollectionCandidates { get; }

		public IReadOnlyDictionary<STEAMSTATTYPE, int> LifetimeStats { get; }

		public IReadOnlyList<BiomeType> SegmentBiomes { get; }

		public IReadOnlyCollection<BiomeType> PresentBiomes { get; }

		public int? CurrentSegmentIndex { get; }

		public float SecondsSinceRunStarted { get; }

		public IReadOnlyList<BiomeSplit> BiomeSplits { get; }

		public IReadOnlyDictionary<BiomeType, float> BiomeMedians { get; }

		public IReadOnlyCollection<ushort>? ItemsOnMap { get; }

		public bool RunLost { get; }

		public int LitBells { get; }

		public RunFacts(IReadOnlyDictionary<RUNBASEDVALUETYPE, float> runValues, IReadOnlyDictionary<RunCollection, IReadOnlyCollection<ushort>> eatenItems, IReadOnlyDictionary<RunCollection, IReadOnlyList<ushort>> collectionCandidates, IReadOnlyDictionary<STEAMSTATTYPE, int> lifetimeStats, IReadOnlyList<BiomeType> segmentBiomes, IReadOnlyCollection<BiomeType> presentBiomes, int? currentSegmentIndex, float secondsSinceRunStarted, IReadOnlyList<BiomeSplit> biomeSplits, IReadOnlyDictionary<BiomeType, float> biomeMedians, IReadOnlyCollection<ushort>? itemsOnMap, bool runLost, int litBells = 0)
		{
			RunValues = runValues;
			EatenItems = eatenItems;
			CollectionCandidates = collectionCandidates;
			LifetimeStats = lifetimeStats;
			SegmentBiomes = segmentBiomes;
			PresentBiomes = presentBiomes;
			CurrentSegmentIndex = currentSegmentIndex;
			SecondsSinceRunStarted = secondsSinceRunStarted;
			BiomeSplits = biomeSplits;
			BiomeMedians = biomeMedians;
			ItemsOnMap = itemsOnMap;
			RunLost = runLost;
			LitBells = litBells;
		}

		public float RunValue(RUNBASEDVALUETYPE type)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!RunValues.TryGetValue(type, out var value))
			{
				return 0f;
			}
			return value;
		}

		public int CollectionCount(RunCollection collection)
		{
			if (!EatenItems.TryGetValue(collection, out IReadOnlyCollection<ushort> value))
			{
				return 0;
			}
			return value.Count;
		}

		public int LifetimeStat(STEAMSTATTYPE stat)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!LifetimeStats.TryGetValue(stat, out var value))
			{
				return 0;
			}
			return value;
		}

		public bool HasLeft(BiomeType biome)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			int? currentSegmentIndex = CurrentSegmentIndex;
			if (currentSegmentIndex.HasValue)
			{
				int valueOrDefault = currentSegmentIndex.GetValueOrDefault();
				bool result = false;
				for (int i = 0; i < SegmentBiomes.Count; i++)
				{
					if (SegmentBiomes[i] == biome)
					{
						if (i >= valueOrDefault)
						{
							return false;
						}
						result = true;
					}
				}
				return result;
			}
			return false;
		}
	}
	internal readonly record struct PastSplit(Guid RunId, int Ascent, int Index, BiomeType Biome, float Seconds)
	{
		private const char FieldSeparator = ',';

		private const int FieldCount = 5;

		public string ToLine()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			return string.Join(','.ToString(), RunId.ToString(), Ascent.ToString(CultureInfo.InvariantCulture), Index.ToString(CultureInfo.InvariantCulture), ((object)Biome/*cast due to .constrained prefix*/).ToString(), Seconds.ToString("R", CultureInfo.InvariantCulture));
		}

		public static bool TryParse(string line, out PastSplit split)
		{
			//IL_005d: 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)
			split = default(PastSplit);
			string[] array = line.Split(',');
			if (array.Length != 5 || !Guid.TryParse(array[0], out var result) || !int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || !int.TryParse(array[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3) || !Enum.TryParse<BiomeType>(array[3], out BiomeType result4) || !Enum.IsDefined(typeof(BiomeType), result4) || !float.TryParse(array[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result5))
			{
				return false;
			}
			split = new PastSplit(result, result2, result3, result4, result5);
			return true;
		}

		[CompilerGenerated]
		public void Deconstruct(out Guid RunId, out int Ascent, out int Index, out BiomeType Biome, out float Seconds)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			RunId = this.RunId;
			Ascent = this.Ascent;
			Index = this.Index;
			Biome = (BiomeType)(int)this.Biome;
			Seconds = this.Seconds;
		}
	}
	internal sealed class SplitHistory
	{
		private readonly Dictionary<(Guid RunId, int Index), PastSplit> _splits = new Dictionary<(Guid, int), PastSplit>();

		public IEnumerable<PastSplit> Splits => _splits.Values;

		public IReadOnlyList<int> Ascents => (from ascent in _splits.Values.Select((PastSplit split) => split.Ascent).Distinct()
			orderby ascent
			select ascent).ToArray();

		public SplitHistory(IEnumerable<PastSplit> splits)
		{
			foreach (PastSplit split in splits)
			{
				Add(split);
			}
		}

		public bool Add(PastSplit split)
		{
			if (_splits.ContainsKey((split.RunId, split.Index)))
			{
				return false;
			}
			_splits[(split.RunId, split.Index)] = split;
			return true;
		}

		public IReadOnlyDictionary<BiomeType, float> MediansAt(int ascent)
		{
			return (from split in _splits.Values
				where split.Ascent == ascent
				group split by split.Biome).ToDictionary((IGrouping<BiomeType, PastSplit> biome) => biome.Key, (IGrouping<BiomeType, PastSplit> biome) => Median(biome.Select((PastSplit split) => split.Seconds).ToArray()));
		}

		public IReadOnlyList<BiomeStats> StatsAt(int ascent)
		{
			return (from split in _splits.Values
				where split.Ascent == ascent
				group split by split.Biome into biome
				orderby biome.Average((PastSplit split) => split.Index)
				select biome).Select(delegate(IGrouping<BiomeType, PastSplit> biome)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				float[] array = biome.Select((PastSplit split) => split.Seconds).ToArray();
				return new BiomeStats(biome.Key, array.Length, Median(array), array.Min());
			}).ToArray();
		}

		public int RemoveAscent(int ascent)
		{
			(Guid, int)[] array = (from entry in _splits
				where entry.Value.Ascent == ascent
				select entry.Key).ToArray();
			(Guid, int)[] array2 = array;
			foreach ((Guid, int) key in array2)
			{
				_splits.Remove(key);
			}
			return array.Length;
		}

		private static float Median(float[] values)
		{
			Array.Sort(values);
			int num = values.Length / 2;
			if (values.Length % 2 != 1)
			{
				return (values[num - 1] + values[num]) / 2f;
			}
			return values[num];
		}
	}
	internal readonly record struct BiomeStats(BiomeType Biome, int Times, float Median, float Best)
	{
		[CompilerGenerated]
		public void Deconstruct(out BiomeType Biome, out int Times, out float Median, out float Best)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			Biome = (BiomeType)(int)this.Biome;
			Times = this.Times;
			Median = this.Median;
			Best = this.Best;
		}
	}
	internal readonly record struct LayoutTotal(float Median, float Best);
	internal static class SplitStats
	{
		public static LayoutTotal? TotalFor(IReadOnlyCollection<BiomeType> layout, IEnumerable<IReadOnlyCollection<BiomeType>> allLayouts, IReadOnlyList<BiomeStats> stats)
		{
			if (!layout.All((BiomeType biome) => stats.Any((BiomeStats row) => row.Biome == biome)))
			{
				return null;
			}
			HashSet<BiomeType> listed = allLayouts.SelectMany((IReadOnlyCollection<BiomeType> map) => map).ToHashSet();
			BiomeStats[] source = stats.Where((BiomeStats row) => layout.Contains(row.Biome) || !listed.Contains(row.Biome)).ToArray();
			return new LayoutTotal(source.Sum((BiomeStats row) => row.Median), source.Sum((BiomeStats row) => row.Best));
		}
	}
	internal sealed class TornCards
	{
		private readonly Dictionary<ACHIEVEMENTTYPE, bool> _wasImpossible = new Dictionary<ACHIEVEMENTTYPE, bool>();

		public IReadOnlyList<ACHIEVEMENTTYPE> Update(IReadOnlyList<TrackedBadge> tracked)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			bool value;
			ACHIEVEMENTTYPE[] result = (from badge in tracked
				where badge.Status is TrackedStatus.Unattainable && _wasImpossible.TryGetValue(badge.Badge, out value) && !value
				select badge.Badge).ToArray();
			_wasImpossible.Clear();
			foreach (TrackedBadge item in tracked)
			{
				_wasImpossible[item.Badge] = item.Status is TrackedStatus.Unattainable;
			}
			return result;
		}

		public static IReadOnlyList<TrackedBadge> Arrange(IReadOnlyList<TrackedBadge> tracked, IReadOnlyList<ACHIEVEMENTTYPE> tornOrder, IReadOnlyCollection<ACHIEVEMENTTYPE> folded)
		{
			return tracked.Where((TrackedBadge badge) => !tornOrder.Contains(badge.Badge) && !folded.Contains(badge.Badge)).Concat(tracked.Where((TrackedBadge badge) => folded.Contains(badge.Badge) && !tornOrder.Contains(badge.Badge))).Concat(tornOrder.SelectMany((ACHIEVEMENTTYPE torn) => tracked.Where((TrackedBadge badge) => badge.Badge == torn)))
				.ToArray();
		}
	}
	internal readonly record struct TrackedBadge(ACHIEVEMENTTYPE Badge, BadgeRule Rule, TrackedStatus Status, BadgeDetail? Detail, bool ForAlly = false, bool ForTeam = false)
	{
		[CompilerGenerated]
		public void Deconstruct(out ACHIEVEMENTTYPE Badge, out BadgeRule Rule, out TrackedStatus Status, out BadgeDetail? Detail, out bool ForAlly, out bool ForTeam)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			Badge = (ACHIEVEMENTTYPE)(int)this.Badge;
			Rule = this.Rule;
			Status = this.Status;
			Detail = this.Detail;
			ForAlly = this.ForAlly;
			ForTeam = this.ForTeam;
		}
	}
	internal enum ProgressScope
	{
		ThisRun,
		Lifetime
	}
	internal enum ProgressUnit
	{
		Count,
		Duration,
		Percent
	}
	internal readonly record struct Progress(int Current, int Target, ProgressScope Scope, ProgressUnit Unit = ProgressUnit.Count, STATUSTYPE? Affliction = null)
	{
		public float Fraction
		{
			get
			{
				if (Target > 0)
				{
					return Math.Min(1f, (float)Current / (float)Target);
				}
				return 1f;
			}
		}

		public bool NearLimit
		{
			get
			{
				if (Unit == ProgressUnit.Percent)
				{
					return (float)Current >= 0.75f * (float)Target;
				}
				return false;
			}
		}

		private const float NearLimitShare = 0.75f;
	}
	internal abstract record TrackedStatus
	{
		public sealed record Attainable(Progress? Progress) : TrackedStatus();

		public sealed record Holding(Progress? Progress = null) : TrackedStatus();

		public sealed record Achieved(Progress? Progress) : TrackedStatus();

		public sealed record Unattainable(UnattainableReason Reason) : TrackedStatus();

		private TrackedStatus()
		{
		}
	}
	internal abstract record UnattainableReason
	{
		public sealed record BiomeAbsent(params BiomeType[] Biomes) : UnattainableReason()
		{
			public bool Equals(BiomeAbsent? other)
			{
				if ((object)other != null)
				{
					return Biomes.SequenceEqual(other.Biomes);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return Biomes.Length;
			}
		}

		public sealed record BiomeLeft(params BiomeType[] Biomes) : UnattainableReason()
		{
			public bool Equals(BiomeLeft? other)
			{
				if ((object)other != null)
				{
					return Biomes.SequenceEqual(other.Biomes);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return Biomes.Length;
			}
		}

		public sealed record ConditionBroken(BrokenCondition Condition) : UnattainableReason();

		private UnattainableReason()
		{
		}
	}
	internal enum BrokenCondition
	{
		TookFallDamage,
		AtePackagedFood,
		PassedOut,
		PlacedPermanentItem,
		RunTooLong,
		TooMuchHeat,
		TooMuchCold,
		TooManySpores,
		HitByTrap,
		RunLost
	}
}
namespace PeakAchiever.Team
{
	internal static class BadgeNames
	{
		public sealed record Parsed(IReadOnlyList<ACHIEVEMENTTYPE> Badges, IReadOnlyList<string> Unknown);

		public const char Separator = ',';

		public static string Join(IEnumerable<ACHIEVEMENTTYPE> badges)
		{
			return string.Join(','.ToString(), badges);
		}

		public static Parsed Parse(string text)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			List<ACHIEVEMENTTYPE> list = new List<ACHIEVEMENTTYPE>();
			List<string> list2 = new List<string>();
			foreach (string item in from name in text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select name.Trim())
			{
				if (!TryParse(item, out var badge))
				{
					list2.Add(item);
				}
				else if (!list.Contains(badge))
				{
					list.Add(badge);
				}
			}
			return new Parsed(list, list2);
		}

		public static bool TryParse(string name, out ACHIEVEMENTTYPE badge)
		{
			if (Enum.TryParse<ACHIEVEMENTTYPE>(name, out badge) && !int.TryParse(name, out var _) && Enum.IsDefined(typeof(ACHIEVEMENTTYPE), badge))
			{
				return (int)badge != 0;
			}
			return false;
		}
	}
	internal sealed record Scout(string Name, bool IsLocal, IReadOnlyCollection<ACHIEVEMENTTYPE>? Earned);
	internal static class Scouts
	{
		public static bool EarnedByAll(ACHIEVEMENTTYPE badge, IEnumerable<Scout> scouts)
		{
			//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)
			Scout[] array = scouts.Where((Scout scout) => scout.Earned != null).ToArray();
			if (array.Length != 0)
			{
				return array.All((Scout scout) => scout.Earned.Contains(badge));
			}
			return false;
		}

		public static IReadOnlyList<string> MissingFor(ACHIEVEMENTTYPE badge, IEnumerable<Scout> scouts)
		{
			//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)
			return (from scout in scouts
				where scout.Earned != null && !scout.Earned.Contains(badge)
				select scout.Name).ToArray();
		}
	}
	internal sealed record TeamRow(ACHIEVEMENTTYPE Badge, int EarnedBy, int Known, IReadOnlyList<string> MissingFor)
	{
		public bool NobodyHasIt => EarnedBy == 0;

		[CompilerGenerated]
		public void Deconstruct(out ACHIEVEMENTTYPE Badge, out int EarnedBy, out int Known, out IReadOnlyList<string> MissingFor)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			Badge = (ACHIEVEMENTTYPE)(int)this.Badge;
			EarnedBy = this.EarnedBy;
			Known = this.Known;
			MissingFor = this.MissingFor;
		}
	}
	internal static class TeamRanking
	{
		public static IReadOnlyList<TeamRow> Rank(IEnumerable<ACHIEVEMENTTYPE> candidates, IReadOnlyList<Scout> scouts)
		{
			Scout[] known = scouts.Where((Scout scout) => scout.Earned != null).ToArray();
			return (from row in candidates.Select(delegate(ACHIEVEMENTTYPE badge)
				{
					//IL_0000: 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)
					IReadOnlyList<string> readOnlyList = Scouts.MissingFor(badge, known);
					return new TeamRow(badge, known.Length - readOnlyList.Count, known.Length, readOnlyList);
				})
				where row.Known == 0 || row.MissingFor.Count > 0
				orderby row.MissingFor.Count descending
				select row).ToArray();
		}
	}
	internal static class TeamSync
	{
		private const string EarnedKey = "PeakAchiever.Earned";

		private const string TeamPinsKey = "PeakAchiever.TeamPins";

		private static readonly ACHIEVEMENTTYPE[] AllBadges = (from ACHIEVEMENTTYPE badge in Enum.GetValues(typeof(ACHIEVEMENTTYPE))
			where (int)badge > 0
			select badge).ToArray();

		private static readonly HashSet<string> ReportedUnknown = new HashSet<string>();

		private static string? _publishedEarned;

		private static string? _sentPins;

		private static float _sentAt;

		private const float EchoTimeoutSeconds = 5f;

		public static bool InMultiplayer
		{
			get
			{
				if (PhotonNetwork.InRoom)
				{
					return !PhotonNetwork.OfflineMode;
				}
				return false;
			}
		}

		public static bool IsHost
		{
			get
			{
				if (InMultiplayer)
				{
					return PhotonNetwork.IsMasterClient;
				}
				return false;
			}
		}

		public static IReadOnlyList<ACHIEVEMENTTYPE> TeamPins
		{
			get
			{
				if (!InMultiplayer)
				{
					return Array.Empty<ACHIEVEMENTTYPE>();
				}
				object value;
				string text = (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"PeakAchiever.TeamPins", out value) ? (value as string) : null);
				if (_sentPins != null && text != _sentPins && Time.unscaledTime < _sentAt + 5f)
				{
					return Read(_sentPins);
				}
				_sentPins = null;
				if (text != null)
				{
					return Read(text);
				}
				return Array.Empty<ACHIEVEMENTTYPE>();
			}
		}

		public static IReadOnlyList<Scout> Scouts
		{
			get
			{
				if (!InMultiplayer)
				{
					return Array.Empty<Scout>();
				}
				return PhotonNetwork.PlayerList.Select(ScoutOf).ToArray();
			}
		}

		public static void PublishEarned()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			if (!InMultiplayer)
			{
				return;
			}
			AchievementManager instance = Singleton<AchievementManager>.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				string text = BadgeNames.Join(((IEnumerable<ACHIEVEMENTTYPE>)AllBadges).Where((Func<ACHIEVEMENTTYPE, bool>)instance.IsAchievementUnlocked));
				if (!((Dictionary<object, object>)(object)PhotonNetwork.LocalPlayer.CustomProperties).ContainsKey((object)"PeakAchiever.Earned") || !(text == _publishedEarned))
				{
					PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable { [(object)"PeakAchiever.Earned"] = text }, (Hashtable)null, (WebFlags)null);
					_publishedEarned = text;
				}
			}
		}

		public static void SetTeamPins(IEnumerable<ACHIEVEMENTTYPE> pins)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if (!IsHost)
			{
				Plugin.Log.LogWarning((object)"Only the host sets the team pins; the change is left out.");
				return;
			}
			string text = BadgeNames.Join(pins);
			PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable { [(object)"PeakAchiever.TeamPins"] = text }, (Hashtable)null, (WebFlags)null);
			_sentPins = text;
			_sentAt = Time.unscaledTime;
		}

		public static void DropEarnedByAll()
		{
			if (IsHost)
			{
				IReadOnlyList<ACHIEVEMENTTYPE> teamPins = TeamPins;
				IReadOnlyList<Scout> scouts = Scouts;
				ACHIEVEMENTTYPE[] array = teamPins.Where((ACHIEVEMENTTYPE badge) => !PeakAchiever.Team.Scouts.EarnedByAll(badge, scouts)).ToArray();
				if (array.Length != teamPins.Count)
				{
					SetTeamPins(array);
				}
			}
		}

		private static Scout ScoutOf(Player player)
		{
			object value;
			IReadOnlyCollection<ACHIEVEMENTTYPE> earned = ((((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"PeakAchiever.Earned", out value) && value is string text) ? Read(text).ToHashSet() : null);
			return new Scout(player.NickName, player.IsLocal, earned);
		}

		private static IReadOnlyList<ACHIEVEMENTTYPE> Read(string text)
		{
			BadgeNames.Parsed parsed = BadgeNames.Parse(text);
			foreach (string item in parsed.Unknown.Where(ReportedUnknown.Add))
			{
				Plugin.Log.LogWarning((object)("A player shared badge '" + item + "', which this game does not know; it is left out."));
			}
			return parsed.Badges;
		}
	}
	internal static class TrackedPins
	{
		public static IReadOnlyList<(ACHIEVEMENTTYPE Badge, bool ForTeam)> Merge(IReadOnlyList<ACHIEVEMENTTYPE> team, IReadOnlyList<ACHIEVEMENTTYPE> own)
		{
			return team.Select((ACHIEVEMENTTYPE badge) => (badge: badge, ForTeam: true)).Concat(from badge in own
				where !team.Contains(badge)
				select (badge: badge, ForTeam: false)).ToArray();
		}
	}
}
namespace PeakAchiever.Settings
{
	internal sealed class MarkersSetting : CustomLocalizedOffOnSetting, IExposedSetting
	{
		private const string Category = "General";

		private const string LabelKey = "PEAKACHIEVER_MARKERS";

		private readonly ConfigEntry<bool> _entry;

		public MarkersSetting(ConfigEntry<bool> entry)
		{
			_entry = entry;
			_entry.SettingChanged += delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				((EnumSetting<OffOnMode>)this).Value = ToMode(_entry.Value);
			};
		}

		public override void Load(ISettingsSaveLoad loader)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			((EnumSetting<OffOnMode>)this).Value = ToMode(_entry.Value);
		}

		public override void Save(ISettingsSaveLoad saver)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			_entry.Value = (int)((EnumSetting<OffOnMode>)this).Value == 1;
		}

		public override void ApplyValue()
		{
		}

		public override List<LocalizedString> GetLocalizedChoices()
		{
			return null;
		}

		public string GetDisplayName()
		{
			GameTextTable.Register("PEAKACHIEVER_MARKERS", ModTextKey.SettingsMarkers);
			return "PEAKACHIEVER_MARKERS";
		}

		public string GetCategory()
		{
			return "General";
		}

		protected override OffOnMode GetDefaultValue()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return ToMode((bool)((ConfigEntryBase)_entry).DefaultValue);
		}

		private static OffOnMode ToMode(bool on)
		{
			if (on)
			{
				return (OffOnMode)1;
			}
			return (OffOnMode)0;
		}
	}
	internal sealed class PinLimitSetting : FloatSetting, IExposedSetting
	{
		private const string Category = "General";

		private const string WholeNumber = "F0";

		private readonly ConfigEntry<int> _entry;

		private readonly string _labelKey;

		private readonly ModTextKey _label;

		public PinLimitSetting(ConfigEntry<int> entry, string labelKey, ModTextKey label)
		{
			_entry = entry;
			_labelKey = labelKey;
			_label = label;
			_entry.SettingChanged += delegate
			{
				((FloatSetting)this).Value = _entry.Value;
			};
		}

		public override void Load(ISettingsSaveLoad loader)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			float2 minMaxValue = ((FloatSetting)this).GetMinMaxValue();
			((FloatSetting)this).MinValue = minMaxValue.x;
			((FloatSetting)this).MaxValue = minMaxValue.y;
			((FloatSetting)this).Value = _entry.Value;
		}

		public override void Save(ISettingsSaveLoad saver)
		{
			_entry.Value = Mathf.RoundToInt(((FloatSetting)this).Value);
		}

		public override void ApplyValue()
		{
		}

		public override float Clamp(float value)
		{
			return Mathf.Round(((FloatSetting)this).Clamp(value));
		}

		public override string Expose(float result)
		{
			return Mathf.Round(result).ToString("F0");
		}

		public string GetDisplayName()
		{
			GameTextTable.Register(_labelKey, _label);
			return _labelKey;
		}

		public string GetCategory()
		{
			return "General";
		}

		protected override float GetDefaultValue()
		{
			return (int)((ConfigEntryBase)_entry).DefaultValue;
		}

		protected override float2 GetMinMaxValue()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			AcceptableValueRange<int> val = (AcceptableValueRange<int>)(object)((ConfigEntryBase)_entry).Description.AcceptableValues;
			return new float2((float)val.MinValue, (float)val.MaxValue);
		}
	}
	[HarmonyPatch]
	internal static class SettingsPatches
	{
		private const string MaxPinsLabelKey = "PEAKACHIEVER_MAX_PINS";

		private const string MaxTeamPinsLabelKey = "PEAKACHIEVER_MAX_TEAM_PINS";

		public static void AddModSettings(SettingsHandler handler)
		{
			if (handler.GetSetting<PinLimitSetting>() == null)
			{
				handler.AddSetting((Setting)(object)new PinLimitSetting(Plugin.Pins.Capacity, "PEAKACHIEVER_MAX_PINS", ModTextKey.SettingsMaxPins));
				handler.AddSetting((Setting)(object)new PinLimitSetting(Plugin.Pins.TeamCapacity, "PEAKACHIEVER_MAX_TEAM_PINS", ModTextKey.SettingsMaxTeamPins));
				handler.AddSetting((Setting)(object)new MarkersSetting(Plugin.ShowMarkers));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void AfterSettingsBuilt(SettingsHandler __instance)
		{
			AddModSettings(__instance);
		}
	}
}
namespace PeakAchiever.Pinning
{
	internal enum PinToggleOutcome
	{
		Pinned,
		Unpinned,
		RejectedBoardFull,
		RejectedConflict
	}
	internal sealed class PinBoard
	{
		private readonly List<ACHIEVEMENTTYPE> _pins = pins.ToList();

		private readonly HashSet<ACHIEVEMENTTYPE> _forAllies;

		public IReadOnlyList<ACHIEVEMENTTYPE> Pins => _pins;

		public int Capacity { get; set; }

		public PinBoard(IEnumerable<ACHIEVEMENTTYPE> pins, int capacity, IEnumerable<ACHIEVEMENTTYPE>? pinnedForAllies = null)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			HashSet<ACHIEVEMENTTYPE> hashSet = new HashSet<ACHIEVEMENTTYPE>();
			foreach (ACHIEVEMENTTYPE item in pinnedForAllies ?? Array.Empty<ACHIEVEMENTTYPE>())
			{
				hashSet.Add(item);
			}
			_forAllies = hashSet;
			Capacity = capacity;
			base..ctor();
		}

		public bool IsPinned(ACHIEVEMENTTYPE badge)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _pins.Contains(badge);
		}

		public bool IsForAlly(ACHIEVEMENTTYPE badge)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _forAllies.Contains(badge);
		}

		public PinToggleOutcome Toggle(ACHIEVEMENTTYPE badge, bool isEarned, BadgeCompatibility compatibility)
		{
			//IL_0006: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (_pins.Remove(badge))
			{
				_forAllies.Remove(badge);
				return PinToggleOutcome.Unpinned;
			}
			if (compatibility.FirstConflict(badge, _pins).HasValue)
			{
				return PinToggleOutcome.RejectedConflict;
			}
			if (_pins.Count >= Capacity)
			{
				return PinToggleOutcome.RejectedBoardFull;
			}
			_pins.Add(badge);
			if (isEarned)
			{
				_forAllies.Add(badge);
			}
			return PinToggleOutcome.Pinned;
		}

		public bool DropEarned(Predicate<ACHIEVEMENTTYPE> isEarned)
		{
			return _pins.RemoveAll((ACHIEVEMENTTYPE badge) => isEarned(badge) && !IsForAlly(badge)) > 0;
		}
	}
	internal sealed record PinList(IReadOnlyList<ACHIEVEMENTTYPE> Pins, IReadOnlyList<ACHIEVEMENTTYPE> ForAllies, IReadOnlyList<string> Unknown)
	{
		private const char Separator = ',';

		private const char AllyMark = '+';

		public unsafe static string Write(PinBoard board)
		{
			return string.Join(','.ToString(), board.Pins.Select((ACHIEVEMENTTYPE badge) => (!board.IsForAlly(badge)) ? ((object)(*(ACHIEVEMENTTYPE*)(&badge))/*cast due to .constrained prefix*/).ToString() : ("+" + ((object)(*(ACHIEVEMENTTYPE*)(&badge))/*cast due to .constrained prefix*/).ToString())));
		}

		public static PinList Read(string stored)
		{
			//IL_008e: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			List<ACHIEVEMENTTYPE> list = new List<ACHIEVEMENTTYPE>();
			List<ACHIEVEMENTTYPE> list2 = new List<ACHIEVEMENTTYPE>();
			List<string> list3 = new List<string>();
			foreach (string item in from entry in stored.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select entry.Trim())
			{
				bool flag = item.StartsWith('+'.ToString(), StringComparison.Ordinal);
				string text = item.TrimStart('+');
				if (!BadgeNames.TryParse(text, out var badge))
				{
					list3.Add(text);
				}
				else if (!list.Contains(badge))
				{
					list.Add(badge);
					if (flag)
					{
						list2.Add(badge);
					}
				}
			}
			return new PinList(list, list2, list3);
		}

		[CompilerGenerated]
		private PinList(PinList original)
		{
			Pins = original.Pins;
			ForAllies = original.ForAllies;
			Unknown = original.Unknown;
		}
	}
	internal sealed class PinnedBadgesStore
	{
		private const string Section = "Tracker";

		private const int DefaultCapacity = 5;

		private const int MaxCapacity = 12;

		private const int DefaultTeamCapacity = 5;

		private readonly ConfigEntry<string> _pins;

		private readonly ManualLogSource _log;

		public PinBoard Board { get; }

		public ConfigEntry<int> Capacity { get; }

		public ConfigEntry<int> TeamCapacity { get; }

		public PinnedBadgesStore(ConfigFile config, ManualLogSource log)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			_log = log;
			_pins = config.Bind<string>("Tracker", "PinnedBadges", "", "Badges pinned to the tracker, in order; a leading + marks one pinned while already earned, to help an ally. Edited from the pause menu badges page.");
			Capacity = config.Bind<int>("Tracker", "MaxPinnedBadges", 5, new ConfigDescription("How many badges can be pinned at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>()));
			TeamCapacity = config.Bind<int>("Tracker", "MaxTeamPins", 5, new ConfigDescription("How many badges the host can pin for the whole team in a multiplayer game, on top of their own.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>()));
			PinList pinList = PinList.Read(_pins.Value);
			foreach (string item in pinList.Unknown)
			{
				_log.LogWarning((object)("Ignoring unknown pinned badge '" + item + "' in the config."));
			}
			Board = new PinBoard(pinList.Pins, Capacity.Value, pinList.ForAllies);
			Capacity.SettingChanged += delegate
			{
				Board.Capacity = Capacity.Value;
			};
		}

		public void Save()
		{
			_pins.Value = PinList.Write(Board);
		}
	}
}
namespace PeakAchiever.PauseMenu
{
	[HarmonyPatch]
	internal static class BadgesPagePatches
	{
		private static bool IsOnPauseMenu(Component component)
		{
			return (Object)(object)component.GetComponentInParent<PauseMenuAccoladesPage>(true) != (Object)null;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BadgeUI), "Init")]
		private static void MakeBadgePinnable(BadgeUI __instance, BadgeData data)
		{
			PauseMenuAccoladesPage componentInParent = ((Component)__instance).GetComponentInParent<PauseMenuAccoladesPage>(true);
			if (!((Object)(object)data == (Object)null) && !((Object)(object)componentInParent == (Object)null))
			{
				PinnableBadge.AttachTo(__instance);
				Plugin.Hud.Stats?.Watch(componentInParent);
				Plugin.Hud.Team?.Watch(componentInParent);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void AppendPinHint(BadgeManager __instance)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			BadgeUI selectedBadge = __instance.selectedBadge;
			if ((Object)(object)selectedBadge == (Object)null || (Object)(object)selectedBadge.data == (Object)null || !IsOnPauseMenu((Component)(object)__instance))
			{
				return;
			}
			ACHIEVEMENTTYPE linkedAchievement = selectedBadge.data.linkedAchievement;
			string text;
			if (Plugin.Pins.Board.IsPinned(linkedAchievement))
			{
				text = ModText.Get(ModTextKey.HintClickToUnpin);
			}
			else
			{
				ACHIEVEMENTTYPE? val = PinnableBadge.ConflictOf(linkedAchievement);
				if (val.HasValue)
				{
					ACHIEVEMENTTYPE valueOrDefault = val.GetValueOrDefault();
					text = ModText.Format(ModTextKey.HintConflict, BadgeCatalog.Present(valueOrDefault).Name);
				}
				else
				{
					text = ModText.Get(selectedBadge.data.IsLocked ? ModTextKey.HintClickToPin : ModTextKey.HintClickToPinForAlly);
				}
			}
			if (PinnableBadge.Suggestions(__instance).Contains(linkedAchievement))
			{
				KnownMap? currentOrToday = MapCatalog.CurrentOrToday;
				if (currentOrToday.HasValue)
				{
					ModTextKey key = (currentOrToday.GetValueOrDefault().IsToday ? ModTextKey.HintSuggestedToday : ModTextKey.HintSuggestedThisMap);
					TextMeshProUGUI badgePopupDescription = __instance.badgePopupDescription;
					((TMP_Text)badgePopupDescription).text = ((TMP_Text)badgePopupDescription).text + "\n<size=85%>" + ModText.Get(key) + "</size>";
				}
			}
			IReadOnlyCollection<BiomeType> readOnlyCollection = PinnableBadge.MissingOnKnownMap(linkedAchievement);
			if (readOnlyCollection.Count > 0)
			{
				KnownMap? currentOrToday = MapCatalog.CurrentOrToday;
				if (currentOrToday.HasValue)
				{
					ModTextKey key2 = (currentOrToday.GetValueOrDefault().IsToday ? ModTextKey.HintNotOnTodaysMap : ModTextKey.HintNotOnThisMap);
					TextMeshProUGUI badgePopupDescription2 = __instance.badgePopupDescription;
					((TMP_Text)badgePopupDescription2).text = ((TMP_Text)badgePopupDescription2).text + "\n<size=85%>" + ModText.Format(key2, StatusText.BiomeNames(readOnlyCollection.ToArray())) + "</size>";
				}
			}
			TextMeshProUGUI badgePopupDescription3 = __instance.badgePopupDescription;
			((TMP_Text)badgePopupDescription3).text = ((TMP_Text)badgePopupDescription3).text + "\n<size=85%><b>" + text + "</b></size>";
		}
	}
	internal sealed class PaperKit
	{
		public const int SheetSidePadding = 56;

		public const int SheetBottomPadding = 64;

		public const int SheetTopPadding = 60;

		public const float Gap = 6f;

		private const float ColumnGap = 18f;

		private const float ButtonGap = 18f;

		private const float ScrollSensitivity = 30f;

		public const float MaxListHeight = 520f;

		private const string ModButtonPrefix = "PeakAchiever.";

		private const float DotsHeight = 7f;

		private const float RibbonSideMargin = 30f;

		private const float MinRibbonWidth = 90f;

		private const string RibbonBannerName = "Panel";

		private const string PaperSprite = "BadgePopup";

		private const string DotsSprite = "DottedLine";

		private const string TitleRibbonName = "UI_ScoutTitle";

		private static readonly Color VeilColour = new Color(0f, 0f, 0f, 0.88235295f);

		public static readonly Color PaperInk = Color32.op_Implicit(new Color32((byte)64, (byte)53, (byte)75, byte.MaxValue));

		public Image Paper { get; }

		public TMP_FontAsset Font { get; }

		public Material FontMaterial { get; }

		public Button RedRibbon { get; }

		public Button PurpleRibbon { get; }

		private Image DotsLook { get; }

		private GameObject TitleRibbonSource { get; }

		private PaperKit(Image paper, Image dots, TMP_FontAsset font, Material fontMaterial, GameObject titleRibbon, Button redRibbon, Button purpleRibbon)
		{
			Paper = paper;
			DotsLook = dots;
			Font = font;
			FontMaterial = fontMaterial;
			TitleRibbonSource = titleRibbon;
			RedRibbon = redRibbon;
			PurpleRibbon = purpleRibbon;
		}

		public static PaperKit? Read(PauseMenuAccoladesPage page, string panel)
		{
			BadgeManager componentInChildren = ((Component)page).GetComponentInChildren<BadgeManager>(true);
			GameObject val = (((Object)(object)componentInChildren == (Object)null) ? null : componentInChildren.badgePopup);
			Image[] source = (((Object)(object)val == (Object)null) ? Array.Empty<Image>() : val.GetComponentsInChildren<Image>(true));
			Image val2 = ((IEnumerable<Image>)source).FirstOrDefault((Func<Image, bool>)((Image image) => (Object)(object)image.sprite != (Object)null && ((Object)image.sprite).name == "BadgePopup" && (int)image.type == 1));
			Image val3 = ((IEnumerable<Image>)source).FirstOrDefault((Func<Image, bool>)((Image image) => (Object)(object)image.sprite != (Object)null && ((Object)image.sprite).name == "DottedLine"));
			TextMeshProUGUI val4 = (((Object)(object)componentInChildren == (Object)null) ? null : componentInChildren.badgePopupName);
			Transform val5 = ((Component)page).transform.Find("UI_ScoutTitle");
			PauseMenuControlsPage componentInChildren2 = ((Component)((Component)page).GetComponentInParent<Canvas>(true).rootCanvas).GetComponentInChildren<PauseMenuControlsPage>(true);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)componentInChildren2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)("The pause menu is missing one of the parts the " + panel + " panel is made of; the panel is left out."));
				return null;
			}
			return new PaperKit(val2, val3, ((TMP_Text)val4).font, ((TMP_Text)val4).fontSharedMaterial, ((Component)val5).gameObject, page.backButton, componentInChildren2.restoreAllButton);
		}

		public static GameObject Veil(Transform page, string name)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UiFactory.Create(name, page);
			Stretch((RectTransform)val.transform);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = VeilColour;
			((Graphic)val2).raycastTarget = true;
			return val;
		}

		public static Transform Column(Transform veil)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//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_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UiFactory.Create("Column", veil);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			VerticalLayoutGroup val5 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 18f;
			((LayoutGroup)val5).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			ContentSizeFitter val6 = val.AddComponent<ContentSizeFitter>();
			val6.horizontalFit = (FitMode)2;
			val6.verticalFit = (FitMode)2;
			return val.transform;
		}

		public Transform Sheet(Transform column, float width)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			GameObject val = UiFactory.Create("Sheet", column);
			CopyLook(Paper, val.AddComponent<Image>());
			VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(56, 56, 60, 64);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 6f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			UiFactory.SetPreferredSize(val, width, -1f);
			return val.transform;
		}

		public void Title(Transform sheet, string label)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(TitleRibbonSource, sheet);
			((Object)val).name = "Title";
			val.AddComponent<LayoutElement>().ignoreLayout = true;
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 1f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = Vector2.zero;
			SetRibbonLabel(val, label, resizeInLayout: false);
		}

		public static Button Ribbon(Button source, Transform parent, string name, string label, UnityAction onClick)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent);
			((Object)val).name = name;
			Button component = val.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(onClick);
			LocalizedText[] componentsInChildren = val.GetComponentsInChildren<LocalizedText>(true);
			foreach (LocalizedText val2 in componentsInChildren)
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
			SetRibbonLabel(val, label, resizeInLayout: true);
			return component;
		}

		public static void SetRibbonLabel(GameObject ribbon, string label, bool resizeInLayout)
		{
			//IL_0050: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e7: 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_00fe: Expected O, but got Unknown
			//IL_0105: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text componentInChildren = ribbon.GetComponentInChildren<TMP_Text>(true);
			componentInChildren.text = label;
			componentInChildren.alignment = (TextAlignmentOptions)514;
			componentInChildren.textWrappingMode = (TextWrappingModes)0;
			RectTransform rectTransform = componentInChildren.rectTransform;
			Transform obj = ribbon.transform.Find("Panel");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			rectTransform.anchorMin = (((Object)(object)val != (Object)null) ? val.anchorMin : Vector2.zero);
			rectTransform.anchorMax = (((Object)(object)val != (Object)null) ? val.anchorMax : Vector2.one);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			Vector2 val2 = (((Object)(object)val != (Object)null) ? val.offsetMin : Vector2.zero);
			Vector2 val3 = (((Object)(object)val != (Object)null) ? val.offsetMax : Vector2.zero);
			rectTransform.offsetMin = val2 + new Vector2(30f, 0f);
			rectTransform.offsetMax = val3 - new Vector2(30f, 0f);
			RectTransform val4 = (RectTransform)ribbon.transform;
			float num = Mathf.Max(90f, componentInChildren.GetPreferredValues(label).x + 60f);
			if (!resizeInLayout)
			{
				val4.sizeDelta = new Vector2(num, val4.sizeDelta.y);
				return;
			}
			LayoutElement val5 = ribbon.GetComponent<LayoutElement>();
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = ribbon.AddComponent<LayoutElement>();
			}
			if (val5.preferredHeight <= 0f)
			{
				LayoutElement obj2 = val5;
				Rect rect = val4.rect;
				obj2.preferredHeight = ((Rect)(ref rect)).height;
			}
			val5.preferredWidth = num;
		}

		public static GameObject OpenButton(PauseMenuAccoladesPage page, Transform after, string name, string labelKey, UnityAction onClick)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			Transform parent = ((Component)page.backButton).transform.parent;
			Transform val = parent.Find(name);
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)page.backButton).gameObject, parent);
			((Object)val2).name = name;
			val2.transform.SetSiblingIndex(after.GetSiblingIndex() + 1);
			Button component = val2.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(onClick);
			LocalizedText componentInChildren = val2.GetComponentInChildren<LocalizedText>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.index = labelKey;
				componentInChildren.tmp.text = LocalizedText.GetText(labelKey, true);
			}
			return val2;
		}

		public static void ArrangeButtons(PauseMenuAccoladesPage page)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00aa: 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)
			//IL_00ba: 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)
			//IL_00d6: 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)
			RectTransform back = (RectTransform)((Component)page.backButton).transform;
			RectTransform[] array = (from child in Enumerable.Range(0, ((Transform)back).parent.childCount).Select((Func<int, RectTransform>)((int i) => (RectTransform)((Transform)back).parent.GetChild(i)))
				where (Object)(object)child == (Object)(object)back || (((Object)child).name.StartsWith("PeakAchiever.", StringComparison.Ordinal) && ((Component)child).gameObject.activeSelf)
				select child).ToArray();
			float num = array.Sum(delegate(RectTransform button)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Rect rect2 = button.rect;
				return ((Rect)(ref rect2)).width;
			}) + 18f * (float)(array.Length - 1);
			float num2 = (0f - num) / 2f;
			RectTransform[] array2 = array;
			foreach (RectTransform val in array2)
			{
				float num4 = num2;
				Rect rect = val.rect;
				val.anchoredPosition = new Vector2(num4 + ((Rect)(ref rect)).width * val.pivot.x, back.anchoredPosition.y);
				float num5 = num2;
				rect = val.rect;
				num2 = num5 + (((Rect)(ref rect)).width + 18f);
			}
		}

		public static Transform ScrollList(Transform sheet, string name, float height)
		{
			//IL_0023: 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_004a: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			GameObject val = UiFactory.Create(name, sheet);
			UiFactory.SetPreferredSize(val, -1f, height);
			val.AddComponent<RectMask2D>();
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = Color.clear;
			GameObject val3 = UiFactory.Create("Content", val.transform);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = new Vector2(0f, 1f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(0.5f, 1f);
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			VerticalLayoutGroup val5 = val3.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			val3.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			ScrollRect val6 = val.AddComponent<ScrollRect>();
			val6.viewport = (RectTransform)val.transform;
			val6.content = val4;
			val6.horizontal = false;
			val6.movementType = (MovementType)2;
			val6.scrollSensitivity = 30f;
			return val3.transform;
		}

		public static void FitScrollList(Transform content, float maxHeight)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)content;
			LayoutRebuilder.ForceRebuildLayoutImmediate(val);
			float preferredHeight = LayoutUtility.GetPreferredHeight(val);
			UiFactory.SetPreferredSize(((Component)content.parent).gameObject, -1f, Mathf.Min(preferredHeight, maxHeight));
			val.anchoredPosition = Vector2.zero;
		}

		public void Dots(Transform parent)
		{
			GameObject val = UiFactory.Create("Dots", parent);
			CopyLook(DotsLook, val.AddComponent<Image>());
			UiFactory.SetPreferredSize(val, -1f, 7f);
		}

		public TMP_Text Text(Transform parent, string name, float size, Color color, TextAlignmentOptions alignment, string text = "")
		{
			//IL_0009: 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)
			TextMeshProUGUI val = UiFactory.AddText(parent, name, Font, size, color);
			((TMP_Text)val).fontSharedMaterial = FontMaterial;
			((TMP_Text)val).alignment = alignment;
			((TMP_Text)val).text = text;
			return (TMP_Text)(object)val;
		}

		public static void CopyLook(Image source, Image target)
		{
			//IL_000e: 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)
			target.sprite = source.sprite;
			target.type = source.type;
			((Graphic)target).material = ((Graphic)source).material;
			((Graphic)target).color = ((Graphic)source).color;
			target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
			((Graphic)target).raycastTarget = false;
		}

		public static Transform Row(Transform parent, string name, TextAnchor alignment)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UiFactory.Create(name, parent);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 12f;
			((LayoutGroup)val2).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			return val.transform;
		}

		public static void Stretch(RectTransform rect)
		{
			//IL_0001: 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_0017: 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)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}
	}
	internal sealed class PinnableBadge : MonoBehaviour
	{
		private const float MarkerSize = 22f;

		private const float MarkerGlyphSize = 12f;

		private static readonly Vector2 MarkerOffset = new Vector2(4f, 4f);

		private static readonly Vector2 NotOnMapOffset = new Vector2(4f, -4f);

		private static readonly Vector2 SuggestedOffset = new Vector2(-4f, 4f);

		private static int _suggestionsFrame = -1;

		private static IReadOnlyList<ACHIEVEMENTTYPE> _suggestions = Array.Empty<ACHIEVEMENTTYPE>();

		private const float ConflictAlpha = 0.35f;

		private BadgeUI _badge;

		private GameObject? _marker;

		private GameObject? _notOnMap;

		private GameObject? _suggested;

		private CanvasGroup _fade;

		public static void AttachTo(BadgeUI badge)
		{
			//IL_007b: Unknown result type