Decompiled source of SLRUpgradePack v0.1.5

plugins/SLRUpgradePack.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomColors;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Pun;
using REPOLib.Modules;
using SLRUpgradePack.Properties;
using SLRUpgradePack.UpgradeManagers;
using SLRUpgradePack.UpgradeManagers.MoreUpgrades;
using TMPro;
using UnityEngine;
using UnityEngine.UIElements;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("SolarAaron")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b0d7f72a469e26dbdc652ff73c8aa72df5f29022")]
[assembly: AssemblyProduct("SLRUpgradePack")]
[assembly: AssemblyTitle("SLRUpgradePack")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 SLRUpgradePack
{
	[BepInPlugin("SolarAaron.SLRUpgradePack", "SLRUpgradePack", "0.1.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SLRUpgradePack : BaseUnityPlugin
	{
		internal static SLRUpgradePack Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		internal Harmony? Harmony { get; set; }

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

		public static OverchargeUpgrade OverchargeUpgradeInstance { get; private set; }

		public static ArmorUpgrade ArmorUpgradeInstance { get; private set; }

		public static ObjectValueUpgrade ObjectValueUpgradeInstance { get; private set; }

		public static ObjectDurabilityUpgrade ObjectDurabilityUpgradeInstance { get; private set; }

		public static ValuableDensityUpgrade ValuableDensityUpgradeInstance { get; private set; }

		public static HeartOfGoldUpgrade HeartOfGoldUpgradeInstance { get; private set; }

		public static RegenerationUpgrade RegenerationUpgradeInstance { get; private set; }

		public static ExtraLifeUpgrade ExtraLifeUpgradeInstance { get; private set; }

		public static MapEnemyTrackerUpgrade MapEnemyTrackerUpgradeInstance { get; private set; }

		public static MapPlayerTrackerUpgrade MapPlayerTrackerUpgradeInstance { get; private set; }

		public static SprintUsageUpgrade SprintUsageUpgradeInstance { get; private set; }

		public static MapValueTrackerUpgrade MapValueTrackerUpgradeInstance { get; private set; }

		private void Awake()
		{
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			_logger.LogInfo((object)"Configuring upgrade pack...");
			AssetBundle val = AssetBundle.LoadFromMemory(Resources.slr_assets);
			((Object)val).name = "slr";
			string[] allAssetNames = val.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				_logger.LogInfo((object)("Found asset: " + text));
			}
			if (PhysGrabberPatch.Prepare())
			{
				OverchargeUpgradeInstance = new OverchargeUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 0.75f);
			}
			ArmorUpgradeInstance = new ArmorUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 1f);
			ObjectValueUpgradeInstance = new ObjectValueUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 1.5f);
			ObjectDurabilityUpgradeInstance = new ObjectDurabilityUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 1.5f);
			ValuableDensityUpgradeInstance = new ValuableDensityUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 1.5f);
			HeartOfGoldUpgradeInstance = new HeartOfGoldUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 10f, 2.5f);
			RegenerationUpgradeInstance = new RegenerationUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 0.1f, 1.5f);
			ExtraLifeUpgradeInstance = new ExtraLifeUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 5, 5f);
			MapEnemyTrackerUpgradeInstance = new MapEnemyTrackerUpgrade(enabled: true, ((BaseUnityPlugin)this).Config, val, 4f, arrowIcon: true, Color.red, "", 2000, 3000);
			MapPlayerTrackerUpgradeInstance = new MapPlayerTrackerUpgrade(enabled: true, ((BaseUnityPlugin)this).Config, val, 4f, arrowIcon: true, Color.blue, 2000, 3000, playerColor: false);
			SprintUsageUpgradeInstance = new SprintUsageUpgrade(enabled: true, ((BaseUnityPlugin)this).Config, val, 0.5f, 2000, 3000);
			MapValueTrackerUpgradeInstance = new MapValueTrackerUpgrade(enabled: true, ((BaseUnityPlugin)this).Config, val, 3.5f, 2000, 3000, displayTotal: true);
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

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

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !LevelGenerator.Instance.Generated)
			{
				return;
			}
			List<Action> list = new List<Action>();
			if (PhysGrabberPatch.Prepare())
			{
				foreach (KeyValuePair<string, int> pair3 in OverchargeUpgradeInstance.UpgradeRegister.PlayerDictionary)
				{
					if (pair3.Value < OverchargeUpgradeInstance.StartingAmount.Value)
					{
						list.Add(delegate
						{
							OverchargeUpgradeInstance.UpgradeRegister.SetLevel(pair3.Key, OverchargeUpgradeInstance.StartingAmount.Value);
						});
					}
				}
			}
			foreach (KeyValuePair<string, int> pair4 in ArmorUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair4.Value < ArmorUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						ArmorUpgradeInstance.UpgradeRegister.SetLevel(pair4.Key, ArmorUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair5 in ObjectValueUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair5.Value < ObjectValueUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						ObjectValueUpgradeInstance.UpgradeRegister.SetLevel(pair5.Key, ObjectValueUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair6 in ObjectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair6.Value < ObjectDurabilityUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						ObjectDurabilityUpgradeInstance.UpgradeRegister.SetLevel(pair6.Key, ObjectDurabilityUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair7 in ValuableDensityUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair7.Value < ValuableDensityUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						ValuableDensityUpgradeInstance.UpgradeRegister.SetLevel(pair7.Key, ValuableDensityUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair8 in HeartOfGoldUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair8.Value < HeartOfGoldUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						HeartOfGoldUpgradeInstance.UpgradeRegister.SetLevel(pair8.Key, HeartOfGoldUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair9 in RegenerationUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair9.Value < RegenerationUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						RegenerationUpgradeInstance.UpgradeRegister.SetLevel(pair9.Key, RegenerationUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair10 in ExtraLifeUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair10.Value < ExtraLifeUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						ExtraLifeUpgradeInstance.UpgradeRegister.SetLevel(pair10.Key, ExtraLifeUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair11 in MapEnemyTrackerUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair11.Value < MapEnemyTrackerUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						MapEnemyTrackerUpgradeInstance.UpgradeRegister.SetLevel(pair11.Key, MapEnemyTrackerUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair12 in MapPlayerTrackerUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair12.Value < MapPlayerTrackerUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						MapPlayerTrackerUpgradeInstance.UpgradeRegister.SetLevel(pair12.Key, MapPlayerTrackerUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair2 in MapValueTrackerUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair2.Value < MapValueTrackerUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						MapValueTrackerUpgradeInstance.UpgradeRegister.SetLevel(pair2.Key, MapValueTrackerUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			foreach (KeyValuePair<string, int> pair in SprintUsageUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				if (pair.Value < SprintUsageUpgradeInstance.StartingAmount.Value)
				{
					list.Add(delegate
					{
						SprintUsageUpgradeInstance.UpgradeRegister.SetLevel(pair.Key, SprintUsageUpgradeInstance.StartingAmount.Value);
					});
				}
			}
			list.ForEach(delegate(Action action)
			{
				action();
			});
		}
	}
}
namespace SLRUpgradePack.UpgradeManagers
{
	public class ArmorUpgrade : UpgradeBase<float>
	{
		public ArmorUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier)
			: base("Armor", "assets/repo/mods/resources/items/items/item upgrade armor.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatReduce(this, "Armor", value, player, level);
		}
	}
	[HarmonyPatch(typeof(PlayerHealth), "Hurt")]
	public class PlayerHealthArmorPatch
	{
		private static void Prefix(PlayerHealth __instance, ref int damage, PlayerAvatar ___playerAvatar)
		{
			ArmorUpgrade armorUpgradeInstance = SLRUpgradePack.ArmorUpgradeInstance;
			if (armorUpgradeInstance.UpgradeEnabled.Value)
			{
				SLRUpgradePack.Logger.LogDebug((object)$"Original damage amount: {damage}");
				damage = (int)Math.Ceiling(armorUpgradeInstance.Calculate(damage, ___playerAvatar, armorUpgradeInstance.UpgradeRegister.GetLevel(___playerAvatar)));
				SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with level {0}: {1}", Upgrades.GetUpgrade("Armor").GetLevel(___playerAvatar), damage));
			}
		}
	}
	public class ExtraLifeUpgrade : UpgradeBase<float>
	{
		public ConfigEntry<int> RevivePercent { get; protected set; }

		internal Dictionary<string, ExtraLife> ExtraLives { get; set; } = new Dictionary<string, ExtraLife>();


		public ExtraLifeUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, int revivePercent, float priceMultiplier)
			: base("Extra Life", "assets/repo/mods/resources/items/items/item upgrade extra life.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: false, 2000, 100000, canBeExponential: true, singleUse: false)
		{
			RevivePercent = config.Bind<int>("Extra Life Upgrade", "revivePercent", revivePercent, "Percentage of health to recover when revived");
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ExtraLife", value, player, level);
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			if (ExtraLives.TryGetValue(SemiFunc.PlayerGetSteamID(player), out ExtraLife value))
			{
				Object.Destroy((Object)(object)value);
			}
			value = new GameObject("Extra Life: " + SemiFunc.PlayerGetName(player)).AddComponent<ExtraLife>();
			value.player = player;
			value.playerHead = player.playerDeathHead;
			ExtraLives[SemiFunc.PlayerGetSteamID(player)] = value;
		}
	}
	public class ExtraLife : MonoBehaviour
	{
		private bool _isMoving;

		private Coroutine? reviving;

		private PhotonView photonView;

		private FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health");

		private FieldRef<PlayerDeathHead, bool> _inExtractionPointRef = AccessTools.FieldRefAccess<PlayerDeathHead, bool>("inExtractionPoint");

		public PlayerDeathHead playerHead { get; set; }

		public PlayerAvatar player { get; set; }

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)player.playerHealth))
			{
				ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance;
				if (extraLifeUpgradeInstance.UpgradeEnabled.Value && _healthRef.Invoke(player.playerHealth) == 0 && extraLifeUpgradeInstance.UpgradeRegister.GetLevel(player) > 0 && !_isMoving && !_inExtractionPointRef.Invoke(playerHead) && reviving == null)
				{
					reviving = ((MonoBehaviour)this).StartCoroutine(BeginReviving());
				}
			}
			else
			{
				SLRUpgradePack.Logger.LogInfo((object)"why are we here?");
			}
		}

		private IEnumerator BeginReviving()
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			SLRUpgradePack.Logger.LogInfo((object)("Reviving " + SemiFunc.PlayerGetName(player)));
			ExtraLifeUpgrade extraLifeUpgrade = SLRUpgradePack.ExtraLifeUpgradeInstance;
			FieldRef<PlayerHealth, int> maxHealthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth");
			while (_isMoving)
			{
				AccessTools.FieldRefAccess<PlayerAvatar, float>("deadTimer").Invoke(player) += 1f;
				yield return (object)new WaitForSecondsRealtime(0.1f);
				SLRUpgradePack.Logger.LogInfo((object)"Pause attempt to revive moving head");
			}
			if (_inExtractionPointRef.Invoke(playerHead))
			{
				reviving = null;
				yield break;
			}
			player.Revive(false);
			player.playerHealth.HealOther(Mathf.FloorToInt((float)(maxHealthRef.Invoke(player.playerHealth) * extraLifeUpgrade.RevivePercent.Value) / 100f), true);
			if (!SemiFunc.IsMultiplayer())
			{
				ReviveLogic();
			}
			else
			{
				photonView.RPC("ReviveLogic", (RpcTarget)0, Array.Empty<object>());
			}
			reviving = null;
		}

		[PunRPC]
		private void ReviveLogic()
		{
			SLRUpgradePack.ExtraLifeUpgradeInstance.UpgradeRegister.RemoveLevel(player, 1);
		}

		private void Start()
		{
			SLRUpgradePack.Logger.LogInfo((object)(SemiFunc.PlayerGetName(player) + " has obtained extra lives"));
			photonView = ((Component)this).gameObject.AddComponent<PhotonView>();
			((MonoBehaviour)this).StartCoroutine(MovementCheck());
		}

		private IEnumerator MovementCheck()
		{
			while (!Object.op_Implicit((Object)(object)playerHead))
			{
				yield return null;
			}
			while (!Object.op_Implicit((Object)(object)((Component)playerHead).transform))
			{
				yield return null;
			}
			Vector3 currentPosition = ((Component)playerHead).transform.position;
			while (true)
			{
				yield return (object)new WaitForSecondsRealtime(0.5f);
				Vector3 position = ((Component)playerHead).transform.position;
				_isMoving = Vector3.Distance(currentPosition, position) >= 0.01f;
				SLRUpgradePack.Logger.LogDebug((object)$"{SemiFunc.PlayerGetName(player)} is moving: {_isMoving}");
				currentPosition = position;
			}
		}
	}
	public class HeartOfGoldUpgrade : UpgradeBase<float>
	{
		public ConfigEntry<float> BaseHeartValue { get; protected set; }

		internal Dictionary<string, GoldenHeart> GoldenHearts { get; set; } = new Dictionary<string, GoldenHeart>();


		public HeartOfGoldUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float baseValue, float priceMultiplier)
			: base("Heart Of Gold", "assets/repo/mods/resources/items/items/item upgrade heart of gold.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
			BaseHeartValue = config.Bind<float>("Heart Of Gold Upgrade", "Base Value", baseValue, "Base value to scale by player health");
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "HeartOfGold", value, player, level);
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			if (GoldenHearts.TryGetValue(SemiFunc.PlayerGetSteamID(player), out GoldenHeart value))
			{
				Object.Destroy((Object)(object)value);
			}
			value = new GameObject("Golden Heart: " + SemiFunc.PlayerGetName(player)).AddComponent<GoldenHeart>();
			value.player = player;
			GoldenHearts[SemiFunc.PlayerGetSteamID(player)] = value;
		}
	}
	public class GoldenHeart : MonoBehaviour
	{
		private PhotonView photonView;

		private readonly FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health");

		private readonly FieldRef<ValuableObject, PhysAttribute> _physAttributePresetRef = AccessTools.FieldRefAccess<ValuableObject, PhysAttribute>("physAttributePreset");

		private readonly FieldRef<ValuableObject, bool> _discoveredRef = AccessTools.FieldRefAccess<ValuableObject, bool>("discovered");

		private readonly FieldRef<ValuableObject, float> _dollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent");

		internal PlayerAvatar player { get; set; }

		internal bool Pause { get; set; }

		internal int lastLevel { get; set; } = -1;


		internal int lastHealth { get; set; } = -1;


		internal ValuableObject? ValuableComponent { get; private set; }

		private void Start()
		{
			photonView = ((Component)this).gameObject.GetComponent<PhotonView>();
		}

		public void DestroyOnlyMe()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				DestroyOnlyMeRPC();
			}
			else
			{
				photonView.RPC("DestroyOnlyMeRPC", (RpcTarget)0, Array.Empty<object>());
			}
		}

		[PunRPC]
		private void DestroyOnlyMeRPC()
		{
			if (!((Object)(object)ValuableComponent == (Object)null))
			{
				SLRUpgradePack.Logger.LogInfo((object)("Components in GoldenHeart: " + string.Join(',', from v in ((Component)this).GetComponents<Object>()
					select ((object)v).ToString())));
				RoundDirector.instance.PhysGrabObjectRemove(((Component)ValuableComponent).GetComponent<PhysGrabObject>());
				Object.Destroy((Object)(object)ValuableComponent);
				ValuableComponent = null;
			}
		}

		public void CreateOnlyMe()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				CreateOnlyMeRPC();
			}
			else
			{
				photonView.RPC("CreateOnlyMeRPC", (RpcTarget)0, Array.Empty<object>());
			}
		}

		[PunRPC]
		private void CreateOnlyMeRPC()
		{
			//IL_013f: 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_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance;
			SLRUpgradePack.Logger.LogInfo((object)("Adding valuable component to player " + SemiFunc.PlayerGetName(player)));
			ValuableComponent = ((Component)player.healthGrab).gameObject.AddComponent<ValuableObject>();
			SLRUpgradePack.Logger.LogInfo((object)("Valuable component " + SemiFunc.PlayerGetName(player) + " instantiated at " + JsonConvert.SerializeObject((object)((Component)ValuableComponent).transform)));
			ValuableComponent.valuePreset = ScriptableObject.CreateInstance<Value>();
			ValuableComponent.valuePreset.valueMin = (ValuableComponent.valuePreset.valueMax = heartOfGoldUpgradeInstance.Calculate((float)_healthRef.Invoke(player.playerHealth) * heartOfGoldUpgradeInstance.BaseHeartValue.Value, player, heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player)));
			ValuableComponent.durabilityPreset = ScriptableObject.CreateInstance<Durability>();
			ValuableComponent.durabilityPreset.durability = 999f;
			ValuableComponent.durabilityPreset.fragility = 0f;
			ValuableComponent.physAttributePreset = ScriptableObject.CreateInstance<PhysAttribute>();
			((Component)ValuableComponent).transform.localScale = Vector3.zero;
			((Component)ValuableComponent).transform.SetParent(((Component)player).transform, false);
			((Component)ValuableComponent).gameObject.AddComponent<Rigidbody>();
			PhotonTransformView item = ((Component)ValuableComponent).gameObject.AddComponent<PhotonTransformView>();
			PhysGrabObjectImpactDetector val = ((Component)ValuableComponent).gameObject.AddComponent<PhysGrabObjectImpactDetector>();
			PhysGrabObject val2 = ((Component)ValuableComponent).gameObject.AddComponent<PhysGrabObject>();
			((Component)ValuableComponent).gameObject.AddComponent<PhotonView>().ObservedComponents = new List<Component>(3)
			{
				(Component)(object)val2,
				(Component)(object)val,
				(Component)(object)item
			};
			((Behaviour)val).enabled = false;
			((Behaviour)val2).enabled = false;
			((Component)val2).transform.localScale = Vector3.zero;
			((Component)val2).transform.SetParent(((Component)ValuableComponent).transform, false);
			((Component)val).transform.localScale = Vector3.zero;
			((Component)val).transform.SetParent(((Component)ValuableComponent).transform, false);
			((Component)ValuableComponent).gameObject.AddComponent<RoomVolumeCheck>().CurrentRooms = new List<RoomVolume>();
			ValuableObject? valuableComponent = ValuableComponent;
			Gradient val3 = new Gradient();
			val3.alphaKeys = (GradientAlphaKey[])(object)new GradientAlphaKey[1]
			{
				new GradientAlphaKey(1f, 0f)
			};
			val3.colorKeys = (GradientColorKey[])(object)new GradientColorKey[1]
			{
				new GradientColorKey(Color.yellow, 0f)
			};
			valuableComponent.particleColors = val3;
			_physAttributePresetRef.Invoke(ValuableComponent) = ScriptableObject.CreateInstance<PhysAttribute>();
			int num2 = (lastLevel = -1);
			lastHealth = num2;
		}

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !Traverse.Create((object)RoundDirector.instance).Field("extractionPointsFetched").GetValue<bool>())
			{
				return;
			}
			HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance;
			if (heartOfGoldUpgradeInstance.UpgradeEnabled.Value && !Pause && heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player) != 0 && _healthRef.Invoke(player.playerHealth) != 0 && (lastLevel != heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player) || lastHealth != _healthRef.Invoke(player.playerHealth)))
			{
				lastLevel = heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player);
				lastHealth = _healthRef.Invoke(player.playerHealth);
				if ((Object)(object)ValuableComponent == (Object)null || !Object.op_Implicit((Object)(object)ValuableComponent))
				{
					CreateOnlyMe();
				}
				if (!SemiFunc.IsMultiplayer())
				{
					UpdateOnlyMeRPC();
				}
				else
				{
					photonView.RPC("UpdateOnlyMeRPC", (RpcTarget)0, Array.Empty<object>());
				}
			}
		}

		[PunRPC]
		private void UpdateOnlyMeRPC()
		{
			HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance;
			if (!_discoveredRef.Invoke(ValuableComponent))
			{
				ValuableComponent.Discover((State)0);
			}
			_dollarValueCurrentRef.Invoke(ValuableComponent) = heartOfGoldUpgradeInstance.Calculate((float)_healthRef.Invoke(player.playerHealth) * heartOfGoldUpgradeInstance.BaseHeartValue.Value, player, heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player));
			ValuableObjectValuePatch.Action(ValuableComponent);
		}

		public void PauseLogic(bool pause)
		{
			if (!SemiFunc.IsMultiplayer())
			{
				PauseLogicRPC(pause);
				return;
			}
			photonView.RPC("PauseLogicRPC", (RpcTarget)0, new object[1] { pause });
		}

		[PunRPC]
		private void PauseLogicRPC(bool pause)
		{
			Pause = pause;
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint))]
	public class ExrtractionPointdestoryPatch
	{
		private static FieldRef<RoundDirector, int>? _totalHaulRef = AccessTools.FieldRefAccess<RoundDirector, int>("totalHaul");

		[HarmonyPatch("DestroyAllPhysObjectsInHaulList")]
		[HarmonyPrefix]
		private static bool DestroyAllPrefix()
		{
			HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value)
			{
				return true;
			}
			ValuableObject val = default(ValuableObject);
			foreach (GameObject dollarHaul in RoundDirector.instance.dollarHaulList)
			{
				if (!Object.op_Implicit((Object)(object)dollarHaul) || !Object.op_Implicit((Object)(object)dollarHaul.GetComponent<PhysGrabObject>()))
				{
					continue;
				}
				_totalHaulRef.Invoke(RoundDirector.instance) += (int)Traverse.Create((object)dollarHaul.GetComponent<ValuableObject>()).Field("dollarValueCurrent").GetValue<float>();
				if (dollarHaul.TryGetComponent<ValuableObject>(ref val) && ((Object)val).name.Equals("Health Grab"))
				{
					foreach (KeyValuePair<string, GoldenHeart> goldenHeart in heartOfGoldUpgradeInstance.GoldenHearts)
					{
						if ((Object)(object)goldenHeart.Value.ValuableComponent == (Object)(object)val)
						{
							SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.Value.player) + " in extraction zone counts as valuable"));
							goldenHeart.Value.PauseLogic(pause: true);
							goldenHeart.Value.DestroyOnlyMe();
						}
					}
				}
				else
				{
					dollarHaul.GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
				}
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				player.playerDeathHead.Revive();
			}
			foreach (KeyValuePair<string, GoldenHeart> goldenHeart2 in heartOfGoldUpgradeInstance.GoldenHearts)
			{
				goldenHeart2.Value.PauseLogic(pause: false);
			}
			return false;
		}

		[HarmonyPatch("DestroyTheFirstPhysObjectsInHaulList")]
		[HarmonyPrefix]
		private static bool DestroyFirstPrefix()
		{
			HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || RoundDirector.instance.dollarHaulList.Count == 0 || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0]) || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>()) || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value)
			{
				return true;
			}
			_totalHaulRef.Invoke(RoundDirector.instance) += (int)Traverse.Create((object)RoundDirector.instance.dollarHaulList[0].GetComponent<ValuableObject>()).Field("dollarValueCurrent").GetValue<float>();
			ValuableObject val = default(ValuableObject);
			if (RoundDirector.instance.dollarHaulList[0].TryGetComponent<ValuableObject>(ref val) && ((Object)val).name.Equals("Health Grab"))
			{
				foreach (KeyValuePair<string, GoldenHeart> goldenHeart in heartOfGoldUpgradeInstance.GoldenHearts)
				{
					if ((Object)(object)goldenHeart.Value.ValuableComponent == (Object)(object)val)
					{
						SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.Value.player) + " in extraction zone counts as valuable"));
						goldenHeart.Value.PauseLogic(pause: true);
						goldenHeart.Value.DestroyOnlyMe();
					}
				}
			}
			else
			{
				RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
			}
			RoundDirector.instance.dollarHaulList.RemoveAt(0);
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundDirector), "Update")]
	public class RoundDirectorUpdatePatch
	{
		private static void Prefix(RoundDirector __instance)
		{
			ValuableObject val = default(ValuableObject);
			__instance.dollarHaulList.RemoveAll((GameObject go) => (Object)(object)go == (Object)null || !go.TryGetComponent<ValuableObject>(ref val) || !Object.op_Implicit((Object)(object)val));
		}
	}
	public class ObjectDurabilityUpgrade : UpgradeBase<float>
	{
		public ObjectDurabilityUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier)
			: base("Object Durability", "assets/repo/mods/resources/items/items/item upgrade durability.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ObjectDurability", value, player, level);
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "Start")]
	public class ValuableObjectDurabilityPatch
	{
		[HarmonyPriority(0)]
		internal static void Prefix(ValuableObject __instance)
		{
			ObjectDurabilityUpgrade objectDurabilityUpgradeInstance = SLRUpgradePack.ObjectDurabilityUpgradeInstance;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !objectDurabilityUpgradeInstance.UpgradeEnabled.Value)
			{
				return;
			}
			SLRUpgradePack.Logger.LogDebug((object)$"Original durability: {__instance.durabilityPreset.durability}");
			Durability val = Object.Instantiate<Durability>(__instance.durabilityPreset);
			foreach (KeyValuePair<string, int> item in objectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				val.durability = objectDurabilityUpgradeInstance.Calculate(__instance.durabilityPreset.durability, SemiFunc.PlayerGetFromSteamID(item.Key), item.Value);
				val.fragility = UpgradeBase<float>.DefaultCalculateFloatReduce(objectDurabilityUpgradeInstance, "ObjectDurability", __instance.durabilityPreset.fragility, SemiFunc.PlayerGetFromSteamID(item.Key), item.Value);
			}
			__instance.durabilityPreset = val;
			SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with levels {0}: {1}", string.Join(",", from kvp in objectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary
				where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null
				select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)), __instance.durabilityPreset.durability));
		}
	}
	public class SpawnedValuableDurabilityPatch<TSVT> where TSVT : MonoBehaviour
	{
		protected static void DoValuableStuff(TSVT spawnedValuable)
		{
			ValuableObject val = default(ValuableObject);
			if (((Component)(object)spawnedValuable).TryGetComponent<ValuableObject>(ref val))
			{
				SLRUpgradePack.Logger.LogDebug((object)$"Valuable spawned with: {val.durabilityPreset.durability} / {val.durabilityPreset.fragility}");
				ValuableObjectDurabilityPatch.Prefix(val);
			}
		}
	}
	[HarmonyPatch(typeof(SurplusValuable), "Start")]
	public class SurplusValuableDurabilityValuePatch : SpawnedValuableDurabilityPatch<SurplusValuable>
	{
		internal static void Prefix(SurplusValuable __instance)
		{
			SpawnedValuableDurabilityPatch<SurplusValuable>.DoValuableStuff(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyValuable), "Start")]
	public class EnemyValuableDurabilityValuePatch : SpawnedValuableDurabilityPatch<EnemyValuable>
	{
		internal static void Prefix(EnemyValuable __instance)
		{
			SpawnedValuableDurabilityPatch<EnemyValuable>.DoValuableStuff(__instance);
		}
	}
	public class ObjectValueUpgrade : UpgradeBase<float>
	{
		public ConfigEntry<bool> UpgradeScalesSurplus { get; protected set; }

		public ObjectValueUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier)
			: base("Object Value", "assets/repo/mods/resources/items/items/item upgrade value.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
			UpgradeScalesSurplus = config.Bind<bool>("Object Value Upgrade", "Scale Surplus Bag", false, "Should the Object Value Upgrade scale the extraction surplus bag?");
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ObjectValue", value, player, level);
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "DollarValueSetLogic")]
	public class ValuableObjectValuePatch
	{
		internal static readonly FieldRef<ValuableObject, int> FixedValueRef = AccessTools.FieldRefAccess<ValuableObject, int>("dollarValueOverride");

		internal static readonly FieldRef<ValuableObject, float> DollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent");

		internal static readonly Queue<ValuableObject> DollarValueQueue = new Queue<ValuableObject>();

		[HarmonyPriority(800)]
		internal static void Postfix(ValuableObject __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			ObjectValueUpgrade objectValueUpgradeInstance = SLRUpgradePack.ObjectValueUpgradeInstance;
			if ((Object)(object)__instance == (Object)null || SemiFunc.RunIsLobby() || SemiFunc.RunIsShop() || SemiFunc.RunIsArena())
			{
				return;
			}
			if (objectValueUpgradeInstance.UpgradeEnabled.Value && (int)LevelGenerator.Instance.State <= 11)
			{
				if (!DollarValueQueue.Contains(__instance))
				{
					DollarValueQueue.Enqueue(__instance);
				}
			}
			else
			{
				Action(__instance);
			}
		}

		internal static void Action(ValuableObject instance)
		{
			ObjectValueUpgrade objectValueUpgradeInstance = SLRUpgradePack.ObjectValueUpgradeInstance;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !objectValueUpgradeInstance.UpgradeEnabled.Value || (!objectValueUpgradeInstance.UpgradeScalesSurplus.Value && StringUtilsExtensions.StartsWithIgnoreCaseFast(((Object)instance).name, "surplus")))
			{
				return;
			}
			SLRUpgradePack.Logger.LogDebug((object)$"{((Object)instance).name} Original value: {instance.valuePreset.valueMin} - {instance.valuePreset.valueMax} ({DollarValueCurrentRef.Invoke(instance)} / {FixedValueRef.Invoke(instance)})");
			Value val = Object.Instantiate<Value>(instance.valuePreset);
			float num = DollarValueCurrentRef.Invoke(instance);
			foreach (KeyValuePair<string, int> item in objectValueUpgradeInstance.UpgradeRegister.PlayerDictionary)
			{
				val.valueMin = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMin, SemiFunc.PlayerGetFromSteamID(item.Key), item.Value);
				val.valueMax = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMax, SemiFunc.PlayerGetFromSteamID(item.Key), item.Value);
				if (FixedValueRef.Invoke(instance) != 0)
				{
					FixedValueRef.Invoke(instance) = (int)Math.Ceiling(objectValueUpgradeInstance.Calculate(FixedValueRef.Invoke(instance), SemiFunc.PlayerGetFromSteamID(item.Key), item.Value));
				}
				num = objectValueUpgradeInstance.Calculate(num, SemiFunc.PlayerGetFromSteamID(item.Key), item.Value);
			}
			instance.valuePreset = val;
			DollarValueCurrentRef.Invoke(instance) = num;
			SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with levels {0}: {1} - {2} ({3} / {4})", string.Join(",", from kvp in objectValueUpgradeInstance.UpgradeRegister.PlayerDictionary
				where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null
				select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)), instance.valuePreset.valueMin, instance.valuePreset.valueMax, DollarValueCurrentRef.Invoke(instance), FixedValueRef.Invoke(instance)));
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	public class LevelGeneratorObjectValueStartPatch
	{
		internal static void Postfix(ValuableDirector __instance)
		{
			if (!SemiFunc.RunIsLevel())
			{
				return;
			}
			while (ValuableObjectValuePatch.DollarValueQueue.Count > 0)
			{
				ValuableObject val = ValuableObjectValuePatch.DollarValueQueue.Dequeue();
				if (Object.op_Implicit((Object)(object)val))
				{
					ValuableObjectValuePatch.Action(val);
				}
			}
		}
	}
	public class SpawnedValuableValuePatch<TSVT> where TSVT : MonoBehaviour
	{
		protected static void DoValuableStuff(TSVT spawnedValuable)
		{
			ValuableObject val = default(ValuableObject);
			if (((Component)(object)spawnedValuable).TryGetComponent<ValuableObject>(ref val) && SLRUpgradePack.ObjectValueUpgradeInstance.UpgradeEnabled.Value)
			{
				SLRUpgradePack.Logger.LogDebug((object)$"Valuable spawned with: {val.valuePreset.valueMin} {val.valuePreset.valueMax} {ValuableObjectValuePatch.FixedValueRef.Invoke(val)}");
				ValuableObjectValuePatch.Action(val);
			}
		}
	}
	[HarmonyPatch(typeof(SurplusValuable), "Start")]
	public class SurplusValuableValuePatch : SpawnedValuableValuePatch<SurplusValuable>
	{
		internal static void Prefix(SurplusValuable __instance)
		{
			if (SLRUpgradePack.ObjectValueUpgradeInstance.UpgradeScalesSurplus.Value && SLRUpgradePack.ObjectValueUpgradeInstance.UpgradeEnabled.Value)
			{
				SpawnedValuableValuePatch<SurplusValuable>.DoValuableStuff(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyValuable), "Start")]
	public class EnemyValuableValuePatch : SpawnedValuableValuePatch<EnemyValuable>
	{
		internal static void Prefix(EnemyValuable __instance)
		{
			SpawnedValuableValuePatch<EnemyValuable>.DoValuableStuff(__instance);
		}
	}
	public class OverchargeUpgrade : UpgradeBase<float>
	{
		public OverchargeUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier)
			: base("Overcharge", "assets/repo/mods/resources/items/items/item upgrade overcharge.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatReduce(this, "Overcharge", value, player, level);
		}
	}
	[HarmonyPatch(typeof(PhysGrabber))]
	public class PhysGrabberPatch
	{
		public static bool Prepare()
		{
			return typeof(PhysGrabber).GetMethods().Any((MethodInfo method) => method.Name.Equals("PhysGrabOverCharge"));
		}

		[HarmonyPatch("PhysGrabOverCharge")]
		private static void Prefix(PhysGrabber __instance, ref float _amount)
		{
			OverchargeUpgrade overchargeUpgradeInstance = SLRUpgradePack.OverchargeUpgradeInstance;
			if (overchargeUpgradeInstance.UpgradeEnabled.Value)
			{
				SLRUpgradePack.Logger.LogDebug((object)$"Original overcharge amount: {_amount}");
				_amount = overchargeUpgradeInstance.Calculate(_amount, __instance.playerAvatar, overchargeUpgradeInstance.UpgradeRegister.GetLevel(__instance.playerAvatar));
				SLRUpgradePack.Logger.LogDebug((object)$"After calculation with level {overchargeUpgradeInstance.UpgradeRegister.GetLevel(__instance.playerAvatar)}: {_amount}");
			}
		}
	}
	public class RegenerationComponent : MonoBehaviour
	{
		internal PlayerAvatar player;

		private float pendingHealing;

		private FieldRef<PlayerHealth, int>? _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health");

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			RegenerationUpgrade regenerationUpgradeInstance = SLRUpgradePack.RegenerationUpgradeInstance;
			if (ValuableDirector.instance.setupComplete && regenerationUpgradeInstance.UpgradeEnabled.Value && regenerationUpgradeInstance.UpgradeRegister.GetLevel(player) != 0 && _healthRef.Invoke(player.playerHealth) != 0)
			{
				pendingHealing += regenerationUpgradeInstance.Calculate(regenerationUpgradeInstance.BaseHealing.Value * Time.deltaTime, player, regenerationUpgradeInstance.UpgradeRegister.GetLevel(player));
				if (pendingHealing >= 1f)
				{
					player.playerHealth.HealOther((int)Math.Floor(pendingHealing), false);
					pendingHealing -= Mathf.Floor(pendingHealing);
				}
			}
		}
	}
	public class RegenerationUpgrade : UpgradeBase<float>
	{
		public ConfigEntry<float> BaseHealing { get; protected set; }

		public RegenerationUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float baseHealing, float priceMultiplier)
			: base("Regeneration", "assets/repo/mods/resources/items/items/item upgrade regeneration.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			BaseHealing = config.Bind<float>("Regeneration Upgrade", "Base Healing", baseHealing, new ConfigDescription("Base Healing Amount", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "Regeneration", value, player, level);
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			base.InitUpgrade(player, level);
			RegenerationComponent regenerationComponent = default(RegenerationComponent);
			if (!((Component)player).TryGetComponent<RegenerationComponent>(ref regenerationComponent))
			{
				regenerationComponent = ((Component)player).gameObject.AddComponent<RegenerationComponent>();
				regenerationComponent.player = player;
			}
		}
	}
	public abstract class UpgradeBase<T>
	{
		public ConfigEntry<bool> UpgradeEnabled { get; protected set; }

		public ConfigEntry<T> UpgradeAmount { get; protected set; }

		public ConfigEntry<bool> UpgradeExponential { get; protected set; }

		public ConfigEntry<T> UpgradeExpAmount { get; protected set; }

		public ConfigEntry<float> PriceMultiplier { get; protected set; }

		public ConfigEntry<int> StartingAmount { get; protected set; }

		public PlayerUpgrade UpgradeRegister { get; protected set; }

		protected UpgradeBase(string name, string assetName, bool enabled, T upgradeAmount, bool exponential, T exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, bool configureAmount, int minPrice, int maxPrice, bool canBeExponential, bool singleUse)
		{
			UpgradeEnabled = config.Bind<bool>(name + " Upgrade", "Enabled", enabled, "Should the " + name + " Upgrade be enabled?");
			PriceMultiplier = config.Bind<float>(name + " Upgrade", "Price multiplier", priceMultiplier, "Multiplier of upgrade base price");
			StartingAmount = config.Bind<int>(name + " Upgrade", "Starting Amount", 0, "How many levels of " + name + " to start a game with");
			if (configureAmount)
			{
				UpgradeAmount = config.Bind<T>(name + " Upgrade", name + " Upgrade Power", upgradeAmount, "How much the " + name + " Upgrade increments");
				if (canBeExponential)
				{
					UpgradeExponential = config.Bind<bool>(name + " Upgrade", "Exponential upgrade", exponential, "Should the " + name + " Upgrade stack exponentially?");
					UpgradeExpAmount = config.Bind<T>(name + " Upgrade", name + " Upgrade Exponential Power", exponentialAmount, "How much the Exponential " + name + " upgrade increments");
				}
			}
			if (UpgradeEnabled.Value)
			{
				Item val = assetBundle.LoadAsset<Item>(assetName);
				SLRUpgradePack.Logger.LogInfo((object)$"Upgrade price range (default) {val.value.valueMin} - {val.value.valueMax}");
				Value val2 = ScriptableObject.CreateInstance<Value>();
				val2.valueMin = val.value.valueMin * PriceMultiplier.Value;
				val2.valueMax = val.value.valueMax * PriceMultiplier.Value;
				val.value = val2;
				Items.RegisterItem(val);
				UpgradeRegister = Upgrades.RegisterUpgrade(name.Replace(" ", ""), val, (Action<PlayerAvatar, int>)InitUpgrade, (Action<PlayerAvatar, int>)UseUpgrade);
			}
		}

		internal virtual void InitUpgrade(PlayerAvatar player, int level)
		{
			GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: false);
			if (Traverse.Create((object)player).Field<bool>("isLocal").Value)
			{
				SLRUpgradePack.Logger.LogInfo((object)("Init: " + string.Join(",", from kvp in UpgradeRegister.PlayerDictionary
					where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null
					select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value))));
			}
		}

		internal void UseUpgrade(PlayerAvatar player, int level)
		{
			if (Traverse.Create((object)player).Field<bool>("isLocal").Value)
			{
				SLRUpgradePack.Logger.LogInfo((object)("Used: " + string.Join(",", from kvp in UpgradeRegister.PlayerDictionary
					where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null
					select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value))));
			}
		}

		public abstract T Calculate(T value, PlayerAvatar player, int level);

		public static float DefaultCalculateFloatReduce(UpgradeBase<float> instance, string name, float value, PlayerAvatar player, int level)
		{
			if (level > 0)
			{
				if (instance.UpgradeExponential.Value)
				{
					return (float)((double)value / Math.Pow(instance.UpgradeExpAmount.Value, level));
				}
				return value / (1f + instance.UpgradeAmount.Value * (float)level);
			}
			return value;
		}

		public static float DefaultCalculateFloatIncrease(UpgradeBase<float> instance, string name, float value, PlayerAvatar player, int level)
		{
			if (level > 0)
			{
				if (instance.UpgradeExponential.Value)
				{
					return (float)((double)value * Math.Pow(instance.UpgradeExpAmount.Value, level));
				}
				return value * (1f + instance.UpgradeAmount.Value * (float)level);
			}
			return value;
		}

		protected GameObject GetVisualsFromComponent(Component component)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			GameObject val = null;
			if (((object)component).GetType() == typeof(EnemyParent))
			{
				EnemyParent val2 = (EnemyParent)(object)((component is EnemyParent) ? component : null);
				Enemy val3 = (Enemy)AccessTools.Field(typeof(EnemyParent), "Enemy").GetValue(component);
				try
				{
					val = ((Component)val2.EnableObject.gameObject.GetComponentInChildren<Animator>()).gameObject;
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					try
					{
						val = ((Component)((Component)val3).GetComponent<EnemyVision>().VisionTransform).gameObject;
					}
					catch
					{
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)val3).gameObject;
				}
			}
			else if (((object)component).GetType() == typeof(PlayerAvatar))
			{
				val = ((Component)((PlayerAvatar)((component is PlayerAvatar) ? component : null)).playerAvatarVisuals).gameObject;
			}
			return val;
		}
	}
	public class EnumeratorWrapper : IEnumerable
	{
		public IEnumerator enumerator;

		public Action? prefixAction;

		public Action? postfixAction;

		public Action<object>? preItemAction;

		public Action<object>? postItemAction;

		public Func<object, object>? itemAction;

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

		public IEnumerator GetEnumerator()
		{
			prefixAction?.Invoke();
			while (enumerator.MoveNext())
			{
				object item = enumerator.Current;
				preItemAction?.Invoke(item);
				if (itemAction != null)
				{
					yield return itemAction(item);
				}
				else
				{
					yield return item;
				}
				postItemAction?.Invoke(item);
			}
			postfixAction?.Invoke();
		}
	}
	[HarmonyPatch(typeof(StatsManager), "FetchPlayerUpgrades")]
	public class StatsManagerPatch
	{
		private static bool Prefix(StatsManager __instance, ref string _steamID, ref Dictionary<string, int> __result)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			Regex regex = new Regex("(?<!^)(?=[A-Z])");
			foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in __instance.dictionaryOfDictionaries)
			{
				if (!dictionaryOfDictionary.Key.StartsWith("playerUpgrade") || !dictionaryOfDictionary.Value.ContainsKey(_steamID))
				{
					continue;
				}
				string text = "";
				string[] array = regex.Split(dictionaryOfDictionary.Key);
				bool flag = false;
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					if (flag)
					{
						text = text + text2 + " ";
					}
					if (text2 == "Upgrade")
					{
						flag = true;
					}
				}
				text = text.Replace("Modded", "").Trim();
				if (text.Length != 0)
				{
					int num = dictionaryOfDictionary.Value[_steamID];
					if (dictionary.TryGetValue(text, out var value))
					{
						SLRUpgradePack.Logger.LogWarning((object)$"Duplicate upgrade found [{text}: {value} => {num}]");
					}
					dictionary[text] = num;
				}
			}
			__result = dictionary;
			return false;
		}
	}
	public class ValuableDensityUpgrade : UpgradeBase<float>
	{
		public List<AnimationCurve> TotalMaxAmountCurves { get; set; }

		public List<AnimationCurve> TotalMaxValueCurves { get; set; }

		public List<AnimationCurve> TinyCurves { get; set; }

		public List<AnimationCurve> SmallCurves { get; set; }

		public List<AnimationCurve> MediumCurves { get; set; }

		public List<AnimationCurve> BigCurves { get; set; }

		public List<AnimationCurve> WideCurves { get; set; }

		public List<AnimationCurve> TallCurves { get; set; }

		public List<AnimationCurve> VeryTallCurves { get; set; }

		public ValuableDensityUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier)
			: base("Valuable Density", "assets/repo/mods/resources/items/items/item upgrade valuable density.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, 2000, 100000, canBeExponential: true, singleUse: false)
		{
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ValuableDensity", value, player, level);
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	public class LevelGeneratorPatch
	{
		private delegate float difficultyDelegate();

		private static bool initialized;

		private static void Prefix(LevelGenerator __instance)
		{
			ValuableDensityUpgrade valuableDensityUpgrade = SLRUpgradePack.ValuableDensityUpgradeInstance;
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !valuableDensityUpgrade.UpgradeEnabled.Value)
			{
				return;
			}
			SLRUpgradePack.Logger.LogInfo((object)"Valuable Density Upgrade runs HERE");
			if (!initialized)
			{
				valuableDensityUpgrade.TinyCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tinyMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.SmallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "smallMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.MediumCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "mediumMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.BigCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "bigMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.WideCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "wideMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.TallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tallMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.VeryTallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "veryTallMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.TotalMaxAmountCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxAmountCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				valuableDensityUpgrade.TotalMaxValueCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxValueCurve", 10)
					select re.Invoke(ValuableDirector.instance)).ToList();
				initialized = true;
			}
			List<difficultyDelegate> staticNumberedMethodDelegates = GetStaticNumberedMethodDelegates<difficultyDelegate>(typeof(SemiFunc), "RunGetDifficultyMultiplier", Array.Empty<Type>(), 10);
			foreach (string item in valuableDensityUpgrade.TotalMaxAmountCurves.Zip(staticNumberedMethodDelegates, (AnimationCurve curve, difficultyDelegate difficulty) => $"Probably applying valuable density upgrade to {curve.Evaluate(difficulty())}"))
			{
				SLRUpgradePack.Logger.LogInfo((object)item);
			}
			Traverse val = Traverse.Create((object)ValuableDirector.instance).Field("totalMaxAmount");
			if (valuableDensityUpgrade.UpgradeRegister != null && valuableDensityUpgrade.UpgradeRegister.PlayerDictionary != null)
			{
				foreach (KeyValuePair<string, int> pair in valuableDensityUpgrade.UpgradeRegister.PlayerDictionary)
				{
					if (valuableDensityUpgrade.TotalMaxAmountCurves.Count != 0)
					{
						SLRUpgradePack.Logger.LogInfo((object)"Replacing Max Amount curve");
						foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item2 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
							where value.Item1.Item1 != null && value.Item1.Item2 != null
							select value)
						{
							item2.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TotalMaxAmountCurves[item2.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
						}
					}
					else
					{
						SLRUpgradePack.Logger.LogInfo((object)"Setting Max Amount");
						val.SetValue((object)(int)Math.Ceiling(valuableDensityUpgrade.Calculate(val.GetValue<int>(), SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value)));
					}
					if (valuableDensityUpgrade.TotalMaxValueCurves.Count != 0)
					{
						SLRUpgradePack.Logger.LogInfo((object)"Replacing Max Value curve");
						foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item3 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxValueCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
							where value.Item1.Item1 != null && value.Item1.Item2 != null
							select value)
						{
							item3.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TotalMaxValueCurves[item3.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
						}
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Tiny Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item4 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tinyMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item4.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TinyCurves[item4.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Small Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item5 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "smallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item5.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.SmallCurves[item5.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Medium Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item6 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "mediumMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item6.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.MediumCurves[item6.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Big Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item7 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "bigMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item7.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.BigCurves[item7.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Wide Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item8 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "wideMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item8.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.WideCurves[item8.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Tall Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item9 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item9.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TallCurves[item9.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
					SLRUpgradePack.Logger.LogInfo((object)"Replacing Very Tall Max Amount curve");
					foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item10 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "veryTallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index))
						where value.Item1.Item1 != null && value.Item1.Item2 != null
						select value)
					{
						item10.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.VeryTallCurves[item10.Item2], (float value) => valuableDensityUpgrade.Calculate(value, SemiFunc.PlayerGetFromSteamID(pair.Key), pair.Value));
					}
				}
			}
			SLRUpgradePack.Logger.LogDebug((object)$"Total max items: {val.GetValue<int>()}");
		}

		private static AnimationCurve ReplaceCurve(AnimationCurve target, Func<float, float> calculate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			AnimationCurve val = new AnimationCurve();
			val.CopyFrom(target);
			val.ClearKeys();
			Keyframe[] keys = target.GetKeys();
			for (int i = 0; i < keys.Length; i++)
			{
				Keyframe val2 = keys[i];
				Keyframe val3 = val2;
				((Keyframe)(ref val3)).value = calculate(((Keyframe)(ref val2)).value);
				Keyframe val4 = val3;
				SLRUpgradePack.Logger.LogDebug((object)$"Increased step at {((Keyframe)(ref val4)).time} from {((Keyframe)(ref val2)).value} to {((Keyframe)(ref val4)).value}");
				val.AddKey(val4);
			}
			return val;
		}

		private static List<FieldRef<S, T>> GetNumberedFieldRefs<S, T>(S source, string expectedBaseName, int checkMax, int checkMin = 0)
		{
			List<FieldRef<S, T>> list = new List<FieldRef<S, T>>();
			if (Traverse.Create((object)source).Field(expectedBaseName).FieldExists())
			{
				list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName));
			}
			for (int i = checkMin; i < checkMax; i++)
			{
				if (Traverse.Create((object)source).Field(expectedBaseName + i).FieldExists())
				{
					list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName + i));
				}
			}
			return list;
		}

		private static List<T> GetNumberedMethodDelegates<S, T>(S source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) where T : Delegate
		{
			List<T> list = new List<T>();
			if (Traverse.Create((object)source).Method(expectedBaseName, parameters, (object[])null).MethodExists())
			{
				list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(typeof(S), expectedBaseName, parameters, (Type[])null), (object)source, true));
			}
			for (int i = checkMin; i < checkMax; i++)
			{
				if (Traverse.Create((object)source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists())
				{
					list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(typeof(S), expectedBaseName + i, parameters, (Type[])null), (object)source, true));
				}
			}
			return list;
		}

		private static List<T> GetStaticNumberedMethodDelegates<T>(Type source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) where T : Delegate
		{
			List<T> list = new List<T>();
			if (Traverse.Create(source).Method(expectedBaseName, parameters, (object[])null).MethodExists())
			{
				list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName, parameters, (Type[])null), (object)source, true));
			}
			for (int i = checkMin; i < checkMax; i++)
			{
				if (Traverse.Create(source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists())
				{
					list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName + i, parameters, (Type[])null), (object)source, true));
				}
			}
			return list;
		}
	}
}
namespace SLRUpgradePack.UpgradeManagers.MoreUpgrades
{
	internal class IntegrationResource
	{
		public static AssetBundle moreBundle = AssetBundle.LoadFromMemory(Resources.moreupgrades);
	}
	[HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")]
	public class ShopManagerSingleUsePatch
	{
		private static void Prefix(ShopManager __instance)
		{
			foreach (Item value in StatsManager.instance.itemDictionary.Values)
			{
				if (new List<string>(3) { "Item Upgrade Map Enemy Tracker", "Item Upgrade Map Player Tracker", "Item Upgrade Map Value Tracker" }.Contains(value.itemAssetName))
				{
					value.maxPurchaseAmount = GameDirector.instance.PlayerList.Count;
				}
			}
		}
	}
	public class EnemyTrackerComponent : MonoBehaviour
	{
		private void Update()
		{
			SLRUpgradePack.MapEnemyTrackerUpgradeInstance.UpdateTracker();
		}
	}
	public class MapEnemyTrackerUpgrade : UpgradeBase<int>
	{
		private List<(GameObject, Color, float)> addToMap = new List<(GameObject, Color, float)>();

		private List<GameObject> removeFromMap = new List<GameObject>();

		private AssetBundle assetBundle;

		private EnemyTrackerComponent enemyTrackerComponent;

		public ConfigEntry<bool> ArrowIcon { get; set; }

		public ConfigEntry<Color> TrackerColor { get; set; }

		public ConfigEntry<string> ExcludeEnemies { get; set; }

		public MapEnemyTrackerUpgrade(bool enabled, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, bool arrowIcon, Color trackerColor, string excludeEnemies, int minPrice, int maxPrice)
			: base("Map Enemy Tracker", "assets/repo/mods/resources/items/items/item upgrade map enemy tracker.asset", enabled, 1, exponential: false, 1, config, assetBundle, priceMultiplier, configureAmount: false, minPrice, maxPrice, canBeExponential: false, singleUse: true)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			ArrowIcon = config.Bind<bool>("Map Enemy Tracker Upgrade", "Arrow Icon", arrowIcon, "Whether the icon should appear as an arrow showing direction instead of a dot.");
			TrackerColor = config.Bind<Color>("Map Enemy Tracker Upgrade", "Color", trackerColor, "The color of the icon.");
			ExcludeEnemies = config.Bind<string>("Map Enemy Tracker Upgrade", "Exclude Enemies", excludeEnemies, "Exclude specific enemies from displaying their icon by listing their names.\nExample: 'Gnome, Clown', seperated by commas.");
			this.assetBundle = assetBundle;
		}

		public override int Calculate(int value, PlayerAvatar player, int level)
		{
			throw new NotImplementedException();
		}

		internal void AddEnemyToMap(Component component, string enemyName = null)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if (base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			EnemyParent val = (EnemyParent)(object)((component is EnemyParent) ? component : null);
			if (val != null && enemyName == null)
			{
				enemyName = val.enemyName;
			}
			if ((from x in ExcludeEnemies.Value.Split(',')
				select x.Trim() into x
				where !string.IsNullOrEmpty(x)
				select x).Contains(enemyName))
			{
				return;
			}
			GameObject visuals = GetVisualsFromComponent(component);
			if (!((Object)(object)visuals == (Object)null) && !addToMap.Any<(GameObject, Color, float)>(((GameObject, Color, float) x) => (Object)(object)x.Item1 == (Object)(object)visuals))
			{
				if (removeFromMap.Contains(visuals))
				{
					removeFromMap.Remove(visuals);
				}
				addToMap.Add((visuals, TrackerColor.Value, (enemyName == "Animal") ? 180 : 0));
			}
		}

		internal void RemoveEnemyFromMap(Component component, string enemyName = null)
		{
			if (base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			EnemyParent val = (EnemyParent)(object)((component is EnemyParent) ? component : null);
			if (val != null && enemyName == null)
			{
				enemyName = val.enemyName;
			}
			if ((from x in ExcludeEnemies.Value.Split(',')
				select x.Trim() into x
				where !string.IsNullOrEmpty(x)
				select x).Contains(enemyName))
			{
				return;
			}
			GameObject visuals = GetVisualsFromComponent(component);
			if ((Object)(object)visuals == (Object)null || removeFromMap.Contains(visuals))
			{
				return;
			}
			if (addToMap.Any<(GameObject, Color, float)>(((GameObject, Color, float) x) => (Object)(object)x.Item1 == (Object)(object)visuals))
			{
				addToMap.RemoveAll(((GameObject, Color, float) x) => (Object)(object)x.Item1 == (Object)(object)visuals);
			}
			removeFromMap.Add(visuals);
		}

		internal void UpdateTracker()
		{
			//IL_004d: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)null) || base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) <= 0)
			{
				return;
			}
			for (int num = addToMap.Count - 1; num >= 0; num--)
			{
				var (val, color, num2) = addToMap[num];
				addToMap.RemoveAt(num);
				MapCustom component = val.GetComponent<MapCustom>();
				if (!((Object)(object)component != (Object)null))
				{
					component = val.AddComponent<MapCustom>();
					component.color = color;
					component.sprite = (ArrowIcon.Value ? IntegrationResource.moreBundle.LoadAsset<Sprite>("Map Tracker") : SemiFunc.PlayerAvatarLocal().playerDeathHead.mapCustom.sprite);
					((Component)component).transform.RotateAround(((Component)component).transform.position, Vector3.up, num2);
				}
			}
			for (int num3 = removeFromMap.Count - 1; num3 >= 0; num3--)
			{
				GameObject obj = removeFromMap[num3];
				removeFromMap.RemoveAt(num3);
				MapCustom component2 = obj.GetComponent<MapCustom>();
				if (!((Object)(object)component2 == (Object)null))
				{
					Object.Destroy((Object)(object)((Component)component2.mapCustomEntity).gameObject);
					Object.Destroy((Object)(object)component2);
				}
			}
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			if ((Object)(object)enemyTrackerComponent != (Object)null)
			{
				Object.Destroy((Object)(object)enemyTrackerComponent);
			}
			enemyTrackerComponent = new GameObject().AddComponent<EnemyTrackerComponent>();
		}
	}
	[HarmonyPatch(typeof(EnemyParent))]
	internal class EnemyParentPatch
	{
		[HarmonyPatch("SpawnRPC")]
		[HarmonyPostfix]
		private static void SpawnRPC(EnemyParent __instance)
		{
			MapEnemyTrackerUpgrade mapEnemyTrackerUpgradeInstance = SLRUpgradePack.MapEnemyTrackerUpgradeInstance;
			if (mapEnemyTrackerUpgradeInstance.UpgradeEnabled.Value && mapEnemyTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapEnemyTrackerUpgradeInstance.AddEnemyToMap((Component)(object)__instance);
			}
		}

		[HarmonyPatch("DespawnRPC")]
		[HarmonyPostfix]
		private static void DespawnRPC(EnemyParent __instance)
		{
			MapEnemyTrackerUpgrade mapEnemyTrackerUpgradeInstance = SLRUpgradePack.MapEnemyTrackerUpgradeInstance;
			if (mapEnemyTrackerUpgradeInstance.UpgradeEnabled.Value && mapEnemyTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapEnemyTrackerUpgradeInstance.RemoveEnemyFromMap((Component)(object)__instance);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth))]
	internal class EnemyHealthPatch
	{
		[HarmonyPatch("DeathRPC")]
		[HarmonyPostfix]
		private static void DeathRPC(EnemyHealth __instance, Enemy ___enemy)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			MapEnemyTrackerUpgrade mapEnemyTrackerUpgradeInstance = SLRUpgradePack.MapEnemyTrackerUpgradeInstance;
			if (mapEnemyTrackerUpgradeInstance.UpgradeEnabled.Value && mapEnemyTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapEnemyTrackerUpgradeInstance.RemoveEnemyFromMap((Component)(EnemyParent)AccessTools.Field(typeof(Enemy), "EnemyParent").GetValue(___enemy));
			}
		}
	}
	[HarmonyPatch(typeof(EnemySlowMouth))]
	internal class EnemySlowMouthPatch
	{
		[HarmonyPatch("UpdateStateRPC")]
		[HarmonyPostfix]
		private static void UpdateStateRPC(EnemySlowMouth __instance, Enemy ___enemy)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			MapEnemyTrackerUpgrade mapEnemyTrackerUpgradeInstance = SLRUpgradePack.MapEnemyTrackerUpgradeInstance;
			MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
			if (!mapEnemyTrackerUpgradeInstance.UpgradeEnabled.Value || mapEnemyTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			PlayerAvatar val = (PlayerAvatar)AccessTools.Field(typeof(EnemySlowMouth), "playerTarget").GetValue(__instance);
			EnemyParent val2 = (EnemyParent)AccessTools.Field(typeof(Enemy), "EnemyParent").GetValue(___enemy);
			State currentState = __instance.currentState;
			if ((int)currentState == 9)
			{
				mapEnemyTrackerUpgradeInstance.RemoveEnemyFromMap((Component)(object)val2);
				if (!((Object)(object)val == (Object)(object)SemiFunc.PlayerAvatarLocal()))
				{
					mapPlayerTrackerUpgradeInstance.RemovePlayerFromMap(val);
					mapEnemyTrackerUpgradeInstance.AddEnemyToMap((Component)(object)val, val2.enemyName);
				}
			}
			else if ((int)currentState == 11)
			{
				mapEnemyTrackerUpgradeInstance.AddEnemyToMap((Component)(object)val2);
				if (!((Object)(object)val == (Object)(object)SemiFunc.PlayerAvatarLocal()))
				{
					mapPlayerTrackerUpgradeInstance.AddPlayerToMap(val);
					mapEnemyTrackerUpgradeInstance.RemoveEnemyFromMap((Component)(object)val, val2.enemyName);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal class PlayerAvatarEnemyPatch
	{
		[HarmonyPatch("PlayerDeathRPC")]
		[HarmonyPostfix]
		private static void PlayerDeathRPC(PlayerAvatar __instance)
		{
			MapEnemyTrackerUpgrade mapEnemyTrackerUpgradeInstance = SLRUpgradePack.MapEnemyTrackerUpgradeInstance;
			if (mapEnemyTrackerUpgradeInstance.UpgradeEnabled.Value && mapEnemyTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapEnemyTrackerUpgradeInstance.RemoveEnemyFromMap((Component)(object)__instance);
			}
		}
	}
	public class PlayerTrackerComponent : MonoBehaviour
	{
		private void Update()
		{
			SLRUpgradePack.MapPlayerTrackerUpgradeInstance.UpdateTracker();
		}
	}
	public class MapPlayerTrackerUpgrade : UpgradeBase<int>
	{
		private List<(GameObject, Color)> addToMap = new List<(GameObject, Color)>();

		private List<GameObject> removeFromMap = new List<GameObject>();

		private AssetBundle assetBundle;

		private PlayerTrackerComponent playerTrackerComponent;

		public ConfigEntry<bool> ArrowIcon { get; set; }

		public ConfigEntry<bool> PlayerColor { get; set; }

		public ConfigEntry<Color> TrackerColor { get; set; }

		public MapPlayerTrackerUpgrade(bool enabled, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, bool arrowIcon, Color trackerColor, int minPrice, int maxPrice, bool playerColor)
			: base("Map Player Tracker", "assets/repo/mods/resources/items/items/item upgrade map player tracker.asset", enabled, 1, exponential: false, 1, config, assetBundle, priceMultiplier, configureAmount: false, minPrice, maxPrice, canBeExponential: true, singleUse: true)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			ArrowIcon = config.Bind<bool>("Map Player Tracker Upgrade", "Arrow Icon", arrowIcon, "Whether the icon should appear as an arrow showing direction instead of a dot.");
			PlayerColor = config.Bind<bool>("Map Player Tracker Upgrade", "Player Color", playerColor, "Whether the icon should be colored as the player.");
			TrackerColor = config.Bind<Color>("Map Player Tracker Upgrade", "Color", trackerColor, "The color of the icon.");
			this.assetBundle = assetBundle;
		}

		public override int Calculate(int value, PlayerAvatar player, int level)
		{
			throw new NotImplementedException();
		}

		internal void AddPlayerToMap(PlayerAvatar playerAvatar)
		{
			//IL_0079: 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_00bd: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			GameObject visuals = GetVisualsFromComponent((Component)(object)playerAvatar);
			if (!((Object)(object)visuals == (Object)null) && !addToMap.Any<(GameObject, Color)>(((GameObject, Color) x) => (Object)(object)x.Item1 == (Object)(object)visuals))
			{
				if (removeFromMap.Contains(visuals))
				{
					removeFromMap.Remove(visuals);
				}
				Color item = TrackerColor.Value;
				if (PlayerColor.Value)
				{
					item = (Color)AccessTools.Field(typeof(PlayerAvatarVisuals), "color").GetValue(playerAvatar.playerAvatarVisuals);
				}
				addToMap.Add((visuals, item));
			}
		}

		internal void RemovePlayerFromMap(PlayerAvatar playerAvatar)
		{
			if (base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			GameObject visuals = GetVisualsFromComponent((Component)(object)playerAvatar);
			if ((Object)(object)visuals == (Object)null || removeFromMap.Contains(visuals))
			{
				return;
			}
			if (addToMap.Any<(GameObject, Color)>(((GameObject, Color) x) => (Object)(object)x.Item1 == (Object)(object)visuals))
			{
				addToMap.RemoveAll(((GameObject, Color) x) => (Object)(object)x.Item1 == (Object)(object)visuals);
			}
			removeFromMap.Add(visuals);
		}

		internal void UpdateTracker()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)null) || base.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) <= 0)
			{
				return;
			}
			for (int num = addToMap.Count - 1; num >= 0; num--)
			{
				var (val, color) = addToMap[num];
				addToMap.RemoveAt(num);
				if (!((Object)(object)val.GetComponent<MapCustom>() != (Object)null))
				{
					MapCustom obj = val.AddComponent<MapCustom>();
					obj.color = color;
					obj.sprite = (ArrowIcon.Value ? IntegrationResource.moreBundle.LoadAsset<Sprite>("Map Tracker") : SemiFunc.PlayerAvatarLocal().playerDeathHead.mapCustom.sprite);
				}
			}
			for (int num2 = removeFromMap.Count - 1; num2 >= 0; num2--)
			{
				GameObject obj2 = removeFromMap[num2];
				removeFromMap.RemoveAt(num2);
				MapCustom component = obj2.GetComponent<MapCustom>();
				if (!((Object)(object)component == (Object)null))
				{
					Object.Destroy((Object)(object)((Component)component.mapCustomEntity).gameObject);
					Object.Destroy((Object)(object)component);
				}
			}
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			if ((Object)(object)playerTrackerComponent != (Object)null)
			{
				Object.Destroy((Object)(object)playerTrackerComponent);
			}
			playerTrackerComponent = new GameObject().AddComponent<PlayerTrackerComponent>();
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal class PlayerAvatarPatch
	{
		[HarmonyPatch(typeof(ModdedColorPlayerAvatar))]
		internal class ModdedColorPlayerAvatarPatch
		{
			public static bool Prepare()
			{
				return Chainloader.PluginInfos.ContainsKey("x753.CustomColors");
			}

			[HarmonyPatch("ModdedSetColorRPC")]
			private static void Postfix(ModdedColorPlayerAvatar __instance)
			{
				MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
				if (mapPlayerTrackerUpgradeInstance.UpgradeEnabled.Value && mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
				{
					PlayerAvatar avatar = __instance.avatar;
					if (mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) > 0 && mapPlayerTrackerUpgradeInstance.PlayerColor.Value)
					{
						mapPlayerTrackerUpgradeInstance.RemovePlayerFromMap(avatar);
						mapPlayerTrackerUpgradeInstance.AddPlayerToMap(avatar);
					}
				}
			}
		}

		[HarmonyPatch("LateStart")]
		[HarmonyPostfix]
		private static void LateStart(PlayerAvatar __instance)
		{
			MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
			if (mapPlayerTrackerUpgradeInstance.UpgradeEnabled.Value && mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapPlayerTrackerUpgradeInstance.AddPlayerToMap(__instance);
			}
		}

		[HarmonyPatch("ReviveRPC")]
		[HarmonyPostfix]
		private static void ReviveRPC(PlayerAvatar __instance)
		{
			MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
			if (mapPlayerTrackerUpgradeInstance.UpgradeEnabled.Value && mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapPlayerTrackerUpgradeInstance.AddPlayerToMap(__instance);
			}
		}

		[HarmonyPatch("PlayerDeathRPC")]
		[HarmonyPostfix]
		private static void PlayerDeathRPC(PlayerAvatar __instance)
		{
			MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
			if (mapPlayerTrackerUpgradeInstance.UpgradeEnabled.Value && mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				mapPlayerTrackerUpgradeInstance.RemovePlayerFromMap(__instance);
			}
		}

		[HarmonyPatch("SetColorRPC")]
		[HarmonyPostfix]
		private static void SetColorRPC(PlayerAvatar __instance)
		{
			MapPlayerTrackerUpgrade mapPlayerTrackerUpgradeInstance = SLRUpgradePack.MapPlayerTrackerUpgradeInstance;
			if (mapPlayerTrackerUpgradeInstance.UpgradeEnabled.Value && mapPlayerTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0 && mapPlayerTrackerUpgradeInstance.PlayerColor.Value)
			{
				mapPlayerTrackerUpgradeInstance.RemovePlayerFromMap(__instance);
				mapPlayerTrackerUpgradeInstance.AddPlayerToMap(__instance);
			}
		}
	}
	public class MapValueTrackerComponent : MonoBehaviour
	{
		private FieldRef<ValuableObject, float>? _dollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent");

		private void Update()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if (SemiFunc.RunIsLobby() || SemiFunc.RunIsShop())
			{
				return;
			}
			MapValueTrackerUpgrade mapValueTrackerUpgradeInstance = SLRUpgradePack.MapValueTrackerUpgradeInstance;
			if (!((Object)(object)MissionUI.instance != (Object)null) || mapValueTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) == 0)
			{
				return;
			}
			TextMeshProUGUI val = (TextMeshProUGUI)AccessTools.Field(typeof(MissionUI), "Text").GetValue(MissionUI.instance);
			_ = (string)AccessTools.Field(typeof(MissionUI), "messagePrev").GetValue(MissionUI.instance);
			int count = mapValueTrackerUpgradeInstance.currentValuables.Count;
			bool value = mapValueTrackerUpgradeInstance.DisplayTotalValue.Value;
			int num = (value ? mapValueTrackerUpgradeInstance.currentValuables.Select((ValuableObject x) => (int)_dollarValueCurrentRef.Invoke(x)).Sum() : 0);
			if (!Utility.IsNullOrWhiteSpace(((TMP_Text)val).text) && (mapValueTrackerUpgradeInstance.changed || mapValueTrackerUpgradeInstance.previousCount != count || mapValueTrackerUpgradeInstance.previousValue != num))
			{
				SLRUpgradePack.Logger.LogInfo((object)"Calculating map value");
				string text = ((TMP_Text)val).text;
				if (!mapValueTrackerUpgradeInstance.changed && (mapValueTrackerUpgradeInstance.previousCount != count || mapValueTrackerUpgradeInstance.previousValue != num))
				{
					text = text.Substring(0, text.Length - mapValueTrackerUpgradeInstance.textLength);
				}
				string text2 = $"\nValuables: <b>{count}</b>" + (value ? (" (<color=#558B2F>$</color><b>" + SemiFunc.DollarGetString(num) + "</b>)") : "");
				SLRUpgradePack.Logger.LogInfo((object)(text2 ?? ""));
				text += text2;
				mapValueTrackerUpgradeInstance.previousCount = count;
				mapValueTrackerUpgradeInstance.previousValue = num;
				mapValueTrackerUpgradeInstance.textLength = text2.Length;
				((TMP_Text)val).text = text;
				AccessTools.Field(typeof(MissionUI), "messagePrev").SetValue(MissionUI.instance, text);
				if (mapValueTrackerUpgradeInstance.changed)
				{
					mapValueTrackerUpgradeInstance.changed = false;
				}
			}
		}
	}
	public class MapValueTrackerUpgrade : UpgradeBase<int>
	{
		internal List<ValuableObject> currentValuables = new List<ValuableObject>();

		internal bool changed;

		internal int previousCount;

		internal int previousValue;

		internal int textLength;

		private MapValueTrackerComponent mapValueTrackerComponent;

		public ConfigEntry<bool> DisplayTotalValue { get; set; }

		public MapValueTrackerUpgrade(bool enabled, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, int minPrice, int maxPrice, bool displayTotal)
			: base("Map Value Tracker", "assets/repo/mods/resources/items/items/item upgrade map value tracker.asset", enabled, 1, exponential: false, 1, config, assetBundle, priceMultiplier, configureAmount: false, minPrice, maxPrice, canBeExponential: false, singleUse: true)
		{
			DisplayTotalValue = config.Bind<bool>("Map Value Tracker Upgrade", "Display Total Value", displayTotal, "Whether to display the total value next to the valuable counter.");
		}

		public override int Calculate(int value, PlayerAvatar player, int level)
		{
			throw new NotImplementedException();
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			changed = false;
			previousCount = 0;
			previousValue = 0;
			textLength = 0;
			if ((Object)(object)mapValueTrackerComponent != (Object)null)
			{
				Object.Destroy((Object)(object)mapValueTrackerComponent);
			}
			mapValueTrackerComponent = new GameObject().AddComponent<MapValueTrackerComponent>();
		}
	}
	[HarmonyPatch(typeof(MissionUI), "MissionText")]
	internal class MissionUIPatch
	{
		internal static void Prefix(MissionUI __instance, out string __state)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				__state = AccessTools.Field(typeof(MissionUI), "messagePrev").GetValue(__instance) as string;
			}
			else
			{
				__state = null;
			}
		}

		internal static void Postfix(MissionUI __instance, string __state)
		{
			string text = (((Object)(object)__instance == (Object)null) ? null : ((string)AccessTools.Field(typeof(MissionUI), "messagePrev").GetValue(__instance)));
			if (__state != text)
			{
				SLRUpgradePack.MapValueTrackerUpgradeInstance.changed = true;
			}
		}
	}
	[HarmonyPatch(typeof(ValuableObject))]
	internal class ValuableObjectTrackerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Start(ValuableObject __instance)
		{
			MapValueTrackerUpgrade mapValueTrackerUpgradeInstance = SLRUpgradePack.MapValueTrackerUpgradeInstance;
			if (mapValueTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				SLRUpgradePack.Logger.LogInfo((object)("Start tracking " + ((Object)__instance).name));
				if (!mapValueTrackerUpgradeInstance.currentValuables.Contains(__instance))
				{
					mapValueTrackerUpgradeInstance.currentValuables.Add(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject))]
	internal class PhysGrabObjectTrackerPatch
	{
		[HarmonyPatch("OnDestroy")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void OnDestroy(PhysGrabObject __instance)
		{
			MapValueTrackerUpgrade mapValueTrackerUpgradeInstance = SLRUpgradePack.MapValueTrackerUpgradeInstance;
			if (mapValueTrackerUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0)
			{
				ValuableObject component = ((Component)__instance).gameObject.GetComponent<ValuableObject>();
				if (mapValueTrackerUpgradeInstance.currentValuables.Contains(component))
				{
					mapValueTrackerUpgradeInstance.currentValuables.Remove(component);
				}
			}
		}
	}
	public class SprintUsageComponent : MonoBehaviour
	{
		private void FixedUpdate()
		{
			SprintUsageUpgrade sprintUsageUpgradeInstance = SLRUpgradePack.SprintUsageUpgradeInstance;
			if ((Object)(object)PlayerController.instance != (Object)null && sprintUsageUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()) != 0 && sprintUsageUpgradeInstance.originalEnergySprintDrain.HasValue)
			{
				PlayerController.instance.EnergySprintDrain = sprintUsageUpgradeInstance.Calculate(sprintUsageUpgradeInstance.originalEnergySprintDrain.Value, PlayerController.instance.playerAvatarScript, sprintUsageUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarLocal()));
			}
		}

		private void OnDestroy()
		{
			SprintUsageUpgrade sprintUsageUpgradeInstance = SLRUpgradePack.SprintUsageUpgradeInstance;
			if ((Object)(object)PlayerController.instance != (Object)null && sprintUsageUpgradeInstance.originalEnergySprintDrain.HasValue)
			{
				PlayerController.instance.EnergySprintDrain = sprintUsageUpgradeInstance.originalEnergySprintDrain.Value;
			}
		}
	}
	public class SprintUsageUpgrade : UpgradeBase<float>
	{
		internal float? originalEnergySprintDrain;

		private SprintUsageComponent sprintUsageComponent;

		public ConfigEntry<float> ScalingFactor { get; set; }

		public SprintUsageUpgrade(bool enabled, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, int minPrice, int maxPrice)
			: base("Sprint Usage", "assets/repo/mods/resources/items/items/item upgrade sprint usage.asset", enabled, 0.1f, exponential: false, 1.1f, config, assetBundle, priceMultiplier, configureAmount: false, minPrice, maxPrice, canBeExponential: false, singleUse: false)
		{
			ScalingFactor = config.Bind<float>("Sprint Usage Upgrade", "Scaling Factor", 0.1f, "Formula: energySprintDrain / (1 + (upgradeAmount * scalingFactor))");
		}

		public override float Calculate(float value, PlayerAvatar player, int level)
		{
			return value / (1f + (float)level * ScalingFactor.Value);
		}

		internal override void InitUpgrade(PlayerAvatar player, int level)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			base.InitUpgrade(player, level);
			if ((Object)(object)PlayerController.instance != (Object)null)
			{
				originalEnergySprintDrain = PlayerController.instance.EnergySprintDrain;
			}
			if ((Object)(object)sprintUsageComponent != (Object)null)
			{
				Object.Destroy((Object)(object)sprintUsageComponent);
			}
			sprintUsageComponent = new GameObject("Sprint Usage Component").AddComponent<SprintUsageComponent>();
		}
	}
}
namespace SLRUpgradePack.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	public class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static ResourceManager ResourceManager
		{
			get
			{
				if (object.Equals(null, resourceMan))
				{
					resourceMan = new ResourceManager("SLRUpgradePack.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		public static byte[] slr_assets => (byte[])ResourceManager.GetObject("slr_assets", resourceCulture);

		public static byte[] moreupgrades => (byte[])ResourceManager.GetObject("moreupgrades", resourceCulture);

		internal Resources()
		{
		}
	}
}