Decompiled source of Improve v1.0.1

Improve.dll

Decompiled 21 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

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

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Improve
{
	[BepInPlugin("headclef.Improve", "Improve", "1.0.1")]
	public class Improve : BaseUnityPlugin
	{
		private const string PluginGuid = "headclef.Improve";

		private const string PluginName = "Improve";

		private const string PluginVersion = "1.0.1";

		internal static ConfigEntry<float> DifficultyMultiplier;

		internal static ConfigEntry<int> BaseCost;

		internal static Improve Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0060: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			BindConfiguration();
			SaveData.Initialize();
			ImproveMenu.Initialize();
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		private void OnDestroy()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void BindConfiguration()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			DifficultyMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Leveling", "Difficulty Multiplier", 0.5f, new ConfigDescription("Difficulty multiplier for level-up cost. Easy=0.25, Standard=0.5, Hard=0.75, Hardest=1.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			BaseCost = ((BaseUnityPlugin)this).Config.Bind<int>("Leveling", "Base Cost", 1000000, new ConfigDescription("Base haul cost for the first level-up. Cost doubles each level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100000, 10000000), Array.Empty<object>()));
		}
	}
	public static class ImproveMenu
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static BuilderDelegate <>9__4_0;

			public static BuilderDelegate <>9__4_1;

			public static BuilderDelegate <>9__4_2;

			public static Action <>9__8_3;

			public static Action <>9__8_0;

			public static Action <>9__8_4;

			public static Action <>9__8_1;

			public static Action <>9__8_2;

			internal void <Initialize>b__4_0(Transform parent)
			{
				AddImproveButton(parent);
			}

			internal void <Initialize>b__4_1(Transform parent)
			{
				AddImproveButton(parent);
			}

			internal void <Initialize>b__4_2(Transform parent)
			{
				AddImproveButton(parent);
			}

			internal void <CreateStatsPage>b__8_0()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				MenuAPI.OpenPopup("Reset Stats", Color.yellow, "Reclaim all spent stat points? Your haul and level will be preserved.", (Action)delegate
				{
					SaveData.ResetStats();
					_statsPage.ClosePage(true);
				}, (Action)null);
			}

			internal void <CreateStatsPage>b__8_3()
			{
				SaveData.ResetStats();
				_statsPage.ClosePage(true);
			}

			internal void <CreateStatsPage>b__8_1()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				MenuAPI.OpenPopup("Reset All", Color.red, "Wipe ALL progress including haul, level, and stat allocations? This cannot be undone!", (Action)delegate
				{
					SaveData.ResetAll();
					_statsPage.ClosePage(true);
				}, (Action)null);
			}

			internal void <CreateStatsPage>b__8_4()
			{
				SaveData.ResetAll();
				_statsPage.ClosePage(true);
			}

			internal void <CreateStatsPage>b__8_2()
			{
				_statsPage.ClosePage(true);
			}
		}

		[CompilerGenerated]
		private sealed class <FixRepoButton>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public REPOButton btn;

			public Transform parent;

			private TextMeshProUGUI <tmp>5__1;

			private RectTransform <parentRt>5__2;

			private RectTransform <btnRt>5__3;

			private RectTransform <textRt>5__4;

			private float <marginRight>5__5;

			private float <marginBottom>5__6;

			private float <x>5__7;

			private float <y>5__8;

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

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

			[DebuggerHidden]
			public <FixRepoButton>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<tmp>5__1 = null;
				<parentRt>5__2 = null;
				<btnRt>5__3 = null;
				<textRt>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Expected O, but got Unknown
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: 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_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Canvas.ForceUpdateCanvases();
					<tmp>5__1 = ((Component)btn).GetComponentInChildren<TextMeshProUGUI>(true);
					if ((Object)(object)<tmp>5__1 != (Object)null)
					{
						<btnRt>5__3 = ((REPOElement)btn).rectTransform;
						<textRt>5__4 = (RectTransform)((TMP_Text)<tmp>5__1).transform;
						((Transform)<textRt>5__4).SetParent((Transform)(object)<btnRt>5__3, false);
						<textRt>5__4.anchorMin = Vector2.zero;
						<textRt>5__4.anchorMax = Vector2.one;
						<textRt>5__4.pivot = new Vector2(0.5f, 0.5f);
						<textRt>5__4.offsetMin = new Vector2(14f, 6f);
						<textRt>5__4.offsetMax = new Vector2(-14f, -6f);
						((TMP_Text)<tmp>5__1).alignment = (TextAlignmentOptions)4614;
						((TMP_Text)<tmp>5__1).enableWordWrapping = false;
						<btnRt>5__3 = null;
						<textRt>5__4 = null;
					}
					ref RectTransform reference = ref <parentRt>5__2;
					Transform obj = parent;
					reference = (RectTransform)(object)((obj is RectTransform) ? obj : null);
					if ((Object)(object)<parentRt>5__2 != (Object)null)
					{
						<marginRight>5__5 = 40f;
						<marginBottom>5__6 = 20f;
						Rect rect = <parentRt>5__2.rect;
						float width = ((Rect)(ref rect)).width;
						rect = ((REPOElement)btn).rectTransform.rect;
						<x>5__7 = width - ((Rect)(ref rect)).width - <marginRight>5__5;
						<y>5__8 = <marginBottom>5__6;
						((Transform)((REPOElement)btn).rectTransform).localPosition = new Vector3(<x>5__7, <y>5__8, 0f);
					}
					return false;
				}
				}
			}

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

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

		private static REPOPopupPage _statsPage;

		private static REPOPopupPage _skillsPage;

		private static REPOLabel _availablePointsLabel;

		private static REPOSlider[] _skillSliders;

		internal static void Initialize()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//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_006a: Expected O, but got Unknown
			object obj = <>c.<>9__4_0;
			if (obj == null)
			{
				BuilderDelegate val = delegate(Transform parent)
				{
					AddImproveButton(parent);
				};
				<>c.<>9__4_0 = val;
				obj = (object)val;
			}
			MenuAPI.AddElementToMainMenu((BuilderDelegate)obj);
			object obj2 = <>c.<>9__4_1;
			if (obj2 == null)
			{
				BuilderDelegate val2 = delegate(Transform parent)
				{
					AddImproveButton(parent);
				};
				<>c.<>9__4_1 = val2;
				obj2 = (object)val2;
			}
			MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj2);
			object obj3 = <>c.<>9__4_2;
			if (obj3 == null)
			{
				BuilderDelegate val3 = delegate(Transform parent)
				{
					AddImproveButton(parent);
				};
				<>c.<>9__4_2 = val3;
				obj3 = (object)val3;
			}
			MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj3);
		}

		private static void AddImproveButton(Transform parent)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			REPOButton btn = MenuAPI.CreateREPOButton("Improve", (Action)OpenImproveMenu, parent, new Vector2(0f, 300f));
			((MonoBehaviour)Improve.Instance).StartCoroutine(FixRepoButton(btn, parent));
		}

		[IteratorStateMachine(typeof(<FixRepoButton>d__6))]
		private static IEnumerator FixRepoButton(REPOButton btn, Transform parent)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FixRepoButton>d__6(0)
			{
				btn = btn,
				parent = parent
			};
		}

		private static void OpenImproveMenu()
		{
			((BaseUnityPlugin)Improve.Instance).Config.Reload();
			CreateStatsPage();
			CreateSkillsPage();
		}

		private static void CreateStatsPage()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			_statsPage = MenuAPI.CreateREPOPopupPage("Improve - Progress", (PresetSide)0, false, true, 0f);
			int num = SaveData.CurrentLevel();
			int num2 = SaveData.AvailablePoints();
			int num3 = SaveData.TotalSpent();
			int value = SaveData.HaulNeededForNextLevel();
			string difficultyLabel = GetDifficultyLabel();
			string text = (SaveData.IsOverspent() ? $"{num2} (OVER!)" : $"{num2}");
			float num4 = 0.75f;
			REPOElement[] array = (REPOElement[])(object)new REPOElement[15]
			{
				(REPOElement)MenuAPI.CreateREPOLabel("Lifetime Haul:", ((Component)_statsPage).transform, new Vector2(40f, 280f)),
				(REPOElement)MenuAPI.CreateREPOLabel("Current Level:", ((Component)_statsPage).transform, new Vector2(40f, 255f)),
				(REPOElement)MenuAPI.CreateREPOLabel("Available Points:", ((Component)_statsPage).transform, new Vector2(40f, 230f)),
				(REPOElement)MenuAPI.CreateREPOLabel("Spent Points:", ((Component)_statsPage).transform, new Vector2(40f, 205f)),
				(REPOElement)MenuAPI.CreateREPOLabel("Next Level In:", ((Component)_statsPage).transform, new Vector2(40f, 180f)),
				(REPOElement)MenuAPI.CreateREPOLabel("Difficulty:", ((Component)_statsPage).transform, new Vector2(40f, 155f)),
				(REPOElement)MenuAPI.CreateREPOLabel(FormatHaul(SaveData.LifetimeHaul.Value), ((Component)_statsPage).transform, new Vector2(240f, 280f)),
				(REPOElement)MenuAPI.CreateREPOLabel($"{num}", ((Component)_statsPage).transform, new Vector2(240f, 255f)),
				(REPOElement)(_availablePointsLabel = MenuAPI.CreateREPOLabel(text, ((Component)_statsPage).transform, new Vector2(240f, 230f))),
				(REPOElement)MenuAPI.CreateREPOLabel($"{num3}", ((Component)_statsPage).transform, new Vector2(240f, 205f)),
				(REPOElement)MenuAPI.CreateREPOLabel(FormatHaul(value), ((Component)_statsPage).transform, new Vector2(240f, 180f)),
				(REPOElement)MenuAPI.CreateREPOLabel(difficultyLabel, ((Component)_statsPage).transform, new Vector2(240f, 155f)),
				(REPOElement)MenuAPI.CreateREPOButton("Reset Stats", (Action)delegate
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					MenuAPI.OpenPopup("Reset Stats", Color.yellow, "Reclaim all spent stat points? Your haul and level will be preserved.", (Action)delegate
					{
						SaveData.ResetStats();
						_statsPage.ClosePage(true);
					}, (Action)null);
				}, ((Component)_statsPage).transform, new Vector2(40f, 80f)),
				(REPOElement)MenuAPI.CreateREPOButton("Reset All", (Action)delegate
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					MenuAPI.OpenPopup("Reset All", Color.red, "Wipe ALL progress including haul, level, and stat allocations? This cannot be undone!", (Action)delegate
					{
						SaveData.ResetAll();
						_statsPage.ClosePage(true);
					}, (Action)null);
				}, ((Component)_statsPage).transform, new Vector2(220f, 80f)),
				(REPOElement)MenuAPI.CreateREPOButton("Close", (Action)delegate
				{
					_statsPage.ClosePage(true);
				}, ((Component)_statsPage).transform, new Vector2(130f, 20f))
			};
			REPOElement[] array2 = array;
			foreach (REPOElement val in array2)
			{
				REPOLabel val2 = (REPOLabel)(object)((val is REPOLabel) ? val : null);
				if (val2 != null && (Object)(object)val2.labelTMP != (Object)null)
				{
					TextMeshProUGUI labelTMP = val2.labelTMP;
					((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * num4;
				}
				else
				{
					REPOButton val3 = (REPOButton)(object)((val is REPOButton) ? val : null);
					if (val3 != null && (Object)(object)val3.labelTMP != (Object)null)
					{
						TextMeshProUGUI labelTMP2 = val3.labelTMP;
						((TMP_Text)labelTMP2).fontSize = ((TMP_Text)labelTMP2).fontSize * num4;
						((REPOElement)val3).rectTransform.sizeDelta = new Vector2(160f, ((REPOElement)val3).rectTransform.sizeDelta.y);
					}
				}
				_statsPage.AddElement(val.rectTransform, Vector2.op_Implicit(((Transform)val.rectTransform).localPosition));
			}
			_statsPage.OpenPage(false);
		}

		private static void CreateSkillsPage()
		{
			//IL_005a: 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)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			int num = SaveData.AvailablePoints();
			int available = Math.Max(num, 0);
			_skillsPage = MenuAPI.CreateREPOPopupPage("Improve - Skills", (PresetSide)1, false, false, 0f);
			float num2 = 0.75f;
			if (SaveData.IsOverspent())
			{
				REPOLabel val = MenuAPI.CreateREPOLabel($"Over budget by {Math.Abs(num)} pts! Reset stats or earn more haul.", ((Component)_skillsPage).transform, default(Vector2));
				if ((Object)(object)val.labelTMP != (Object)null)
				{
					TextMeshProUGUI labelTMP = val.labelTMP;
					((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * num2;
				}
				_skillsPage.AddElementToScrollView(((REPOElement)val).rectTransform, default(Vector2), 0f, 0f);
			}
			_skillSliders = (REPOSlider[])(object)new REPOSlider[13]
			{
				CreateSlider("Health", SaveData.AllocHealth, available, 0),
				CreateSlider("Sprint Speed", SaveData.AllocSpeed, available, 1),
				CreateSlider("Stamina", SaveData.AllocStamina, available, 2),
				CreateSlider("Extra Jump", SaveData.AllocExtraJump, available, 3),
				CreateSlider("Grab Range", SaveData.AllocGrabRange, available, 4),
				CreateSlider("Grab Strength", SaveData.AllocGrabStrength, available, 5),
				CreateSlider("Throw", SaveData.AllocGrabThrow, available, 6),
				CreateSlider("Tumble Launch", SaveData.AllocTumbleLaunch, available, 7),
				CreateSlider("Tumble Climb", SaveData.AllocTumbleClimb, available, 8),
				CreateSlider("Tumble Wings", SaveData.AllocTumbleWings, available, 9),
				CreateSlider("Crouch Rest", SaveData.AllocCrouchRest, available, 10),
				CreateSlider("Map Count", SaveData.AllocMapPlayerCount, available, 11, 1),
				CreateSlider("Death Head", SaveData.AllocDeathHeadBattery, available, 12)
			};
			REPOSlider[] skillSliders = _skillSliders;
			foreach (REPOSlider val2 in skillSliders)
			{
				if ((Object)(object)val2.labelTMP != (Object)null)
				{
					TextMeshProUGUI labelTMP2 = val2.labelTMP;
					((TMP_Text)labelTMP2).fontSize = ((TMP_Text)labelTMP2).fontSize * num2;
				}
				_skillsPage.AddElementToScrollView(((REPOElement)val2).rectTransform, default(Vector2), 0f, 0f);
			}
			((REPOElement)_skillSliders[0]).repoScrollViewElement.topPadding = 5f;
			_skillsPage.scrollView.spacing = 5f;
			_skillsPage.OpenPage(true);
		}

		private static REPOSlider CreateSlider(string name, ConfigEntry<int> entry, int available, int index, int maxCap = int.MaxValue)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<int> entry2 = entry;
			return MenuAPI.CreateREPOSlider(name, string.Empty, (Action<int>)delegate(int value)
			{
				OnPointChanged(index, entry2, value);
			}, ((Component)_skillsPage).transform, default(Vector2), 0, Math.Clamp(entry2.Value + available, 0, maxCap), entry2.Value, "", "", (BarBehavior)0);
		}

		private static void OnPointChanged(int index, ConfigEntry<int> entry, int value)
		{
			entry.Value = value;
			int num = SaveData.AvailablePoints();
			int num2 = Math.Max(num, 0);
			string text = (SaveData.IsOverspent() ? $"{num} (OVER!)" : $"{num}");
			((TMP_Text)_availablePointsLabel.labelTMP).text = text;
			for (int i = 0; i < _skillSliders.Length; i++)
			{
				REPOSlider val = _skillSliders[i];
				int num3 = ((((TMP_Text)val.labelTMP).text == "Map Count") ? 1 : int.MaxValue);
				if (i == index)
				{
					val.max = Mathf.Min(value + num2, num3);
				}
				else
				{
					val.max = Mathf.Min(val.value + (float)num2, (float)num3);
				}
				val.SetValue(val.value, false);
			}
		}

		private static string GetDifficultyLabel()
		{
			float value = Improve.DifficultyMultiplier.Value;
			if (value <= 0.25f)
			{
				return "Easy";
			}
			if (value <= 0.5f)
			{
				return "Standard";
			}
			if (value <= 0.75f)
			{
				return "Hard";
			}
			return "Hardest";
		}

		private static string FormatHaul(int value)
		{
			if (value >= 1000000000)
			{
				return ((double)value / 1000000000.0).ToString("0.##") + "B";
			}
			if (value >= 1000000)
			{
				return ((double)value / 1000000.0).ToString("0.##") + "M";
			}
			if (value >= 1000)
			{
				return ((double)value / 1000.0).ToString("0.##") + "K";
			}
			return value.ToString("N0");
		}
	}
	public static class SaveData
	{
		public static ConfigEntry<int> LifetimeHaul;

		public static ConfigEntry<int> AllocHealth;

		public static ConfigEntry<int> AllocSpeed;

		public static ConfigEntry<int> AllocStamina;

		public static ConfigEntry<int> AllocExtraJump;

		public static ConfigEntry<int> AllocGrabRange;

		public static ConfigEntry<int> AllocGrabStrength;

		public static ConfigEntry<int> AllocGrabThrow;

		public static ConfigEntry<int> AllocTumbleLaunch;

		public static ConfigEntry<int> AllocTumbleClimb;

		public static ConfigEntry<int> AllocTumbleWings;

		public static ConfigEntry<int> AllocCrouchRest;

		public static ConfigEntry<int> AllocMapPlayerCount;

		public static ConfigEntry<int> AllocDeathHeadBattery;

		internal static void Initialize()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			ConfigFile val = new ConfigFile(Path.Combine(Application.persistentDataPath, "REPOModData/Improve/save.cfg"), false);
			LifetimeHaul = val.Bind<int>("Progress", "LifetimeHaul", 0, "Total haul accumulated across all sessions.");
			AllocHealth = val.Bind<int>("Skills", "Health", 0, "Points spent on Health.");
			AllocSpeed = val.Bind<int>("Skills", "SprintSpeed", 0, "Points spent on Sprint Speed.");
			AllocStamina = val.Bind<int>("Skills", "Stamina", 0, "Points spent on Stamina.");
			AllocExtraJump = val.Bind<int>("Skills", "ExtraJump", 0, "Points spent on Extra Jump.");
			AllocGrabRange = val.Bind<int>("Skills", "GrabRange", 0, "Points spent on Grab Range.");
			AllocGrabStrength = val.Bind<int>("Skills", "GrabStrength", 0, "Points spent on Grab Strength.");
			AllocGrabThrow = val.Bind<int>("Skills", "GrabThrow", 0, "Points spent on Throw.");
			AllocTumbleLaunch = val.Bind<int>("Skills", "TumbleLaunch", 0, "Points spent on Tumble Launch.");
			AllocTumbleClimb = val.Bind<int>("Skills", "TumbleClimb", 0, "Points spent on Tumble Climb.");
			AllocTumbleWings = val.Bind<int>("Skills", "TumbleWings", 0, "Points spent on Tumble Wings.");
			AllocCrouchRest = val.Bind<int>("Skills", "CrouchRest", 0, "Points spent on Crouch Rest.");
			AllocMapPlayerCount = val.Bind<int>("Skills", "MapPlayerCount", 0, "Points spent on Map Player Count.");
			AllocDeathHeadBattery = val.Bind<int>("Skills", "DeathHeadBattery", 0, "Points spent on Death Head Battery.");
		}

		public static int CurrentLevel()
		{
			float num = Improve.BaseCost.Value;
			float value = Improve.DifficultyMultiplier.Value;
			float num2 = num * value;
			if (num2 <= 0f || LifetimeHaul.Value <= 0)
			{
				return 0;
			}
			int val = (int)Math.Floor(Math.Log((double)LifetimeHaul.Value / (double)num2 + 1.0, 2.0));
			return Math.Max(val, 0);
		}

		public static int TotalHaulForLevel(int level)
		{
			if (level <= 0)
			{
				return 0;
			}
			float num = Improve.BaseCost.Value;
			float value = Improve.DifficultyMultiplier.Value;
			return (int)((double)num * (Math.Pow(2.0, level) - 1.0) * (double)value);
		}

		public static int HaulNeededForNextLevel()
		{
			int num = TotalHaulForLevel(CurrentLevel() + 1);
			return Math.Max(num - LifetimeHaul.Value, 0);
		}

		public static int TotalSpent()
		{
			return AllocHealth.Value + AllocSpeed.Value + AllocStamina.Value + AllocExtraJump.Value + AllocGrabRange.Value + AllocGrabStrength.Value + AllocGrabThrow.Value + AllocTumbleLaunch.Value + AllocTumbleClimb.Value + AllocTumbleWings.Value + AllocCrouchRest.Value + AllocMapPlayerCount.Value + AllocDeathHeadBattery.Value;
		}

		public static int AvailablePoints()
		{
			return CurrentLevel() - TotalSpent();
		}

		public static bool IsOverspent()
		{
			return AvailablePoints() < 0;
		}

		public static void ResetStats()
		{
			AllocHealth.Value = 0;
			AllocSpeed.Value = 0;
			AllocStamina.Value = 0;
			AllocExtraJump.Value = 0;
			AllocGrabRange.Value = 0;
			AllocGrabStrength.Value = 0;
			AllocGrabThrow.Value = 0;
			AllocTumbleLaunch.Value = 0;
			AllocTumbleClimb.Value = 0;
			AllocTumbleWings.Value = 0;
			AllocCrouchRest.Value = 0;
			AllocMapPlayerCount.Value = 0;
			AllocDeathHeadBattery.Value = 0;
			Improve.Logger.LogInfo((object)"Stat allocations reset. Points reclaimed.");
		}

		public static void ResetAll()
		{
			LifetimeHaul.Value = 0;
			ResetStats();
			Improve.Logger.LogInfo((object)"Full reset — haul and stats wiped.");
		}

		public static void ApplyStats(bool force = false)
		{
			Dictionary<string, int> dict;
			if (!((Object)(object)PlayerController.instance == (Object)null))
			{
				string playerSteamID = PlayerController.instance.playerSteamID;
				Improve.Logger.LogDebug((object)"Applying Improve stats...");
				dict = StatsManager.instance.FetchPlayerUpgrades(playerSteamID);
				PunManager.instance.UpdateStat("playerUpgradeHealth", playerSteamID, GetBase("playerUpgradeHealth") + AllocHealth.Value);
				PunManager.instance.UpdateStat("playerUpgradeSpeed", playerSteamID, GetBase("playerUpgradeSpeed") + AllocSpeed.Value);
				PunManager.instance.UpdateStat("playerUpgradeStamina", playerSteamID, GetBase("playerUpgradeStamina") + AllocStamina.Value);
				PunManager.instance.UpdateStat("playerUpgradeExtraJump", playerSteamID, GetBase("playerUpgradeExtraJump") + AllocExtraJump.Value);
				PunManager.instance.UpdateStat("playerUpgradeRange", playerSteamID, GetBase("playerUpgradeRange") + AllocGrabRange.Value);
				PunManager.instance.UpdateStat("playerUpgradeStrength", playerSteamID, GetBase("playerUpgradeStrength") + AllocGrabStrength.Value);
				PunManager.instance.UpdateStat("playerUpgradeThrow", playerSteamID, GetBase("playerUpgradeThrow") + AllocGrabThrow.Value);
				PunManager.instance.UpdateStat("playerUpgradeLaunch", playerSteamID, GetBase("playerUpgradeLaunch") + AllocTumbleLaunch.Value);
				PunManager.instance.UpdateStat("playerUpgradeTumbleClimb", playerSteamID, GetBase("playerUpgradeTumbleClimb") + AllocTumbleClimb.Value);
				PunManager.instance.UpdateStat("playerUpgradeTumbleWings", playerSteamID, GetBase("playerUpgradeTumbleWings") + AllocTumbleWings.Value);
				PunManager.instance.UpdateStat("playerUpgradeCrouchRest", playerSteamID, GetBase("playerUpgradeCrouchRest") + AllocCrouchRest.Value);
				PunManager.instance.UpdateStat("playerUpgradeMapPlayerCount", playerSteamID, GetBase("playerUpgradeMapPlayerCount") + AllocMapPlayerCount.Value);
				PunManager.instance.UpdateStat("playerUpgradeDeathHeadBattery", playerSteamID, GetBase("playerUpgradeDeathHeadBattery") + AllocDeathHeadBattery.Value);
				Improve.Logger.LogInfo((object)$"Improve stats applied (Level {CurrentLevel()}, {TotalSpent()} spent, {AvailablePoints()} available).");
			}
			int GetBase(string key)
			{
				int value;
				return (dict != null && dict.TryGetValue(key, out value)) ? value : 0;
			}
		}
	}
}
namespace Improve.Patches
{
	[HarmonyPatch]
	internal static class HaulTrackerPatch
	{
		private static int _haulAtLevelStart;

		[HarmonyPatch(typeof(StatsManager), "PlayerAdd")]
		[HarmonyPostfix]
		private static void PlayerAdd_Postfix(string _steamID)
		{
			if (!(_steamID != PlayerAvatar.instance.steamID))
			{
				_haulAtLevelStart = StatsManager.instance.GetRunStatTotalHaul();
				Improve.Logger.LogDebug((object)$"Level start baseline: {_haulAtLevelStart}");
			}
		}

		[HarmonyPatch(typeof(SemiFunc), "OnSceneSwitch")]
		[HarmonyPrefix]
		private static void OnSceneSwitch_Prefix()
		{
			if (SemiFunc.RunIsLevel())
			{
				int runStatTotalHaul = StatsManager.instance.GetRunStatTotalHaul();
				int num = runStatTotalHaul - _haulAtLevelStart;
				if (num > 0)
				{
					ConfigEntry<int> lifetimeHaul = SaveData.LifetimeHaul;
					lifetimeHaul.Value += num;
					Improve.Logger.LogInfo((object)$"Level haul captured: +{num} (lifetime: {SaveData.LifetimeHaul.Value})");
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class StatApplyPatch
	{
		[CompilerGenerated]
		private sealed class <DelayedApply>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

			[DebuggerHidden]
			public <DelayedApply>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					SaveData.ApplyStats();
					return false;
				}
			}

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

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

		[HarmonyPatch(typeof(StatsManager), "PlayerAdd")]
		[HarmonyPostfix]
		private static void PlayerAdd_Postfix(string _steamID)
		{
			if (SemiFunc.RunIsLevel() && !(_steamID != PlayerAvatar.instance.steamID))
			{
				Improve.Logger.LogDebug((object)"Player data added — scheduling stat apply...");
				Object.FindObjectOfType<MonoBehaviour>().StartCoroutine(DelayedApply());
			}
		}

		[HarmonyPatch(typeof(PunManager), "ReceiveSyncData")]
		[HarmonyPostfix]
		private static void ReceiveSyncData_Postfix(bool finalChunk)
		{
			if (finalChunk)
			{
				Improve.Logger.LogDebug((object)"Sync complete — re-applying stats...");
				SaveData.ApplyStats();
			}
		}

		[IteratorStateMachine(typeof(<DelayedApply>d__2))]
		private static IEnumerator DelayedApply()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedApply>d__2(0);
		}
	}
}