Decompiled source of PeakAchiever v0.3.0
plugins/Altaks.PeakAchiever.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
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 PeakAchiever.Controls; using PeakAchiever.Game; using PeakAchiever.Hud; using PeakAchiever.Localization; using PeakAchiever.PauseMenu; using PeakAchiever.Pinning; using PeakAchiever.Team; using PeakAchiever.Tracking; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.ControllerSupport; using Zorro.Core; 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.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0+ceb35a73773b5037d5e4991e2c34d4fc3804ad8f")] [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.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [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.3.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; } public static string Name => "PeakAchiever"; public static string Version => "0.3.0"; private void Awake() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0095: 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); 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); 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; } } 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 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)), [(ACHIEVEMENTTYPE)3] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)1)), [(ACHIEVEMENTTYPE)4] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)2)), [(ACHIEVEMENTTYPE)41] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)6)), [(ACHIEVEMENTTYPE)51] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)7)), [(ACHIEVEMENTTYPE)62] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)8)), [(ACHIEVEMENTTYPE)5] = BadgeRule.OneOff(new BiomeOnMap((BiomeType)3)), [(ACHIEVEMENTTYPE)49] = BadgeRule.OneOff(new InBiome((BiomeType)6)), [(ACHIEVEMENTTYPE)48] = BadgeRule.OneOff(new InBiome((BiomeType)6)), [(ACHIEVEMENTTYPE)47] = BadgeRule.OneOff(new InBiome((BiomeType)6)), [(ACHIEVEMENTTYPE)53] = BadgeRule.OneOff(new InBiome((BiomeType)7)), [(ACHIEVEMENTTYPE)63] = BadgeRule.OneOff(new InBiome((BiomeType)8)), [(ACHIEVEMENTTYPE)24] = BadgeRule.OneOff(new InBiome((BiomeType)2, (BiomeType)6)), [(ACHIEVEMENTTYPE)25] = BadgeRule.OneOff(new InBiome((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 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 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (facts.BiomeSplits.Count == 0) { return null; } 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)) { if (!facts.BiomeMedians.TryGetValue(item, out var value2)) { return null; } num += value2; } return num; } private static IEnumerable<BiomeType> BiomesAhead(RunFacts facts) { BiomeType val = facts.SegmentBiomes[facts.CurrentSegmentIndex]; foreach (BiomeType biome in facts.SegmentBiomes.Skip(facts.CurrentSegmentIndex + 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 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) { RunValues = runValues; EatenItems = eatenItems; CollectionCandidates = collectionCandidates; LifetimeStats = lifetimeStats; SegmentBiomes = segmentBiomes; PresentBiomes = presentBiomes; CurrentSegmentIndex = currentSegmentIndex; SecondsSinceRunStarted = secondsSinceRunStarted; BiomeSplits = biomeSplits; BiomeMedians = biomeMedians; ItemsOnMap = itemsOnMap; RunLost = runLost; } 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_000d: 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) bool result = false; for (int i = 0; i < SegmentBiomes.Count; i++) { if (SegmentBiomes[i] == biome) { if (i >= CurrentSegmentIndex) { return false; } result = true; } } return result; } } 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) { return tracked.Where((TrackedBadge 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) { [CompilerGenerated] public void Deconstruct(out ACHIEVEMENTTYPE Badge, out BadgeRule Rule, out TrackedStatus Status, out BadgeDetail? Detail) { //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; } } 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; } } 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) string[] array = (from scout in known where !scout.Earned.Contains(badge) select scout.Name).ToArray(); return new TeamRow(badge, known.Length - array.Length, known.Length, array); }) 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; } } } 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 ConfigEntry<int> _capacity; private readonly ConfigEntry<int> _teamCapacity; private readonly ManualLogSource _log; public PinBoard Board { get; } public int TeamCapacity => _teamCapacity.Value; 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 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 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 (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown PinnableBadge pinnableBadge = default(PinnableBadge); if (!((Component)badge).TryGetComponent<PinnableBadge>(ref pinnableBadge)) { Button val = default(Button); if (!((Component)badge).TryGetComponent<Button>(ref val)) { Plugin.Log.LogError((object)("Badge '" + ((Object)badge).name + "' has no Button; it cannot be pinned from the pause menu.")); return; } pinnableBadge = ((Component)badge).gameObject.AddComponent<PinnableBadge>(); pinnableBadge._badge = badge; pinnableBadge._fade = (((Object)(object)badge.canvasGroup != (Object)null) ? badge.canvasGroup : ((Component)badge).gameObject.AddComponent<CanvasGroup>()); ((UnityEvent)val.onClick).AddListener(new UnityAction(pinnableBadge.TogglePin)); } pinnableBadge.ShowPinState(); } public static ACHIEVEMENTTYPE? ConflictOf(ACHIEVEMENTTYPE badge) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return MapCatalog.Compatibility.FirstConflict(badge, Plugin.Pins.Board.Pins); } public static IReadOnlyList<ACHIEVEMENTTYPE> Suggestions(BadgeManager manager) { if (_suggestionsFrame == Time.frameCount) { return _suggestions; } _suggestionsFrame = Time.frameCount; PinBoard board = Plugin.Pins.Board; KnownMap? currentOrToday = MapCatalog.CurrentOrToday; IReadOnlyList<ACHIEVEMENTTYPE> suggestions; if (currentOrToday.HasValue) { KnownMap valueOrDefault = currentOrToday.GetValueOrDefault(); suggestions = PinSuggestions.For(from data in manager.badgeData where (Object)(object)data != (Object)null && data.IsLocked && !data.secret select data.linkedAchievement, (IReadOnlyCollection<ACHIEVEMENTTYPE>)(object)board.Pins.ToArray(), board.Capacity - board.Pins.Count, valueOrDefault.Biomes, MapCatalog.Compatibility); } else { IReadOnlyList<ACHIEVEMENTTYPE> readOnlyList = Array.Empty<ACHIEVEMENTTYPE>(); suggestions = readOnlyList; } _suggestions = suggestions; return _suggestions; } public static IReadOnlyCollection<BiomeType> MissingOnKnownMap(ACHIEVEMENTTYPE badge) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) KnownMap? currentOrToday = MapCatalog.CurrentOrToday; if (currentOrToday.HasValue) { KnownMap valueOrDefault = currentOrToday.GetValueOrDefault(); return MapCatalog.Compatibility.MissingOn(badge, valueOrDefault.Biomes); } return (IReadOnlyCollection<BiomeType>)(object)Array.Empty<BiomeType>(); } private void TogglePin() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) BadgeData data = _badge.data; if ((Object)(object)data == (Object)null) { return; } PinnedBadgesStore pins = Plugin.Pins; PinToggleOutcome pinToggleOutcome = pins.Board.Toggle(data.linkedAchievement, !data.IsLocked, MapCatalog.Compatibility); switch (pinToggleOutcome) { case PinToggleOutcome.Pinned: case PinToggleOutcome.Unpinned: { pins.Save(); Plugin.Hud.RequestRefresh(); PinnableBadge[] componentsInChildren = ((Component)_badge.manager).GetComponentsInChildren<PinnableBadge>(true); foreach (PinnableBadge pinnableBadge in componentsInChildren) { pinnableBadge.ShowPinState(); } _badge.manager.selectedBadge = _badge; break; } case PinToggleOutcome.RejectedBoardFull: Plugin.Hud.ShowToast(ModText.Format(ModTextKey.RefusalBoardFull, pins.Board.Capacity)); break; case PinToggleOutcome.RejectedConflict: { ACHIEVEMENTTYPE value = ConflictOf(data.linkedAchievement).Value; Plugin.Hud.ShowToast(ModText.Format(ModTextKey.RefusalConflict, BadgeCatalog.Present(value).Name)); break; } default: throw new ArgumentOutOfRangeException("outcome", pinToggleOutcome, "Unhandled pin outcome."); } } private void ShowPinState() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) BadgeData data = _badge.data; bool flag = (Object)(object)data != (Object)null && Plugin.Pins.Board.IsPinned(data.linkedAchievement); if (flag && (Object)(object)_marker == (Object)null) { HudStyle style = Plugin.Hud.Style; if (style != null) { _marker = CreateMarker(style, "PinMarker", Vector2.one, MarkerOffset, HudStyle.ProgressFill, style.Pin); } } if ((Object)(object)_marker != (Object)null) { _marker.SetActive(flag); } bool flag2 = (Object)(object)data != (Object)null && data.IsLocked && MissingOnKnownMap(data.linkedAchievement).Count > 0; if (flag2 && (Object)(object)_notOnMap == (Object)null) { HudStyle style2 = Plugin.Hud.Style; if (style2 != null) { _notOnMap = CreateMarker(style2, "NotOnMap", new Vector2(1f, 0f), NotOnMapOffset, HudStyle.Unattainable, style2.Cross); } } if ((Object)(object)_notOnMap != (Object)null) { _notOnMap.SetActive(flag2); } bool flag3 = (Object)(object)data != (Object)null && Suggestions(_badge.manager).Contains(data.linkedAchievement); if (flag3 && (Object)(object)_suggested == (Object)null) { HudStyle style3 = Plugin.Hud.Style; if (style3 != null) { _suggested = CreateMarker(style3, "Suggested", Vector2.up, SuggestedOffset, HudStyle.ProgressFill, style3.Star); } } if ((Object)(object)_suggested != (Object)null) { _suggested.SetActive(flag3); } bool flag4 = (Object)(object)data != (Object)null && data.IsLocked && !flag && ConflictOf(data.linkedAchievement).HasValue; _fade.alpha = (flag4 ? 0.35f : 1f); } private GameObject CreateMarker(HudStyle style, string name, Vector2 corner, Vector2 offset, Color fill, Sprite glyphSprite) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) GameObject val = UiFactory.Create(name, ((Component)this).transform); UiFactory.PinToCorner(val, corner, offset, 22f); UiFactory.AddImage(val, style.Circle, fill); GameObject target = UiFactory.Create("Glyph", val.transform); UiFactory.PinToCorner(target, new Vector2(0.5f, 0.5f), Vector2.zero, 12f); UiFactory.AddImage(target, glyphSprite, HudStyle.PinMarkerInk).preserveAspect = true; return val; } } internal sealed class RibbonHint : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private const float HintWidth = 460f; private const int HintSidePadding = 40; private const int HintTopPadding = 26; private const int HintTailPadding = 40; private const float HintFontSize = 17f; private const float HintGap = 4f; private static readonly Color GreyBanner = Color32.op_Implicit(new Color32((byte)110, (byte)106, (byte)102, byte.MaxValue)); private static readonly Color GreyDots = Color32.op_Implicit(new Color32((byte)154, (byte)149, (byte)143, byte.MaxValue)); private const string BannerName = "Panel"; private const string DotsName = "Border"; private readonly Dictionary<Image, Color> _nativeColours = new Dictionary<Image, Color>(); private Button _button; private GameObject _hint; private TMP_Text _hintText; private string _reason = ""; public static RibbonHint AttachTo(Button ribbon, Transform hintLayer, Image paper, TMP_FontAsset font, Material fontMaterial, Color ink) { //IL_005a: 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_009e: Expected O, but got Unknown //IL_00ca: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) RibbonHint ribbonHint = ((Component)ribbon).gameObject.AddComponent<RibbonHint>(); ribbonHint._button = ribbon; foreach (Image item in ((Component)ribbon).GetComponentsInChildren<Image>(true).Where(delegate(Image image) { string name = ((Object)image).name; return (name == "Panel" || name == "Border") ? true : false; })) { ribbonHint._nativeColours[item] = ((Graphic)item).color; } ribbonHint._hint = new GameObject("Hint", new Type[1] { typeof(RectTransform) }); ribbonHint._hint.transform.SetParent(hintLayer, false); Image val = ribbonHint._hint.AddComponent<Image>(); val.sprite = paper.sprite; val.type = paper.type; ((Graphic)val).material = ((Graphic)paper).material; ((Graphic)val).color = ((Graphic)paper).color; val.pixelsPerUnitMultiplier = paper.pixelsPerUnitMultiplier; ((Graphic)val).raycastTarget = false; VerticalLayoutGroup val2 = ribbonHint._hint.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val2).padding = new RectOffset(40, 40, 26, 40); ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ContentSizeFitter val3 = ribbonHint._hint.AddComponent<ContentSizeFitter>(); val3.verticalFit = (FitMode)2; RectTransform val4 = (RectTransform)ribbonHint._hint.transform; val4.sizeDelta = new Vector2(460f, val4.sizeDelta.y); val4.pivot = new Vector2(0.5f, 0f); TextMeshProUGUI val5 = new GameObject("Text", new Type[1] { typeof(RectTransform) }).AddComponent<TextMeshProUGUI>(); ((TMP_Text)val5).transform.SetParent(ribbonHint._hint.transform, false); ((TMP_Text)val5).font = font; ((TMP_Text)val5).fontSharedMaterial = fontMaterial; ((TMP_Text)val5).fontSize = 17f; ((Graphic)val5).color = ink; ((TMP_Text)val5).alignment = (TextAlignmentOptions)514; ((TMP_Text)val5).textWrappingMode = (TextWrappingModes)1; ((Graphic)val5).raycastTarget = false; ribbonHint._hintText = (TMP_Text)(object)val5; ribbonHint._hint.SetActive(false); return ribbonHint; } public void Set(bool usable, string reason) { //IL_005b: 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_004b: Unknown result type (might be due to invalid IL or missing references) ((Selectable)_button).interactable = usable; _reason = reason; foreach (KeyValuePair<Image, Color> nativeColour in _nativeColours) { ((Graphic)nativeColour.Key).color = (usable ? nativeColour.Value : ((((Object)nativeColour.Key).name == "Border") ? GreyDots : GreyBanner)); } if (usable) { _hint.SetActive(false); } } public void OnPointerEnter(PointerEventData eventData) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0056: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Selectable)_button).interactable) { _hintText.text = _reason; RectTransform val = (RectTransform)((Component)this).transform; RectTransform val2 = (RectTransform)_hint.transform; Rect rect = val.rect; float x = ((Rect)(ref rect)).center.x; rect = val.rect; Vector3 position = ((Transform)val).TransformPoint(new Vector3(x, ((Rect)(ref rect)).yMax + 4f, 0f)); ((Transform)val2).position = position; _hint.transform.SetAsLastSibling(); _hint.SetActive(true); } } public void OnPointerExit(PointerEventData eventData) { _hint.SetActive(false); } private void OnDisable() { if ((Object)(object)_hint != (Object)null) { _hint.SetActive(false); } } } internal sealed class StatsPanel { private const float SheetWidth = 820f; private const float RowFontSize = 22f; private const float HeadFontSize = 17f; private const float AscentFontSize = 24f; private const float BiomeColumnWidth = 330f; private const float TimesColumnWidth = 70f; private const float NumberColumnWidth = 130f; private const float EraseConfirmSeconds = 3f; private const int AscentTitleOffset = 2; public const string OpenButtonName = "PeakAchiever.StatsButton"; private const string OpenButtonLabelKey = "PEAKACHIEVER_STATISTICS"; private const string RootName = "PeakAchiever.Statistics"; private const float HeadAlpha = 0.7f; private static readonly Color TotalInk = Color32.op_Implicit(new Color32((byte)140, (byte)59, (byte)13, byte.MaxValue)); private readonly SplitHistoryStore _store; private PauseMenuAccoladesPage? _page; private GameObject? _root; private TMP_Text _ascentName; private RibbonHint _previous; private RibbonHint _next; private Button _erase; private Transform _rows; private PaperKit _kit; private int _shownAscent; private float _eraseArmedUntil = float.NegativeInfinity; public StatsPanel(SplitHistoryStore store) { _store = store; } public void Watch(PauseMenuAccoladesPage page) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown _page = page; GameTextTable.Register("PEAKACHIEVER_STATISTICS", ModTextKey.StatsButton); if (!((Object)(object)_root != (Object)null)) { PaperKit paperKit = PaperKit.Read(page, "statistics"); if (paperKit != null) { _kit = paperKit; Build(page); PaperKit.OpenButton(page, ((Component)page.backButton).transform, "PeakAchiever.StatsButton", "PEAKACHIEVER_STATISTICS", new UnityAction(Open)); PaperKit.ArrangeButtons(page); } } } public void Tick() { if (!((Object)(object)_root == (Object)null) && _root.activeSelf) { if ((Object)(object)_page == (Object)null || !((Component)_page).gameObject.activeInHierarchy || !GUIManager.InPauseMenu) { Close(); } else if (!float.IsNegativeInfinity(_eraseArmedUntil) && Time.unscaledTime >= _eraseArmedUntil) { Disarm(); } } } private void Build(PauseMenuAccoladesPage page) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown _root = PaperKit.Veil(((Component)page).transform, "PeakAchiever.Statistics"); Transform val = PaperKit.Column(_root.transform); Transform val2 = _kit.Sheet(val, 820f); Transform parent = PaperKit.Row(val2, "Ascent", (TextAnchor)4); Button ribbon = PaperKit.Ribbon(_kit.PurpleRibbon, parent, "Previous", "<", (UnityAction)delegate { ShowAscentAt(-1); }); _ascentName = _kit.Text(parent, "Name", 24f, PaperKit.PaperInk, (TextAlignmentOptions)514); UiFactory.SetPreferredSize(((Component)_ascentName).gameObject, 330f, -1f); Button ribbon2 = PaperKit.Ribbon(_kit.PurpleRibbon, parent, "Next", ">", (UnityAction)delegate { ShowAscentAt(1); }); _previous = RibbonHint.AttachTo(ribbon, _root.transform, _kit.Paper, _kit.Font, _kit.FontMaterial, PaperKit.PaperInk); _next = RibbonHint.AttachTo(ribbon2, _root.transform, _kit.Paper, _kit.Font, _kit.FontMaterial, PaperKit.PaperInk); _rows = UiFactory.Create("Rows", val2).transform; VerticalLayoutGroup val3 = ((Component)_rows).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 6f; ((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; _kit.Title(val2, ModText.Get(ModTextKey.StatsTitle)); Transform parent2 = PaperKit.Row(val, "Actions",