Decompiled source of PlayerLevels v0.0.5

PlayerLevels.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;

[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-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: AssemblyCompany("WAAAAGH")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.7")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PlayerLevels")]
[assembly: AssemblyTitle("PlayerLevels")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.7.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 PlayerLevels
{
	[BepInPlugin("WAAAAGH.PlayerLevels", "PlayerLevels", "1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PlayerLevels : BaseUnityPlugin
	{
		public static ConfigEntry<int> NumberOfUpgradesPerLevel;

		public static ConfigEntry<int> MaxStaminaGain;

		public static ConfigEntry<int> MaxHealthGain;

		public static ConfigEntry<int> MaxStrengthGain;

		public static ConfigEntry<int> MaxRangeGain;

		public static ConfigEntry<int> MaxSpeedGain;

		public static ConfigEntry<int> MaxJumpGain;

		public static ConfigEntry<int> MaxTumbleLaunchGain;

		public static ConfigEntry<float> DelayBeforeRegen;

		public static ConfigEntry<float> StaminaRegenPerLevel;

		public static ConfigEntry<float> HealthRegenPerLevel;

		public static ConfigEntry<int> BaseStaminaLevel;

		public static ConfigEntry<int> BaseHealthLevel;

		public static ConfigEntry<int> TumbleLevel1Damage;

		public static ConfigEntry<int> TumbleLevel2Damage;

		public static ConfigEntry<int> TumbleLevel3Damage;

		public static ConfigEntry<int> TumbleLevel4Damage;

		public static ConfigEntry<int> TumbleLevelNDamage;

		public static ConfigEntry<int> ExpGainedAnimal;

		public static ConfigEntry<int> ExpGainedRobe;

		public static ConfigEntry<int> ExpGainedUpscream;

		public static ConfigEntry<int> ExpGainedGnome;

		public static ConfigEntry<int> ExpGainedBang;

		public static ConfigEntry<int> ExpGainedHunter;

		public static ConfigEntry<int> ExpGainedBowtie;

		public static ConfigEntry<int> ExpGainedDuck;

		public static ConfigEntry<int> ExpGainedBeamer;

		public static ConfigEntry<int> ExpGainedTumbler;

		public static ConfigEntry<int> ExpGainedFloater;

		public static ConfigEntry<int> ExpGainedHidden;

		public static ConfigEntry<int> ExpGainedRunner;

		public static ConfigEntry<int> ExpGainedSlowMouth;

		public static ConfigEntry<int> ExpGainedSlowWalker;

		public static ConfigEntry<int> ExpGainedThinman;

		public static ConfigEntry<int> ExpGainedValuableThrower;

		public static ConfigEntry<int> ExpGainedCeilingEye;

		public static ConfigEntry<int> ExpNeededPerLevel;

		public static Dictionary<string, int> KillCounts = new Dictionary<string, int>();

		public static int LastLevelCount = 0;

		internal static PlayerLevels Instance { get; private set; } = null;


		internal static ManualLogSource Logger => Instance._logger;

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

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Expected O, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Expected O, but got Unknown
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Expected O, but got Unknown
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Expected O, but got Unknown
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Expected O, but got Unknown
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Expected O, but got Unknown
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Expected O, but got Unknown
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Expected O, but got Unknown
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Expected O, but got Unknown
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Expected O, but got Unknown
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Expected O, but got Unknown
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Expected O, but got Unknown
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Expected O, but got Unknown
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Expected O, but got Unknown
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Expected O, but got Unknown
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Expected O, but got Unknown
			//IL_0634: Expected O, but got Unknown
			NumberOfUpgradesPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Upgrades received per level up", 2, new ConfigDescription("How many upgrades a player receives when they level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxStaminaGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max stamina gain", 10, new ConfigDescription("Maximum stamina gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxHealthGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max health gain", 6, new ConfigDescription("Maximum health gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxStrengthGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max strength gain", 5, new ConfigDescription("Maximum strength gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxRangeGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max range gain", 4, new ConfigDescription("Maximum range gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxSpeedGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max speed gain", 3, new ConfigDescription("Maximum speed gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxJumpGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max jump gain", 4, new ConfigDescription("Maximum jump gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			MaxTumbleLaunchGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max tumble launch gain", 8, new ConfigDescription("Maximum tumble launch gain per level up", (AcceptableValueBase)null, Array.Empty<object>()));
			DelayBeforeRegen = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Delay before regen", 5f, new ConfigDescription("Delay before regen", (AcceptableValueBase)null, Array.Empty<object>()));
			StaminaRegenPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Stamina regen per level", 0.25f, new ConfigDescription("Stamina regen per level", (AcceptableValueBase)null, Array.Empty<object>()));
			HealthRegenPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Health regen per level", 0.1f, new ConfigDescription("Health regen per level", (AcceptableValueBase)null, Array.Empty<object>()));
			BaseStaminaLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Base stamina level", 2, new ConfigDescription("Base stamina level", (AcceptableValueBase)null, Array.Empty<object>()));
			BaseHealthLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Base health level", 1, new ConfigDescription("Base health level", (AcceptableValueBase)null, Array.Empty<object>()));
			TumbleLevel1Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 1 Tumble Damage", 20, (ConfigDescription)null);
			TumbleLevel2Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 2 Tumble Damage", 40, (ConfigDescription)null);
			TumbleLevel3Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 3 Tumble Damage", 60, (ConfigDescription)null);
			TumbleLevel4Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 4 Tumble Damage", 80, (ConfigDescription)null);
			TumbleLevelNDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Tumble Damage foreach level after 4", 10, (ConfigDescription)null);
			ExpGainedAnimal = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Animal Kill Exp", 25, new ConfigDescription("Experience gained for killing an Animal enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedRobe = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Robe Kill Exp", 50, new ConfigDescription("Experience gained for killing a Robe enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedUpscream = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Upscream Kill Exp", 25, new ConfigDescription("Experience gained for killing an Upscream enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedGnome = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Gnome Kill Exp", 5, new ConfigDescription("Experience gained for killing a Gnome enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedBang = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Bang Kill Exp", 5, new ConfigDescription("Experience gained for killing a Bang enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedHunter = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Hunter Kill Exp", 50, new ConfigDescription("Experience gained for killing a Hunter enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedBowtie = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Bowtie Kill Exp", 50, new ConfigDescription("Experience gained for killing a Bowtie enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedDuck = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Duck Kill Exp", 25, new ConfigDescription("Experience gained for killing a Duck enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedBeamer = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Beamer Kill Exp", 25, new ConfigDescription("Experience gained for killing a Beamer enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedTumbler = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Tumbler Kill Exp", 20, new ConfigDescription("Experience gained for killing a Tumbler enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedFloater = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Floater Kill Exp", 25, new ConfigDescription("Experience gained for killing a Floater enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedHidden = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Hidden Kill Exp", 35, new ConfigDescription("Experience gained for killing a Hidden enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedRunner = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Runner Kill Exp", 25, new ConfigDescription("Experience gained for killing a Runner enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedSlowMouth = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "SlowMouth Kill Exp", 15, new ConfigDescription("Experience gained for killing a SlowMouth enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedSlowWalker = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "SlowWalker Kill Exp", 100, new ConfigDescription("Experience gained for killing a SlowWalker enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedThinman = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Thinman Kill Exp", 35, new ConfigDescription("Experience gained for killing a Thinman enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedValuableThrower = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "ValuableThrower Kill Exp", 25, new ConfigDescription("Experience gained for killing a ValuableThrower enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpGainedCeilingEye = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "CeilingEye Kill Exp", 40, new ConfigDescription("Experience gained for killing a CeilingEye enemy", (AcceptableValueBase)null, Array.Empty<object>()));
			ExpNeededPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Exp needed to level", 100, new ConfigDescription("Experience needed to level up", (AcceptableValueBase)null, Array.Empty<object>()));
			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()
		{
		}

		public static int GetExpForEnemyType(string enemyType)
		{
			return enemyType switch
			{
				"Animal" => ExpGainedAnimal.Value, 
				"Robe" => ExpGainedRobe.Value, 
				"Upscream" => ExpGainedUpscream.Value, 
				"Gnome" => ExpGainedGnome.Value, 
				"Bang" => ExpGainedBang.Value, 
				"Hunter" => ExpGainedHunter.Value, 
				"Bowtie" => ExpGainedBowtie.Value, 
				"Duck" => ExpGainedDuck.Value, 
				"Beamer" => ExpGainedBeamer.Value, 
				"Tumbler" => ExpGainedTumbler.Value, 
				"Floater" => ExpGainedFloater.Value, 
				"Hidden" => ExpGainedHidden.Value, 
				"Runner" => ExpGainedRunner.Value, 
				"SlowMouth" => ExpGainedSlowMouth.Value, 
				"SlowWalker" => ExpGainedSlowWalker.Value, 
				"ThinMan" => ExpGainedThinman.Value, 
				"ValuableThrower" => ExpGainedValuableThrower.Value, 
				"CeilingEye" => ExpGainedCeilingEye.Value, 
				_ => 0, 
			};
		}

		public static int GetExpGainedFromKills()
		{
			int num = 0;
			string[] allTypes = ENEMY_TYPE_ENUM.GetAllTypes();
			foreach (string text in allTypes)
			{
				if (KillCounts.TryGetValue(text, out var value))
				{
					num += value * GetExpForEnemyType(text);
				}
			}
			return num;
		}
	}
	public static class CoroutimeManager
	{
	}
	public class PlayerAttributes
	{
		private Dictionary<string, int> attributes;

		public int Stamina
		{
			get
			{
				return attributes["Stamina"];
			}
			set
			{
				attributes["Stamina"] = value;
			}
		}

		public int Health
		{
			get
			{
				return attributes["Health"];
			}
			set
			{
				attributes["Health"] = value;
			}
		}

		public int Strength
		{
			get
			{
				return attributes["Strength"];
			}
			set
			{
				attributes["Strength"] = value;
			}
		}

		public int Range
		{
			get
			{
				return attributes["Range"];
			}
			set
			{
				attributes["Range"] = value;
			}
		}

		public int Speed
		{
			get
			{
				return attributes["Speed"];
			}
			set
			{
				attributes["Speed"] = value;
			}
		}

		public int TumbleLaunch
		{
			get
			{
				return attributes["Launch"];
			}
			set
			{
				attributes["Launch"] = value;
			}
		}

		public int ExtraJump
		{
			get
			{
				return attributes["Extra Jump"];
			}
			set
			{
				attributes["Extra Jump"] = value;
			}
		}

		public PlayerAttributes()
		{
			attributes = new Dictionary<string, int>
			{
				{ "Extra Jump", 0 },
				{ "Range", 0 },
				{ "Strength", 0 },
				{ "Health", 0 },
				{ "Speed", 0 },
				{ "Stamina", 0 },
				{ "Launch", 0 }
			};
		}

		public PlayerAttributes(Dictionary<string, int> existingAttributes)
		{
			attributes = new Dictionary<string, int>(existingAttributes);
		}

		public Dictionary<string, int> GetRawAttributes()
		{
			return new Dictionary<string, int>(attributes);
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	[HarmonyPatch("SpawnRPC")]
	public static class PlayerSpawnPatch
	{
		private static bool canUpgrade = false;

		private static List<Level> BLACK_LISTED_LEVELS = new List<Level>
		{
			RunManager.instance.levelLobby,
			RunManager.instance.levelLobbyMenu,
			RunManager.instance.levelMainMenu,
			RunManager.instance.levelShop,
			RunManager.instance.levelTutorial
		};

		private static string WeightedRandomSelection(Dictionary<string, int> remaining)
		{
			int num = remaining.Values.Sum();
			if (num == 0)
			{
				return "";
			}
			int num2 = Random.Range(0, num);
			int num3 = 0;
			foreach (KeyValuePair<string, int> item in remaining)
			{
				num3 += item.Value;
				if (num2 < num3)
				{
					return item.Key;
				}
			}
			return "";
		}

		private static Dictionary<string, int> PickRandomUpgrades(Dictionary<string, int> currentUpgrades, Dictionary<string, int> maximumUpgrades, int numberOfUpgrades)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (string key in maximumUpgrades.Keys)
			{
				int num = maximumUpgrades[key];
				int num2 = (currentUpgrades.ContainsKey(key) ? currentUpgrades[key] : 0);
				int num3 = num - num2;
				dictionary[key] = ((num3 > 0) ? num3 : 0);
			}
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			foreach (string key2 in maximumUpgrades.Keys)
			{
				dictionary2[key2] = 0;
			}
			for (int i = 0; i < numberOfUpgrades; i++)
			{
				if (dictionary.Values.Sum() == 0)
				{
					break;
				}
				string text = WeightedRandomSelection(dictionary);
				if (text == null)
				{
					break;
				}
				dictionary2[text]++;
				dictionary[text]--;
			}
			return dictionary2;
		}

		public static string? GetSteamID()
		{
			try
			{
				PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(SemiFunc.PhotonViewIDPlayerAvatarLocal());
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				return SemiFunc.PlayerGetSteamID(SemiFunc.PlayerAvatarGetFromPhotonID(SemiFunc.PhotonViewIDPlayerAvatarLocal()));
			}
			catch (Exception ex)
			{
				Debug.Log((object)"Error while retrieving steamID");
				Debug.LogException(ex);
				return null;
			}
		}

		public static Dictionary<string, int>? GetCurrentStats()
		{
			string steamID = GetSteamID();
			if (steamID == null)
			{
				Debug.Log((object)"No valid steamID found, unable to retrieve current stats");
				return null;
			}
			return StatsManager.instance.FetchPlayerUpgrades(steamID);
		}

		private static Dictionary<string, int> GetMaximumStats()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			dictionary["Health"] = PlayerLevels.MaxHealthGain.Value;
			dictionary["Stamina"] = PlayerLevels.MaxStaminaGain.Value;
			dictionary["Strength"] = PlayerLevels.MaxStrengthGain.Value;
			dictionary["Range"] = PlayerLevels.MaxRangeGain.Value;
			dictionary["Speed"] = PlayerLevels.MaxSpeedGain.Value;
			dictionary["Extra Jump"] = PlayerLevels.MaxJumpGain.Value;
			dictionary["Launch"] = PlayerLevels.MaxTumbleLaunchGain.Value;
			return dictionary;
		}

		private static bool ApplyUpgrades(Dictionary<string, int> stats)
		{
			PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>();
			string steamID = GetSteamID();
			if (steamID == null)
			{
				return false;
			}
			int num = 0;
			bool flag = false;
			foreach (KeyValuePair<string, int> stat in stats)
			{
				string key = stat.Key;
				int value = stat.Value;
				num += value;
				for (int i = 0; i < value; i++)
				{
					switch (key)
					{
					case "Health":
						PunManager.instance.UpgradePlayerHealth(steamID);
						flag = true;
						break;
					case "Stamina":
						PunManager.instance.UpgradePlayerEnergy(steamID);
						flag = true;
						break;
					case "Strength":
						PunManager.instance.UpgradePlayerGrabStrength(steamID);
						flag = true;
						break;
					case "Range":
						PunManager.instance.UpgradePlayerGrabRange(steamID);
						flag = true;
						break;
					case "Speed":
						PunManager.instance.UpgradePlayerSprintSpeed(steamID);
						flag = true;
						break;
					case "Extra Jump":
						PunManager.instance.UpgradePlayerExtraJump(steamID);
						flag = true;
						break;
					case "Launch":
						PunManager.instance.UpgradePlayerTumbleLaunch(steamID);
						flag = true;
						break;
					default:
						Debug.Log((object)("Unknown upgrade: " + key));
						break;
					}
					if (GameManager.Multiplayer() && (Object)(object)component != (Object)null)
					{
						component.RPC("UpdateStatRPC", (RpcTarget)1, new object[3] { "playerUpgradesUsed", steamID, 1 });
					}
				}
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, int> stat2 in stats)
			{
				if (stat2.Value >= 1)
				{
					list.Add($"{stat2.Key} +{stat2.Value}");
				}
			}
			if (list.Count > 0)
			{
				((MonoBehaviour)UpgradeCoroutineManager.Instance).StartCoroutine(DisplayExperiencedGained(list));
			}
			return num == 0 || flag;
		}

		public static bool LevelUp()
		{
			Debug.Log((object)"Player has levelled up!");
			Dictionary<string, int> currentStats = GetCurrentStats();
			if (currentStats == null)
			{
				return false;
			}
			Dictionary<string, int> maximumStats = GetMaximumStats();
			int value = PlayerLevels.NumberOfUpgradesPerLevel.Value;
			int expGainedFromKills = PlayerLevels.GetExpGainedFromKills();
			int num = expGainedFromKills / PlayerLevels.ExpNeededPerLevel.Value;
			Debug.Log((object)$"Gained {expGainedFromKills} from kills (+{num} additional levels)");
			value += num;
			Dictionary<string, int> dictionary = PickRandomUpgrades(currentStats, maximumStats, value);
			Debug.Log((object)$"Picking {value} random upgrades");
			foreach (KeyValuePair<string, int> item in dictionary)
			{
				if (item.Value != 0)
				{
					Debug.Log((object)$"    {item.Key} +{item.Value} (Max={maximumStats[item.Key]})");
				}
			}
			return ApplyUpgrades(dictionary);
		}

		private static IEnumerator DisplayExperiencedGained(List<string> appliedUpgrades)
		{
			int totalExperiencedGained = PlayerLevels.GetExpGainedFromKills();
			if (totalExperiencedGained > 0)
			{
				REPOPopupPage page = MenuAPI.CreateREPOPopupPage("Experience gained", (PresetSide)1, false, false, 1.5f);
				page.OpenPage(true);
				yield return (object)new WaitForSeconds(5f);
				int i = 0;
				foreach (KeyValuePair<string, int> killCount in PlayerLevels.KillCounts)
				{
					if (killCount.Value != 0)
					{
						string key = killCount.Key;
						int value = killCount.Value;
						_ = value * PlayerLevels.GetExpForEnemyType(key);
						float x = 420f + (float)i * 0f;
						float y = 270f + (float)i * -25f;
						string fullText = $"{key} x {value}";
						page.AddElement((BuilderDelegate)delegate(Transform parent)
						{
							//IL_0012: Unknown result type (might be due to invalid IL or missing references)
							REPOLabel label2 = MenuAPI.CreateREPOLabel("", parent, new Vector2(x, y));
							UpgradeCoroutineManager.Instance.AnimateText(label2, fullText);
						});
						yield return (object)new WaitForSeconds(0.5f);
						i++;
					}
				}
				string fullText2 = "{0} experienced gained";
				float x2 = 420f + (float)i * 0f;
				float y2 = 270f + (float)i * -25f;
				page.AddElement((BuilderDelegate)delegate(Transform parent)
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					REPOLabel label = MenuAPI.CreateREPOLabel("", parent, new Vector2(x2, y2));
					UpgradeCoroutineManager.Instance.AnimateValue(label, 0, totalExperiencedGained, fullText2, 5f);
				});
				yield return (object)new WaitForSeconds(7f);
				page.ClosePage(true);
				PlayerLevels.KillCounts.Clear();
			}
			yield return (object)new WaitForNextFrameUnit();
			((MonoBehaviour)UpgradeCoroutineManager.Instance).StartCoroutine(DisplayUIPopoutText(appliedUpgrades));
		}

		private static IEnumerator DisplayUIPopoutText(List<string> upgradesReceived)
		{
			List<string> upgradesReceived2 = upgradesReceived;
			SemiFunc.PlayerAvatarLocal();
			string text = "Upgrades received: " + string.Join(", ", upgradesReceived2);
			Debug.Log((object)text);
			REPOPopupPage page = MenuAPI.CreateREPOPopupPage("Upgrades received", (PresetSide)1, false, false, 1.5f);
			upgradesReceived2.Sort();
			page.OpenPage(true);
			yield return (object)new WaitForNextFrameUnit();
			for (int i = 0; i < upgradesReceived2.Count; i++)
			{
				string upgrade = upgradesReceived2[i];
				float num = 420f + (float)i * 0f;
				float num2 = 270f + (float)i * -25f;
				float _x = num;
				float _y = num2;
				page.AddElement((BuilderDelegate)delegate(Transform parent)
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					REPOLabel label = MenuAPI.CreateREPOLabel("", parent, new Vector2(_x, _y));
					UpgradeCoroutineManager.Instance.AnimateText(label, upgrade);
				});
				yield return (object)new WaitForSeconds(0.5f);
			}
			page.AddElement((BuilderDelegate)delegate(Transform parent)
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				REPOButton val = MenuAPI.CreateREPOButton("OK", (Action)delegate
				{
					page.ClosePage(true);
				}, parent, new Vector2(420f + (float)upgradesReceived2.Count * 0f, 270f + (float)upgradesReceived2.Count * -25f * 1.25f));
			});
		}

		private static IEnumerator WaitPlayerReadyLevelup()
		{
			yield return (object)new WaitForEndOfFrameUnit();
			canUpgrade = LevelUp();
		}

		private static void Postfix(PhotonView __instance)
		{
			if (BLACK_LISTED_LEVELS.Contains(RunManager.instance.levelCurrent))
			{
				canUpgrade = true;
			}
			else
			{
				if ((GameManager.Multiplayer() && !__instance.IsMine) || !canUpgrade)
				{
					return;
				}
				canUpgrade = false;
				UpgradeCoroutineManager instance = UpgradeCoroutineManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					if (instance.waitPlayerReadyCoroutine != null)
					{
						((MonoBehaviour)instance).StopCoroutine(instance.waitPlayerReadyCoroutine);
					}
					instance.waitPlayerReadyCoroutine = ((MonoBehaviour)instance).StartCoroutine(WaitPlayerReadyLevelup());
				}
			}
		}
	}
	public class UpgradeCoroutineManager : MonoBehaviour
	{
		public Coroutine? waitPlayerReadyCoroutine;

		private static UpgradeCoroutineManager? _instance;

		public static UpgradeCoroutineManager Instance
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = ((Component)StatsManager.instance).GetComponent<UpgradeCoroutineManager>();
					if ((Object)(object)_instance == (Object)null)
					{
						_instance = ComponentHolderProtocol.AddComponent<UpgradeCoroutineManager>((Object)(object)StatsManager.instance);
					}
				}
				return _instance;
			}
		}

		public Coroutine AnimateText(REPOLabel label, string fullText, float delayBetweenChars = 0.03f)
		{
			return ((MonoBehaviour)this).StartCoroutine(AnimateTextCoroutine(label, fullText, delayBetweenChars));
		}

		private IEnumerator AnimateTextCoroutine(REPOLabel label, string fullText, float delayBetweenChars)
		{
			string currentText = "";
			for (int i = 0; i < fullText.Length; i++)
			{
				currentText += fullText[i];
				((TMP_Text)label.labelTMP).text = currentText;
				yield return (object)new WaitForSeconds(delayBetweenChars);
			}
		}

		public Coroutine AnimateValue(REPOLabel label, int start, int end, string format, float duration = 1f, Action onComplete = null, int easingType = 1)
		{
			return ((MonoBehaviour)this).StartCoroutine(AnimateValueCoroutine(label, start, end, format, duration, onComplete, easingType));
		}

		private IEnumerator AnimateValueCoroutine(REPOLabel label, int start, int end, string format, float duration, Action onComplete, int easingType)
		{
			float elapsed = 0f;
			while (elapsed < duration)
			{
				elapsed += Time.deltaTime;
				float num = Mathf.Clamp01(elapsed / duration);
				if (easingType == 1)
				{
					num = EaseInOut(num);
				}
				int num2 = (int)Mathf.Lerp((float)start, (float)end, num);
				((TMP_Text)label.labelTMP).text = string.Format(format, num2);
				yield return null;
			}
			((TMP_Text)label.labelTMP).text = string.Format(format, end);
			onComplete?.Invoke();
		}

		private float EaseInOut(float t)
		{
			if (!(t < 0.5f))
			{
				return 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f;
			}
			return 4f * t * t * t;
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerEnergy")]
	public static class UpgradePlayerEnergyPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerEnergyCountRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeStamina[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerExtraJump")]
	public static class UpgradePlayerExtraJumpPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerExtraJumpRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeExtraJump[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerGrabRange")]
	public static class UpgradePlayerGrabRangePatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerGrabRangeRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeRange[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerGrabStrength")]
	public static class UpgradePlayerGrabStrengthPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerGrabStrengthRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeStrength[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerHealth")]
	public static class UpgradePlayerHealthPatch
	{
		private static void Postfix(string playerName, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerHealthRPC", (RpcTarget)1, new object[2]
				{
					playerName,
					___statsManager.playerUpgradeHealth[playerName]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerSprintSpeed")]
	public static class UpgradePlayerSprintSpeedPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerSprintSpeedRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeSpeed[_steamID]
				});
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	[HarmonyPatch("UpgradePlayerTumbleLaunch")]
	public static class UpgradePlayerTumbleLaunchPatch
	{
		private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager)
		{
			if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer())
			{
				___photonView.RPC("UpgradePlayerTumbleLaunchRPC", (RpcTarget)1, new object[2]
				{
					_steamID,
					___statsManager.playerUpgradeLaunch[_steamID]
				});
			}
		}
	}
	public static class PLAYER_STATS_ENUM
	{
		public const string HEALTH_KEY = "Health";

		public const string STAMINA_KEY = "Stamina";

		public const string GRAB_STRENGTH_KEY = "Strength";

		public const string GRAB_RANGE_KEY = "Range";

		public const string SPRINT_SPEED_KEY = "Speed";

		public const string TUMBLE_LAUNCH_KEY = "Launch";

		public const string EXTRA_JUMP_KEY = "Extra Jump";
	}
	public static class ENEMY_TYPE_ENUM
	{
		public const string ANIMAL_KEY = "Animal";

		public const string BANG_KEY = "Bang";

		public const string BEAMER_KEY = "Beamer";

		public const string BOWTIE_KEY = "Bowtie";

		public const string CEILING_EYE_KEY = "CeilingEye";

		public const string DUCK_KEY = "Duck";

		public const string FLOATER_KEY = "Floater";

		public const string GNOME_KEY = "Gnome";

		public const string HIDDEN_KEY = "Hidden";

		public const string HUNTER_KEY = "Hunter";

		public const string ROBE_KEY = "Robe";

		public const string RUNNER_KEY = "Runner";

		public const string SLOW_MOUTH_KEY = "SlowMouth";

		public const string SLOW_WALKER_KEY = "SlowWalker";

		public const string THINMAN_KEY = "ThinMan";

		public const string TUMBLER_KEY = "Tumbler";

		public const string UPSCREAM_KEY = "Upscream";

		public const string VALUABLE_THROWER_KEY = "ValuableThrower";

		public static string[] GetAllTypes()
		{
			return new string[18]
			{
				"Animal", "Robe", "Gnome", "Duck", "Upscream", "Bang", "Beamer", "ValuableThrower", "Hunter", "Bowtie",
				"Tumbler", "Floater", "Hidden", "Runner", "SlowMouth", "SlowWalker", "ThinMan", "CeilingEye"
			};
		}
	}
	[HarmonyPatch(typeof(PlayerController))]
	public static class PlayerControllerPatch
	{
		public static float timeSinceSprintStop;

		public static float culmulatedHealthRegenerated;

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		public static void Update_Postfix(PlayerController __instance)
		{
			if (__instance.sprinting)
			{
				timeSinceSprintStop = 0f;
				return;
			}
			timeSinceSprintStop += Time.deltaTime;
			if (timeSinceSprintStop > PlayerLevels.DelayBeforeRegen.Value)
			{
				string key = SemiFunc.PlayerGetSteamID(__instance.playerAvatarScript);
				float num = 0f;
				if (StatsManager.instance.playerUpgradeStamina.ContainsKey(key))
				{
					num = StatsManager.instance.playerUpgradeStamina[key];
				}
				__instance.EnergyCurrent += ((float)PlayerLevels.BaseStaminaLevel.Value + num) * Time.deltaTime * PlayerLevels.StaminaRegenPerLevel.Value;
				__instance.EnergyCurrent = Mathf.Clamp(__instance.EnergyCurrent, 0f, __instance.EnergyStart);
				float num2 = 0f;
				if (StatsManager.instance.playerUpgradeHealth.ContainsKey(key))
				{
					num2 = StatsManager.instance.playerUpgradeHealth[key];
				}
				culmulatedHealthRegenerated += ((float)PlayerLevels.BaseHealthLevel.Value + num2) * Time.deltaTime * PlayerLevels.HealthRegenPerLevel.Value;
				if (culmulatedHealthRegenerated >= 1f)
				{
					PlayerHealth playerHealth = __instance.playerAvatarScript.playerHealth;
					playerHealth.health += (int)culmulatedHealthRegenerated;
					__instance.playerAvatarScript.playerHealth.health = Mathf.Clamp(__instance.playerAvatarScript.playerHealth.health, 0, __instance.playerAvatarScript.playerHealth.maxHealth);
					__instance.playerAvatarScript.playerHealth.UpdateHealthRPC(__instance.playerAvatarScript.playerHealth.health, __instance.playerAvatarScript.playerHealth.maxHealth, false);
					culmulatedHealthRegenerated -= (int)culmulatedHealthRegenerated;
					culmulatedHealthRegenerated = Mathf.Max(culmulatedHealthRegenerated, 0f);
				}
			}
		}
	}
	public static class Utilities
	{
		public static void DebugGameObjectHierarchy(GameObject? go, int level = 0, string indent = "  ")
		{
			if (!((Object)(object)go == (Object)null))
			{
				string text = "";
				for (int i = 0; i < level; i++)
				{
					text += " ";
				}
				text += level;
				Debug.Log((object)(text + ": name=" + ((Object)go).name + ", tags=" + go.tag));
				if ((Object)(object)go.transform.parent != (Object)null)
				{
					DebugGameObjectHierarchy(((Component)go.transform.parent).gameObject, level + 1);
				}
			}
		}
	}
	[HarmonyPatch(typeof(HurtCollider))]
	public static class HurtColliderPatch
	{
		private static int CalculateTubleDamage(int tumbleLevel)
		{
			return tumbleLevel switch
			{
				0 => 0, 
				1 => PlayerLevels.TumbleLevel1Damage.Value, 
				2 => PlayerLevels.TumbleLevel2Damage.Value, 
				3 => PlayerLevels.TumbleLevel3Damage.Value, 
				4 => PlayerLevels.TumbleLevel4Damage.Value, 
				_ => PlayerLevels.TumbleLevel4Damage.Value + PlayerLevels.TumbleLevelNDamage.Value * (tumbleLevel - 4), 
			};
		}

		[HarmonyPatch("EnemyHurt")]
		[HarmonyPrefix]
		public static void EnemyHurt_Prefix(HurtCollider __instance)
		{
			PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>();
			if ((Object)(object)componentInParent != (Object)null && __instance.enemyDamage > 0)
			{
				Dictionary<string, int> currentStats = PlayerSpawnPatch.GetCurrentStats();
				if (currentStats == null)
				{
					Debug.Log((object)"Unable to get player stats");
					return;
				}
				int tumbleLevel = currentStats["Launch"];
				__instance.enemyDamage += CalculateTubleDamage(tumbleLevel);
			}
		}

		[HarmonyPatch("EnemyHurt")]
		[HarmonyPostfix]
		public static void EnemyHurt_Postfix(HurtCollider __instance)
		{
			PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>();
			if ((Object)(object)componentInParent != (Object)null && __instance.enemyDamage > 0)
			{
				__instance.enemyDamage = 15;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth))]
	internal static class EnemyHealthPatch
	{
		[HarmonyPatch("Death")]
		[HarmonyPrefix]
		public static void Death_Prefix(EnemyHealth __instance)
		{
			Dictionary<string, bool> source = new Dictionary<string, bool>
			{
				{
					"Animal",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyAnimal>() != (Object)null
				},
				{
					"Robe",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyRobe>() != (Object)null
				},
				{
					"Upscream",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyUpscream>() != (Object)null
				},
				{
					"Gnome",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyGnome>() != (Object)null
				},
				{
					"Bang",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyBang>() != (Object)null
				},
				{
					"Hunter",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyHunter>() != (Object)null
				},
				{
					"Bowtie",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyBowtie>() != (Object)null
				},
				{
					"Duck",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyDuck>() != (Object)null
				},
				{
					"Beamer",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyBeamer>() != (Object)null
				},
				{
					"Tumbler",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyTumbler>() != (Object)null
				},
				{
					"Floater",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyFloater>() != (Object)null
				},
				{
					"Hidden",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyHidden>() != (Object)null
				},
				{
					"Runner",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyRunner>() != (Object)null
				},
				{
					"SlowMouth",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemySlowMouth>() != (Object)null
				},
				{
					"SlowWalker",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemySlowWalker>() != (Object)null
				},
				{
					"Thinman",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyThinMan>() != (Object)null
				},
				{
					"ValuableThrower",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyValuableThrower>() != (Object)null
				},
				{
					"CeilingEye",
					(Object)(object)((Component)__instance).GetComponentInParent<EnemyCeilingEye>() != (Object)null
				}
			};
			IEnumerable<string> enumerable = from kvp in source
				where kvp.Value
				select kvp.Key;
			if (enumerable.Any())
			{
				Debug.Log((object)("Enemy type(s): " + string.Join(", ", enumerable)));
				string text = enumerable.First();
				if (!PlayerLevels.KillCounts.ContainsKey(text))
				{
					PlayerLevels.KillCounts[text] = 0;
				}
				PlayerLevels.KillCounts[text]++;
				Debug.Log((object)$"Player has killed {PlayerLevels.KillCounts[text]} {text} this level");
			}
			else
			{
				Debug.Log((object)"No recognized enemy type found");
			}
		}
	}
}