Decompiled source of RPGSkillsMod v1.1.0

plugins/RPGSkillsMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RPGSkillsMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RPGSkillsMod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("25df85b1-0101-469c-b93b-aa6ed3e7dbb0")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.2.0.0")]
[HarmonyPatch(typeof(StatsManager), "SaveFileCreate")]
internal static class SaveFileCreatePatch
{
	[HarmonyPostfix]
	private static void ResetClass()
	{
		Plugin.SelectedClass = PlayerClass.None;
		Plugin.Log.LogInfo((object)"New save created. Class reset.");
	}
}
[HarmonyPatch(typeof(StatsManager), "LoadGame")]
internal static class LoadGamePatch
{
	[HarmonyPostfix]
	private static void LoadClass(string fileName, List<string> backupList)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		ES3Settings val = new ES3Settings(Path.Combine(Application.persistentDataPath, "saves", fileName, fileName + "_rpgSkillsMod.es3"), (EncryptionType)1, "Why would you want to cheat?... :o It's no fun. :') :'D", (ES3Settings)null);
		if (!ES3.KeyExists("selectedClass", val))
		{
			ES3Settings val2 = new ES3Settings(Path.Combine(Application.persistentDataPath, "saves", fileName, fileName + ".es3"), (EncryptionType)1, "Why would you want to cheat?... :o It's no fun. :') :'D", (ES3Settings)null);
			if (ES3.KeyExists("selectedClass", val2))
			{
				string text = ES3.Load<string>("selectedClass", val2);
				if (Enum.TryParse<PlayerClass>(text, out var result))
				{
					Plugin.SelectedClass = result;
					ES3.Save<string>("selectedClass", text, val);
					Plugin.Log.LogInfo((object)$"Migrated legacy saved class: {result}");
					return;
				}
			}
			Plugin.SelectedClass = PlayerClass.None;
			Plugin.Log.LogInfo((object)"No saved class found.");
		}
		else
		{
			string text2 = ES3.Load<string>("selectedClass", val);
			if (Enum.TryParse<PlayerClass>(text2, out var result2))
			{
				Plugin.SelectedClass = result2;
				Plugin.Log.LogInfo((object)$"Loaded class: {result2}");
			}
			else
			{
				Plugin.SelectedClass = PlayerClass.None;
				Plugin.Log.LogWarning((object)("Invalid saved class: " + text2));
			}
		}
	}
}
[HarmonyPatch(typeof(StatsManager), "SaveGame")]
internal static class SaveGamePatch
{
	[HarmonyPostfix]
	private static void SaveClass(string fileName)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		if (!string.IsNullOrEmpty(fileName))
		{
			ES3Settings val = new ES3Settings(Path.Combine(Application.persistentDataPath, "saves", fileName, fileName + "_rpgSkillsMod.es3"), (EncryptionType)1, "Why would you want to cheat?... :o It's no fun. :') :'D", (ES3Settings)null);
			ES3.Save<string>("selectedClass", Plugin.SelectedClass.ToString(), val);
			Plugin.Log.LogInfo((object)$"Saved class: {Plugin.SelectedClass}");
		}
	}
}
internal class AssassinSkill : Skill
{
	private const float Duration = 15f;

	public AssassinSkill()
	{
		base.Name = "Phantom";
		base.Description = "Become undetectable by enemies, floating like a ghost.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 60f);
		base.ActiveDuration = 15f;
		base.Properties.Add($"Duration: {15f}s");
	}

	public override bool Execute()
	{
		PlayerAvatar instance = PlayerAvatar.instance;
		FreezeEnemyVision(instance);
		PlayerController.instance.AntiGravity(15f);
		Plugin.Log.LogInfo((object)"Assassin skill used.");
		return true;
	}

	private void FreezeEnemyVision(PlayerAvatar caster)
	{
		if (!SemiFunc.IsMultiplayer())
		{
			caster.EnemyVisionFreezeTimerSet(15f);
			return;
		}
		caster.photonView.RPC("SetVisionFreezeRPC", (RpcTarget)2, new object[1] { 15f });
	}
}
internal class BlacksmithSkill : Skill
{
	private const float IndestructibleDuration = 999999f;

	public BlacksmithSkill()
	{
		base.Name = "Reinforce";
		base.Description = "Makes the item you're currently holding unbreakable.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 90f);
	}

	public override bool Execute()
	{
		if (!ReinforceHeldItem())
		{
			Plugin.Log.LogInfo((object)"Blacksmith skill failed: no item held.");
			return false;
		}
		Plugin.Log.LogInfo((object)"Blacksmith skill used.");
		return true;
	}

	private bool ReinforceHeldItem()
	{
		Transform grabbedObjectTransform = PlayerAvatar.instance.physGrabber.grabbedObjectTransform;
		if ((Object)(object)grabbedObjectTransform == (Object)null)
		{
			return false;
		}
		PhysGrabObject component = ((Component)grabbedObjectTransform).GetComponent<PhysGrabObject>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		if (!SemiFunc.IsMultiplayer())
		{
			component.OverrideIndestructible(999999f);
		}
		else
		{
			((Component)component).GetComponent<PhotonView>().RPC("OverrideIndestructibleRPC", (RpcTarget)2, new object[1] { 999999f });
		}
		return true;
	}
}
internal class DruidSkill : Skill
{
	private const int Health = 50;

	private const float Radius = 5f;

	public DruidSkill()
	{
		base.Name = "Nature's Blessing";
		base.Description = "Heal nearby allies within a small radius.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 45f);
		base.Properties.Add($"Radius: {5f}m");
		base.Properties.Add($"Total health: {50}");
	}

	public override bool Execute()
	{
		bool flag = HealNearbyPlayers();
		Plugin.Log.LogInfo((object)(flag ? "Druid skill used." : "Druid skill failed."));
		return flag;
	}

	private bool HealNearbyPlayers()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar instance = PlayerAvatar.instance;
		List<PlayerAvatar> list = new List<PlayerAvatar> { instance };
		foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
		{
			if (!((Object)(object)item == (Object)(object)instance) && Vector3.Distance(((Component)item).transform.position, ((Component)instance).transform.position) <= 5f)
			{
				list.Add(item);
			}
		}
		List<PlayerAvatar> list2 = new List<PlayerAvatar>();
		Dictionary<PlayerAvatar, int> dictionary = new Dictionary<PlayerAvatar, int>();
		foreach (PlayerAvatar item2 in list)
		{
			int missingHealth = GetMissingHealth(item2);
			if (missingHealth > 0)
			{
				list2.Add(item2);
				dictionary[item2] = missingHealth;
			}
		}
		if (list2.Count == 0)
		{
			return false;
		}
		int num = 50;
		Dictionary<PlayerAvatar, int> dictionary2 = new Dictionary<PlayerAvatar, int>();
		while (num > 0 && list2.Count > 0)
		{
			int num2 = num / list2.Count;
			if (num2 <= 0)
			{
				break;
			}
			List<PlayerAvatar> list3 = new List<PlayerAvatar>();
			foreach (PlayerAvatar item3 in list2)
			{
				int num3 = Mathf.Min(num2, dictionary[item3]);
				dictionary2[item3] = (dictionary2.TryGetValue(item3, out var value) ? (value + num3) : num3);
				num -= num3;
				dictionary[item3] -= num3;
				if (dictionary[item3] <= 0)
				{
					list3.Add(item3);
				}
			}
			foreach (PlayerAvatar item4 in list3)
			{
				list2.Remove(item4);
			}
		}
		if (dictionary2.Count == 0)
		{
			return false;
		}
		foreach (KeyValuePair<PlayerAvatar, int> item5 in dictionary2)
		{
			if ((Object)(object)item5.Key == (Object)(object)instance)
			{
				instance.playerHealth.Heal(item5.Value, true);
			}
			else
			{
				item5.Key.playerHealth.HealOther(item5.Value, true);
			}
		}
		return true;
	}

	private static int GetMissingHealth(PlayerAvatar player)
	{
		Traverse obj = Traverse.Create((object)player.playerHealth);
		int value = obj.Field("health").GetValue<int>();
		int value2 = obj.Field("maxHealth").GetValue<int>();
		return Mathf.Max(0, value2 - value);
	}
}
internal class MonkSkill : Skill
{
	private const float Radius = 10f;

	private const float StunDuration = 5f;

	private const float ExplosionForce = 35f;

	private const float UpwardsModifier = 5f;

	public MonkSkill()
	{
		base.Name = "Shockwave";
		base.Description = "Releases a powerful shockwave, stunning all nearby enemies.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 75f);
		base.ActiveDuration = 5f;
		base.Properties.Add($"Radius: {10f}m");
		base.Properties.Add($"Stun duration: {5f}s");
	}

	public override bool Execute()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar instance = PlayerAvatar.instance;
		PushBackNearbyEnemies(instance);
		try
		{
			SkillVfx.PlayShockwaveEffect(((Component)instance).transform.position, Plugin.SelectedClass, 10f);
		}
		catch (Exception arg)
		{
			Plugin.Log.LogWarning((object)$"Shockwave VFX failed: {arg}");
		}
		Plugin.Log.LogInfo((object)"Monk skill used.");
		return true;
	}

	private void PushBackNearbyEnemies(PlayerAvatar caster)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		Enemy[] array = Object.FindObjectsOfType<Enemy>();
		foreach (Enemy val in array)
		{
			Vector3 val2 = val.CenterTransform.position - ((Component)caster).transform.position;
			if (((Vector3)(ref val2)).magnitude > 10f)
			{
				continue;
			}
			if (!SemiFunc.IsMultiplayer())
			{
				EnemyStateStunned component = ((Component)val).GetComponent<EnemyStateStunned>();
				if ((Object)(object)component != (Object)null)
				{
					component.Set(5f);
				}
				Rigidbody component2 = ((Component)val).GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.AddExplosionForce(35f, ((Component)caster).transform.position, 10f, 5f, (ForceMode)1);
				}
			}
			else
			{
				((Component)((Component)val).GetComponentInParent<EnemyParent>()).GetComponent<PhotonView>().RPC("StunAndPushRPC", (RpcTarget)2, new object[5]
				{
					((Component)caster).transform.position,
					5f,
					35f,
					10f,
					5f
				});
			}
		}
	}
}
internal class NecromancerSkill : Skill
{
	private const int HealthSacrifice = 25;

	public NecromancerSkill()
	{
		base.Name = "Raise Dead";
		base.Description = "Sacrifice your own health to revive yourself, or a fallen ally.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 120f);
		base.Properties.Add($"Health sacrificed: {25}");
	}

	public override bool Execute()
	{
		bool flag = ReviveSelfOrHeldAlly();
		Plugin.Log.LogInfo((object)(flag ? "Necromancer skill used." : "Necromancer skill failed: not downed and not holding a dead ally's head."));
		return flag;
	}

	private bool ReviveSelfOrHeldAlly()
	{
		PlayerAvatar instance = PlayerAvatar.instance;
		PlayerAvatar val = FindReviveTarget(instance);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		instance.playerHealth.Hurt(25, false, -1, false);
		ReviveTarget(val);
		return true;
	}

	private void ReviveTarget(PlayerAvatar target)
	{
		if (!SemiFunc.IsMultiplayer())
		{
			NecromancerReviveRelay.ReviveWithCorrectPosition(target, revivedByTruck: false);
			return;
		}
		target.photonView.RPC("RequestReviveRPC", (RpcTarget)2, new object[1] { false });
	}

	private PlayerAvatar FindReviveTarget(PlayerAvatar caster)
	{
		if (Traverse.Create((object)caster).Field("isDisabled").GetValue<bool>())
		{
			return caster;
		}
		Transform grabbedObjectTransform = caster.physGrabber.grabbedObjectTransform;
		if ((Object)(object)grabbedObjectTransform == (Object)null)
		{
			return null;
		}
		PlayerDeathHead component = ((Component)grabbedObjectTransform).GetComponent<PlayerDeathHead>();
		if (!((Object)(object)component != (Object)null))
		{
			return null;
		}
		return component.playerAvatar;
	}
}
internal class NecromancerReviveRelay : MonoBehaviour
{
	internal static readonly Dictionary<PlayerAvatar, Vector3> LastDeathPosition = new Dictionary<PlayerAvatar, Vector3>();

	[PunRPC]
	public void RequestReviveRPC(bool revivedByTruck)
	{
		PlayerAvatar component = ((Component)this).GetComponent<PlayerAvatar>();
		if ((Object)(object)component != (Object)null)
		{
			ReviveWithCorrectPosition(component, revivedByTruck);
		}
	}

	[PunRPC]
	public void SetVisionFreezeRPC(float duration)
	{
		PlayerAvatar component = ((Component)this).GetComponent<PlayerAvatar>();
		if ((Object)(object)component != (Object)null)
		{
			component.EnemyVisionFreezeTimerSet(duration);
		}
	}

	internal static void ReviveWithCorrectPosition(PlayerAvatar target, bool revivedByTruck)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		if (LastDeathPosition.TryGetValue(target, out var value))
		{
			PlayerDeathHead value2 = Traverse.Create((object)target).Field("playerDeathHead").GetValue<PlayerDeathHead>();
			PhysGrabObject val = (((Object)(object)value2 != (Object)null) ? Traverse.Create((object)value2).Field("physGrabObject").GetValue<PhysGrabObject>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.Teleport(value, ((Component)val).transform.rotation);
			}
		}
		target.Revive(revivedByTruck);
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "Awake")]
internal static class NecromancerRevivePatch
{
	private static void Postfix(PlayerAvatar __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<NecromancerReviveRelay>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<NecromancerReviveRelay>();
		}
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")]
internal static class NecromancerDeathPositionPatch
{
	[HarmonyPrefix]
	private static void Prefix(PlayerAvatar __instance)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		NecromancerReviveRelay.LastDeathPosition[__instance] = ((Component)__instance).transform.position;
	}
}
internal class KonamiCheatRelay : MonoBehaviour
{
	public static bool FreeClassChangeUnlocked;

	[PunRPC]
	public void SetFreeClassChangeRPC(bool unlocked)
	{
		FreeClassChangeUnlocked = unlocked;
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "Awake")]
internal static class KonamiCheatPatch
{
	private static void Postfix(PlayerAvatar __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<KonamiCheatRelay>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<KonamiCheatRelay>();
		}
	}
}
[HarmonyPatch(typeof(RunManager), "Update")]
internal static class KonamiCheatDetector
{
	private static readonly KeyCode[][] Sequence = new KeyCode[10][]
	{
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)273 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)273 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)274 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)274 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)276 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)275 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)276 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)275 },
		(KeyCode[])(object)new KeyCode[1] { (KeyCode)98 },
		(KeyCode[])(object)new KeyCode[2]
		{
			(KeyCode)97,
			(KeyCode)113
		}
	};

	private static readonly KeyCode[] RelevantKeys;

	private static int progress;

	private static void Postfix()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.EnableMod.Value)
		{
			return;
		}
		if (IsAnyKeyDown(Sequence[progress]))
		{
			progress++;
			if (progress >= Sequence.Length)
			{
				progress = 0;
				ToggleFreeClassChange();
			}
			return;
		}
		KeyCode[] relevantKeys = RelevantKeys;
		foreach (KeyCode val in relevantKeys)
		{
			if (Input.GetKeyDown(val))
			{
				progress = ((Array.IndexOf(Sequence[0], val) >= 0) ? 1 : 0);
				break;
			}
		}
	}

	private static bool IsAnyKeyDown(KeyCode[] keys)
	{
		for (int i = 0; i < keys.Length; i++)
		{
			if (Input.GetKeyDown(keys[i]))
			{
				return true;
			}
		}
		return false;
	}

	private static void ToggleFreeClassChange()
	{
		bool flag = !KonamiCheatRelay.FreeClassChangeUnlocked;
		PlayerAvatar instance = PlayerAvatar.instance;
		if (SemiFunc.IsMultiplayer() && (Object)(object)instance != (Object)null && (Object)(object)instance.photonView != (Object)null)
		{
			if ((Object)(object)((Component)instance).GetComponent<KonamiCheatRelay>() == (Object)null)
			{
				((Component)instance).gameObject.AddComponent<KonamiCheatRelay>();
			}
			instance.photonView.RPC("SetFreeClassChangeRPC", (RpcTarget)0, new object[1] { flag });
		}
		else
		{
			KonamiCheatRelay.FreeClassChangeUnlocked = flag;
		}
		if ((Object)(object)ChatManager.instance != (Object)null)
		{
			ChatManager.instance.ForceSendMessage(flag ? "Konami Code activated" : "Konami Code deactivated");
		}
	}

	static KonamiCheatDetector()
	{
		KeyCode[] array = new KeyCode[7];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		RelevantKeys = (KeyCode[])(object)array;
		progress = 0;
	}
}
internal class PaladinSkill : Skill
{
	private const float Radius = 15f;

	private const float Duration = 10f;

	public PaladinSkill()
	{
		base.Name = "Divine Taunt";
		base.Description = "Grants invulnerability, but forces nearby enemies to focus you.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 60f);
		base.ActiveDuration = 10f;
		base.Properties.Add($"Duration: {10f}s");
		base.Properties.Add($"Radius: {15f}m");
	}

	public override bool Execute()
	{
		PlayerAvatar.instance.playerHealth.InvincibleSet(10f);
		TauntNearbyEnemies();
		Plugin.Log.LogInfo((object)"Paladin skill used.");
		return true;
	}

	private void TauntNearbyEnemies()
	{
		//IL_001a: 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)
		PlayerAvatar instance = PlayerAvatar.instance;
		Enemy[] array = Object.FindObjectsOfType<Enemy>();
		foreach (Enemy val in array)
		{
			if (!(Vector3.Distance(val.CenterTransform.position, ((Component)instance).transform.position) > 15f))
			{
				if (!SemiFunc.IsMultiplayer())
				{
					val.SetChaseTarget(instance);
					continue;
				}
				((Component)((Component)val).GetComponentInParent<EnemyParent>()).GetComponent<PhotonView>().RPC("SetChaseTargetRPC", (RpcTarget)2, new object[1] { instance.photonView.ViewID });
			}
		}
	}
}
internal class RangerSkill : Skill
{
	private const float Radius = 30f;

	private const float Duration = 20f;

	public RangerSkill()
	{
		base.Name = "Predator Sense";
		base.Description = "Marks nearby enemies on the map, revealing them to every player.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 60f);
		base.ActiveDuration = 20f;
		base.Properties.Add($"Radius: {30f}m");
		base.Properties.Add($"Duration: {20f}s");
	}

	public override bool Execute()
	{
		int num = RevealNearbyEnemies();
		Plugin.Log.LogInfo((object)$"Ranger skill used, revealed {num} enemies.");
		return true;
	}

	private int RevealNearbyEnemies()
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar instance = PlayerAvatar.instance;
		int num = 0;
		Enemy[] array = Object.FindObjectsOfType<Enemy>();
		foreach (Enemy val in array)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.CenterTransform == (Object)null))
			{
				EnemyParent componentInParent = ((Component)val).GetComponentInParent<EnemyParent>();
				if (!((Object)(object)componentInParent == (Object)null) && !(Vector3.Distance(val.CenterTransform.position, ((Component)instance).transform.position) > 30f))
				{
					RevealEnemy(componentInParent);
					num++;
				}
			}
		}
		return num;
	}

	private void RevealEnemy(EnemyParent enemyParent)
	{
		if (!SemiFunc.IsMultiplayer())
		{
			((Component)enemyParent).GetComponent<EnemyMapReveal>().RevealRPC(20f);
			return;
		}
		((Component)enemyParent).GetComponent<PhotonView>().RPC("RevealRPC", (RpcTarget)0, new object[1] { 20f });
	}
}
internal class EnemyMapReveal : MonoBehaviour
{
	private const string MarkerName = "RPG_EnemyReveal";

	private static readonly Color MapMarkerColor = new Color(1f, 0f, 0f);

	private static Sprite markerSprite;

	private Coroutine activeCoroutine;

	[PunRPC]
	public void SetChaseTargetRPC(int casterViewId)
	{
		PhotonView val = PhotonView.Find(casterViewId);
		PlayerAvatar val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PlayerAvatar>() : null);
		Enemy componentInChildren = ((Component)this).GetComponentInChildren<Enemy>();
		if ((Object)(object)val2 != (Object)null && (Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.SetChaseTarget(val2);
		}
	}

	[PunRPC]
	public void StunAndPushRPC(Vector3 casterPosition, float stunDuration, float explosionForce, float radius, float upwardsModifier)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		Enemy componentInChildren = ((Component)this).GetComponentInChildren<Enemy>();
		if (!((Object)(object)componentInChildren == (Object)null))
		{
			EnemyStateStunned component = ((Component)componentInChildren).GetComponent<EnemyStateStunned>();
			if ((Object)(object)component != (Object)null)
			{
				component.Set(stunDuration);
			}
			Rigidbody component2 = ((Component)componentInChildren).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.AddExplosionForce(explosionForce, casterPosition, radius, upwardsModifier, (ForceMode)1);
			}
		}
	}

	[PunRPC]
	public void RevealRPC(float duration)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		Enemy componentInChildren = ((Component)this).GetComponentInChildren<Enemy>();
		if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.CenterTransform == (Object)null))
		{
			Transform val = componentInChildren.CenterTransform.Find("RPG_EnemyReveal");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			GameObject val2 = new GameObject("RPG_EnemyReveal");
			val2.transform.SetParent(componentInChildren.CenterTransform, false);
			val2.transform.localPosition = Vector3.zero;
			if ((Object)(object)Map.Instance != (Object)null)
			{
				MapCustom obj = val2.AddComponent<MapCustom>();
				obj.sprite = GetMarkerSprite();
				obj.color = MapMarkerColor;
			}
			if (activeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(activeCoroutine);
			}
			activeCoroutine = ((MonoBehaviour)this).StartCoroutine(DestroyAfter(val2, duration));
		}
	}

	private IEnumerator DestroyAfter(GameObject marker, float duration)
	{
		yield return (object)new WaitForSeconds(duration);
		if ((Object)(object)marker != (Object)null)
		{
			Object.Destroy((Object)(object)marker);
		}
		activeCoroutine = null;
	}

	private static Sprite GetMarkerSprite()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)markerSprite != (Object)null)
		{
			return markerSprite;
		}
		Texture2D val = new Texture2D(40, 40, (TextureFormat)4, false);
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(20f, 20f);
		float num = 20f;
		for (int i = 0; i < 40; i++)
		{
			for (int j = 0; j < 40; j++)
			{
				bool flag = Vector2.Distance(new Vector2((float)i + 0.5f, (float)j + 0.5f), val2) <= num;
				val.SetPixel(i, j, new Color(1f, 1f, 1f, flag ? 1f : 0f));
			}
		}
		val.Apply();
		markerSprite = Sprite.Create(val, new Rect(0f, 0f, 40f, 40f), new Vector2(0.5f, 0.5f), 200f);
		return markerSprite;
	}
}
[HarmonyPatch(typeof(EnemyParent), "Awake")]
internal static class EnemyRevealPatch
{
	private static void Postfix(EnemyParent __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<EnemyMapReveal>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<EnemyMapReveal>();
		}
	}
}
internal class PhysGrabObjectRelay : MonoBehaviour
{
	[PunRPC]
	public void OverrideIndestructibleRPC(float duration)
	{
		PhysGrabObject component = ((Component)this).GetComponent<PhysGrabObject>();
		if ((Object)(object)component != (Object)null)
		{
			component.OverrideIndestructible(duration);
		}
	}
}
[HarmonyPatch(typeof(PhysGrabObject), "Awake")]
internal static class PhysGrabObjectRelayPatch
{
	private static void Postfix(PhysGrabObject __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<PhysGrabObjectRelay>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<PhysGrabObjectRelay>();
		}
	}
}
internal class ScoutSkill : Skill
{
	private bool active;

	private float timer;

	private const float Duration = 15f;

	public ScoutSkill()
	{
		base.Name = "Best Runner";
		base.Description = "Grants infinite stamina.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 60f);
		base.ActiveDuration = 15f;
		base.Properties.Add($"Duration: {15f}s");
	}

	public override bool Execute()
	{
		if (!ActivateInfiniteStamina())
		{
			return false;
		}
		Plugin.Log.LogInfo((object)"Scout skill activated.");
		return true;
	}

	public override void Update()
	{
		if (active)
		{
			PlayerController.instance.EnergyCurrent = PlayerController.instance.EnergyStart;
			timer -= Time.deltaTime;
			if (timer <= 0f)
			{
				DeactivateInfiniteStamina();
			}
		}
	}

	private bool ActivateInfiniteStamina()
	{
		if (active)
		{
			return false;
		}
		active = true;
		timer = 15f;
		return true;
	}

	private void DeactivateInfiniteStamina()
	{
		active = false;
		Plugin.Log.LogInfo((object)"Scout skill ended.");
	}
}
internal class TreasureHunterSkill : Skill
{
	private const float Radius = 15f;

	public TreasureHunterSkill()
	{
		base.Name = "Treasure Sense";
		base.Description = "Reveals valuable items around you.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 60f);
		base.Properties.Add($"Radius: {15f}m");
	}

	public override bool Execute()
	{
		RevealNearbyValuables();
		Plugin.Log.LogInfo((object)"Treasure Hunter skill used.");
		return true;
	}

	private void RevealNearbyValuables()
	{
		//IL_001a: 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)
		PlayerAvatar instance = PlayerAvatar.instance;
		ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
		foreach (ValuableObject val in array)
		{
			if (!(Vector3.Distance(((Component)val).transform.position, ((Component)instance).transform.position) > 15f))
			{
				val.Discover((State)0);
			}
		}
	}
}
internal class WarriorSkill : Skill
{
	private bool active;

	private float timer;

	private const int StrengthLevels = 20;

	private const float Duration = 15f;

	public WarriorSkill()
	{
		base.Name = "Berserk";
		base.Description = "Increases your strength.";
		base.Cooldown = (Plugin.DebugAllow ? 20f : 90f);
		base.ActiveDuration = 15f;
		base.Properties.Add($"Strength levels: +{20}");
		base.Properties.Add($"Duration: {15f}s");
	}

	public override bool Execute()
	{
		if (!ActivateBerserk())
		{
			return false;
		}
		Plugin.Log.LogInfo((object)"Warrior skill activated.");
		return true;
	}

	public override void Update()
	{
		if (active)
		{
			timer -= Time.deltaTime;
			if (timer <= 0f)
			{
				DeactivateBerserk();
			}
		}
	}

	private bool ActivateBerserk()
	{
		if (active)
		{
			return false;
		}
		active = true;
		timer = 15f;
		string text = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance);
		PunManager.instance.UpgradePlayerGrabStrength(text, 20);
		PunManager.instance.UpgradePlayerThrowStrength(text, 20);
		return true;
	}

	private void DeactivateBerserk()
	{
		active = false;
		string text = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance);
		PunManager.instance.UpgradePlayerGrabStrength(text, -20);
		PunManager.instance.UpgradePlayerThrowStrength(text, -20);
		Plugin.Log.LogInfo((object)"Warrior skill ended.");
	}
}
[HarmonyPatch(typeof(RunManager), "Update")]
internal static class SkillPatch
{
	private static void Postfix()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.EnableMod.Value || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
		{
			return;
		}
		if (SemiFunc.RunIsLevel())
		{
			SkillManager.Update();
			if (Input.GetKeyDown(Plugin.SkillKey.Value))
			{
				SkillManager.TryUseSkill(SkillSlot.Primary);
			}
			if (Input.GetKeyDown(Plugin.SkillKey2.Value))
			{
				SkillManager.TryUseSkill(SkillSlot.Secondary);
			}
		}
		else
		{
			SkillManager.ResetCooldown();
		}
	}
}
internal static class SkillManager
{
	private static float remainingCooldownPrimary;

	private static float remainingCooldownSecondary;

	public static bool IsReady(SkillSlot slot)
	{
		return RemainingCooldown(slot) <= 0f;
	}

	public static float RemainingCooldown(SkillSlot slot)
	{
		return Mathf.Max(0f, (slot == SkillSlot.Primary) ? remainingCooldownPrimary : remainingCooldownSecondary);
	}

	public static void Update()
	{
		if (remainingCooldownPrimary > 0f)
		{
			remainingCooldownPrimary -= Time.deltaTime;
			if (remainingCooldownPrimary < 0f)
			{
				remainingCooldownPrimary = 0f;
			}
		}
		if (remainingCooldownSecondary > 0f)
		{
			remainingCooldownSecondary -= Time.deltaTime;
			if (remainingCooldownSecondary < 0f)
			{
				remainingCooldownSecondary = 0f;
			}
		}
		SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Primary).Update();
		SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Secondary).Update();
	}

	public static bool TryUseSkill(SkillSlot slot)
	{
		if (!IsReady(slot))
		{
			return false;
		}
		Skill skill = SkillDatabase.Get(Plugin.SelectedClass, slot);
		if (!skill.Execute())
		{
			return false;
		}
		Plugin.Log.LogInfo((object)("Using skill : " + skill.Name));
		AnnounceSkillInChat(skill);
		if (slot == SkillSlot.Primary)
		{
			remainingCooldownPrimary = skill.Cooldown;
		}
		else
		{
			remainingCooldownSecondary = skill.Cooldown;
		}
		try
		{
			SkillVfx.PlayCastEffect(PlayerAvatar.instance, Plugin.SelectedClass, skill.ActiveDuration);
		}
		catch (Exception arg)
		{
			Plugin.Log.LogWarning((object)$"SkillVfx failed: {arg}");
		}
		return true;
	}

	private static void AnnounceSkillInChat(Skill skill)
	{
		if ((Object)(object)ChatManager.instance != (Object)null)
		{
			ChatManager.instance.ForceSendMessage(skill.Name.ToUpper() ?? "");
		}
	}

	public static void ResetCooldown()
	{
		remainingCooldownPrimary = 0f;
		remainingCooldownSecondary = 0f;
	}
}
internal static class SkillVfx
{
	private const float FadeOutBuffer = 1f;

	private const string CastEffectName = "RPG_Particles";

	private static readonly Color DefaultLightColor = Color.white;

	private static readonly Dictionary<PlayerClass, Color> LightColors = new Dictionary<PlayerClass, Color>
	{
		{
			PlayerClass.Warrior,
			new Color(0.9f, 0.1f, 0.1f)
		},
		{
			PlayerClass.Paladin,
			new Color(0.1f, 0.2f, 0.9f)
		},
		{
			PlayerClass.Scout,
			new Color(0.9f, 0.9f, 0.1f)
		},
		{
			PlayerClass.Druid,
			new Color(0.25f, 0.85f, 0.25f)
		},
		{
			PlayerClass.Mage,
			new Color(0.6f, 0.1f, 0.9f)
		}
	};

	public static void PlayCastEffect(PlayerAvatar caster, PlayerClass playerClass, float duration)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)caster == (Object)null || playerClass == PlayerClass.None)
		{
			return;
		}
		GameObject val = (((Object)(object)AssetManager.instance != (Object)null) ? AssetManager.instance.prefabTeleportEffect : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ParticleSystem componentInChildren = val.GetComponentInChildren<ParticleSystem>();
		if ((Object)(object)componentInChildren == (Object)null)
		{
			return;
		}
		ParticleSystem val2 = Object.Instantiate<ParticleSystem>(componentInChildren, ((Component)caster).transform);
		((Object)((Component)val2).gameObject).name = "RPG_Particles";
		((Component)val2).transform.localPosition = new Vector3(0f, 1.1f, 0f);
		((Component)val2).transform.localRotation = Quaternion.identity;
		Color value;
		Color color = (LightColors.TryGetValue(playerClass, out value) ? value : DefaultLightColor);
		ShapeModule shape = val2.shape;
		((ShapeModule)(ref shape)).scale = new Vector3(0.1f, 0.1f, 0.1f);
		EmissionModule emission = val2.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(10f);
		ParticleSystem[] componentsInChildren = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
		foreach (ParticleSystem obj in componentsInChildren)
		{
			MainModule main = obj.main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.white);
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.2f, 1f);
			ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime;
			if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled)
			{
				((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = false;
			}
			ColorBySpeedModule colorBySpeed = obj.colorBySpeed;
			if (((ColorBySpeedModule)(ref colorBySpeed)).enabled)
			{
				((ColorBySpeedModule)(ref colorBySpeed)).enabled = false;
			}
			LightsModule lights = obj.lights;
			if (((LightsModule)(ref lights)).enabled && (Object)(object)((LightsModule)(ref lights)).light != (Object)null)
			{
				Light val3 = Object.Instantiate<Light>(((LightsModule)(ref lights)).light, ((Component)val2).transform);
				((Object)((Component)val3).gameObject).name = "RPG_LightTemplate";
				val3.color = color;
				((Behaviour)val3).enabled = false;
				((LightsModule)(ref lights)).light = val3;
				((LightsModule)(ref lights)).useParticleColor = false;
			}
		}
		val2.Play(true);
		((MonoBehaviour)caster).StartCoroutine(StopAndDestroy(val2, duration));
	}

	private static IEnumerator StopAndDestroy(ParticleSystem effect, float duration)
	{
		yield return (object)new WaitForSeconds(duration);
		if (!((Object)(object)effect == (Object)null))
		{
			effect.Stop(true, (ParticleSystemStopBehavior)1);
			yield return (object)new WaitForSeconds(1f);
			if ((Object)(object)effect != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)effect).gameObject);
			}
		}
	}

	public static void ClearActiveEffects(PlayerAvatar avatar)
	{
		if ((Object)(object)avatar == (Object)null)
		{
			return;
		}
		Transform val = ((Component)avatar).transform.Find("RPG_Particles");
		if (!((Object)(object)val == (Object)null))
		{
			ParticleSystem component = ((Component)val).GetComponent<ParticleSystem>();
			if ((Object)(object)component != (Object)null)
			{
				component.Stop(true, (ParticleSystemStopBehavior)0);
			}
			Object.Destroy((Object)(object)((Component)val).gameObject);
		}
	}

	public static void PlayShockwaveEffect(Vector3 position, PlayerClass playerClass, float radius, float duration = 1.2f)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = (((Object)(object)AssetManager.instance != (Object)null) ? AssetManager.instance.prefabTeleportEffect : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ParticleSystem componentInChildren = val.GetComponentInChildren<ParticleSystem>();
		if ((Object)(object)componentInChildren == (Object)null)
		{
			return;
		}
		ParticleSystem val2 = Object.Instantiate<ParticleSystem>(componentInChildren, position, Quaternion.identity);
		((Object)((Component)val2).gameObject).name = "RPG_Shockwave";
		Color value;
		Color color = (LightColors.TryGetValue(playerClass, out value) ? value : DefaultLightColor);
		float num = Mathf.Max(0.2f, radius / 5f);
		ShapeModule shape = val2.shape;
		((ShapeModule)(ref shape)).scale = Vector3.one * num;
		EmissionModule emission = val2.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(80f);
		ParticleSystem[] componentsInChildren = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
		foreach (ParticleSystem obj in componentsInChildren)
		{
			MainModule main = obj.main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.white);
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.4f, duration);
			((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * num;
			ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime;
			if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled)
			{
				((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = false;
			}
			ColorBySpeedModule colorBySpeed = obj.colorBySpeed;
			if (((ColorBySpeedModule)(ref colorBySpeed)).enabled)
			{
				((ColorBySpeedModule)(ref colorBySpeed)).enabled = false;
			}
			LightsModule lights = obj.lights;
			if (((LightsModule)(ref lights)).enabled && (Object)(object)((LightsModule)(ref lights)).light != (Object)null)
			{
				Light val3 = Object.Instantiate<Light>(((LightsModule)(ref lights)).light, ((Component)val2).transform);
				((Object)((Component)val3).gameObject).name = "RPG_ShockwaveLight";
				val3.color = color;
				val3.range = Mathf.Max(val3.range, radius * 2f);
				val3.intensity *= 4f;
				((Behaviour)val3).enabled = false;
				((LightsModule)(ref lights)).light = val3;
				((LightsModule)(ref lights)).useParticleColor = false;
			}
		}
		val2.Play(true);
		if ((Object)(object)GameDirector.instance != (Object)null)
		{
			GameDirector.instance.CameraShake.ShakeDistance(6f, radius * 0.4f, radius * 1.5f, position, 0.2f);
			GameDirector.instance.CameraImpact.ShakeDistance(14f, radius * 0.4f, radius * 1.5f, position, 0.2f);
		}
		Object.Destroy((Object)(object)((Component)val2).gameObject, duration + 1f);
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")]
internal static class SkillVfxDeathPatch
{
	[HarmonyPrefix]
	private static void Prefix(PlayerAvatar __instance)
	{
		SkillVfx.ClearActiveEffects(__instance);
	}
}
[HarmonyPatch(typeof(RunManager), "Update")]
internal static class SkillUI
{
	private static GameObject skillUI;

	private static GameObject skillUI2;

	private static TextMeshProUGUI skillText;

	private static TextMeshProUGUI lobbyDescription;

	private static TextMeshProUGUI lobbyProperties;

	private static TextMeshProUGUI levelCooldown;

	private static TextMeshProUGUI levelKey;

	private static TextMeshProUGUI skillText2;

	private static TextMeshProUGUI lobbyDescription2;

	private static TextMeshProUGUI lobbyProperties2;

	private static TextMeshProUGUI levelCooldown2;

	private static TextMeshProUGUI levelKey2;

	private static bool visible = true;

	private static void Postfix()
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (Plugin.EnableMod.Value && !((Object)(object)LevelGenerator.Instance == (Object)null) && LevelGenerator.Instance.Generated)
		{
			if ((Object)(object)skillUI == (Object)null && (Object)(object)skillUI2 == (Object)null)
			{
				CreateUI();
			}
			if (Input.GetKeyDown(Plugin.ToggleSkillUIKey.Value))
			{
				visible = !visible;
			}
			if (!visible || Plugin.SelectedClass == PlayerClass.None)
			{
				skillUI.SetActive(false);
				skillUI2.SetActive(false);
			}
			else if (SemiFunc.RunIsLobby() || SemiFunc.RunIsShop())
			{
				skillUI.SetActive(true);
				((Component)lobbyDescription).gameObject.SetActive(true);
				((Component)lobbyProperties).gameObject.SetActive(true);
				((Component)levelCooldown).gameObject.SetActive(false);
				((Component)levelKey).gameObject.SetActive(false);
				skillUI2.SetActive(true);
				((Component)lobbyDescription2).gameObject.SetActive(true);
				((Component)lobbyProperties2).gameObject.SetActive(true);
				((Component)levelCooldown2).gameObject.SetActive(false);
				((Component)levelKey2).gameObject.SetActive(false);
				RefreshLobbyShop();
			}
			else if (SemiFunc.RunIsLevel())
			{
				skillUI.SetActive(true);
				((Component)lobbyDescription).gameObject.SetActive(false);
				((Component)lobbyProperties).gameObject.SetActive(false);
				((Component)levelCooldown).gameObject.SetActive(true);
				skillUI2.SetActive(true);
				((Component)lobbyDescription2).gameObject.SetActive(false);
				((Component)lobbyProperties2).gameObject.SetActive(false);
				((Component)levelCooldown2).gameObject.SetActive(true);
				RefreshLevel();
			}
			else
			{
				skillUI.SetActive(false);
				skillUI2.SetActive(false);
			}
		}
	}

	private static void CreateUI()
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0322: Unknown result type (might be due to invalid IL or missing references)
		//IL_032c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_0363: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
		skillUI = Object.Instantiate<GameObject>(((Component)EnergyUI.instance).gameObject, ((Component)EnergyUI.instance).transform.parent);
		skillUI2 = Object.Instantiate<GameObject>(((Component)EnergyUI.instance).gameObject, ((Component)EnergyUI.instance).transform.parent);
		((Object)skillUI).name = "SkillUI";
		((Object)skillUI2).name = "SkillUI";
		Object.Destroy((Object)(object)skillUI.GetComponent<EnergyUI>());
		Object.Destroy((Object)(object)skillUI2.GetComponent<EnergyUI>());
		DestroyAllChildren(skillUI);
		DestroyAllChildren(skillUI2);
		skillText = skillUI.GetComponent<TextMeshProUGUI>();
		((TMP_Text)skillText).fontSize = 28f;
		((Graphic)skillText).color = Color.yellow;
		skillText2 = skillUI2.GetComponent<TextMeshProUGUI>();
		((TMP_Text)skillText2).fontSize = 28f;
		((Graphic)skillText2).color = Color.yellow;
		RectTransform component = skillUI.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0f, 0f);
		component.anchorMax = new Vector2(0f, 0f);
		component.pivot = new Vector2(0f, 0f);
		component.anchoredPosition = new Vector2(0f, 130f);
		component.sizeDelta = new Vector2(260f, 160f);
		RectTransform component2 = skillUI2.GetComponent<RectTransform>();
		component2.anchorMin = new Vector2(0f, 0f);
		component2.anchorMax = new Vector2(0f, 0f);
		component2.pivot = new Vector2(0f, 0f);
		component2.anchoredPosition = new Vector2(0f, 20f);
		component2.sizeDelta = new Vector2(260f, 160f);
		lobbyDescription = CreateText(skillUI.transform, "Description", "", new Vector2(0f, -85f), 18f, Color.white);
		lobbyProperties = CreateText(skillUI.transform, "Properties", "", new Vector2(0f, -110f), 12f, Color.green);
		levelCooldown = CreateText(skillUI.transform, "Cooldown", "", new Vector2(0f, -85f), 18f, Color.white);
		levelKey = CreateText(skillUI.transform, "Key", ((object)Plugin.SkillKey.Value/*cast due to .constrained prefix*/).ToString() + " to use", new Vector2(0f, -105f), 18f, Color.grey);
		lobbyDescription2 = CreateText(skillUI2.transform, "Description", "", new Vector2(0f, -85f), 18f, Color.white);
		lobbyProperties2 = CreateText(skillUI2.transform, "Properties", "", new Vector2(0f, -110f), 12f, Color.green);
		levelCooldown2 = CreateText(skillUI2.transform, "Cooldown", "", new Vector2(0f, -85f), 18f, Color.white);
		levelKey2 = CreateText(skillUI2.transform, "Key", ((object)Plugin.SkillKey2.Value/*cast due to .constrained prefix*/).ToString() + " to use", new Vector2(0f, -105f), 18f, Color.grey);
		RefreshLevel();
	}

	private static void RefreshLobbyShop()
	{
		Skill skill = SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Primary);
		((TMP_Text)skillText).text = skill.Name;
		((TMP_Text)lobbyDescription).text = skill.Description;
		List<string> list = new List<string>(skill.Properties) { $"Cooldown: {skill.Cooldown:0}s" };
		((TMP_Text)lobbyProperties).text = string.Join("\n", list.ConvertAll((string p) => "• " + p));
		Skill skill2 = SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Secondary);
		((TMP_Text)skillText2).text = skill2.Name;
		((TMP_Text)lobbyDescription2).text = skill2.Description;
		List<string> list2 = new List<string>(skill2.Properties) { $"Cooldown: {skill2.Cooldown:0}s" };
		((TMP_Text)lobbyProperties2).text = string.Join("\n", list2.ConvertAll((string p) => "• " + p));
	}

	private static void RefreshLevel()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		Skill skill = SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Primary);
		((TMP_Text)skillText).text = skill.Name;
		if (SkillManager.IsReady(SkillSlot.Primary))
		{
			((Component)levelKey).gameObject.SetActive(true);
			((Graphic)levelCooldown).color = Color.green;
			((TMP_Text)levelCooldown).text = "READY";
		}
		else
		{
			((Component)levelKey).gameObject.SetActive(false);
			((Graphic)levelCooldown).color = Color.white;
			((TMP_Text)levelCooldown).text = $"{SkillManager.RemainingCooldown(SkillSlot.Primary):0}s remaining...";
		}
		Skill skill2 = SkillDatabase.Get(Plugin.SelectedClass, SkillSlot.Secondary);
		((TMP_Text)skillText2).text = skill2.Name;
		if (SkillManager.IsReady(SkillSlot.Secondary))
		{
			((Component)levelKey2).gameObject.SetActive(true);
			((Graphic)levelCooldown2).color = Color.green;
			((TMP_Text)levelCooldown2).text = "READY";
		}
		else
		{
			((Component)levelKey2).gameObject.SetActive(false);
			((Graphic)levelCooldown2).color = Color.white;
			((TMP_Text)levelCooldown2).text = $"{SkillManager.RemainingCooldown(SkillSlot.Secondary):0}s remaining...";
		}
	}

	private static TextMeshProUGUI CreateText(Transform uiParent, string name, string text, Vector2 position, float size, Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(uiParent, false);
		RectTransform obj = val.AddComponent<RectTransform>();
		obj.anchorMin = new Vector2(0f, 1f);
		obj.anchorMax = new Vector2(0f, 1f);
		obj.pivot = new Vector2(0f, 1f);
		obj.anchoredPosition = position;
		obj.sizeDelta = new Vector2(480f, 50f);
		TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)obj2).font = ((TMP_Text)skillText).font;
		((TMP_Text)obj2).fontSharedMaterial = ((TMP_Text)skillText).fontSharedMaterial;
		((TMP_Text)obj2).fontSize = size;
		((TMP_Text)obj2).fontSizeMin = size;
		((Graphic)obj2).color = color;
		((TMP_Text)obj2).text = text;
		((TMP_Text)obj2).alignment = (TextAlignmentOptions)257;
		return obj2;
	}

	private static void DestroyAllChildren(GameObject parent)
	{
		for (int num = parent.transform.childCount - 1; num >= 0; num--)
		{
			Object.Destroy((Object)(object)((Component)parent.transform.GetChild(num)).gameObject);
		}
	}
}
public enum PlayerClass
{
	None,
	Warrior,
	Paladin,
	Scout,
	Druid,
	Mage
}
public enum SkillSlot
{
	Primary,
	Secondary
}
[HarmonyPatch(typeof(RunManager), "Update")]
internal static class ClassUI
{
	public static GameObject classUI;

	private static TextMeshProUGUI classText;

	private static TextMeshProUGUI helpIcon;

	private static TextMeshProUGUI helpKey;

	private static TextMeshProUGUI leftArrow;

	private static TextMeshProUGUI rightArrow;

	private static TextMeshProUGUI leftKey;

	private static TextMeshProUGUI rightKey;

	private static void Postfix()
	{
		//IL_0067: 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)
		if (!Plugin.EnableMod.Value || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
		{
			return;
		}
		if ((Object)(object)classUI == (Object)null)
		{
			CreateUI();
		}
		bool flag = Plugin.DebugAllow || KonamiCheatRelay.FreeClassChangeUnlocked;
		if (SemiFunc.RunIsLobby() || SemiFunc.RunIsShop() || (flag && SemiFunc.RunIsLevel()))
		{
			if (Input.GetKeyDown(Plugin.PreviousClassKey.Value))
			{
				PreviousClass();
				Refresh();
			}
			if (Input.GetKeyDown(Plugin.NextClassKey.Value))
			{
				NextClass();
				Refresh();
			}
		}
		if (SemiFunc.RunIsLobby() || SemiFunc.RunIsShop() || flag)
		{
			classUI.SetActive(true);
			((Component)helpIcon).gameObject.SetActive(true);
			((Component)helpKey).gameObject.SetActive(true);
			((Component)leftArrow).gameObject.SetActive(true);
			((Component)rightArrow).gameObject.SetActive(true);
			((Component)leftKey).gameObject.SetActive(true);
			((Component)rightKey).gameObject.SetActive(true);
		}
		else if (SemiFunc.RunIsLevel())
		{
			classUI.SetActive(true);
			((Component)helpIcon).gameObject.SetActive(true);
			((Component)helpKey).gameObject.SetActive(true);
			((Component)leftArrow).gameObject.SetActive(false);
			((Component)rightArrow).gameObject.SetActive(false);
			((Component)leftKey).gameObject.SetActive(false);
			((Component)rightKey).gameObject.SetActive(false);
		}
		else
		{
			classUI.SetActive(false);
		}
	}

	private static void CreateUI()
	{
		//IL_00a0: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Unknown result type (might be due to invalid IL or missing references)
		classUI = Object.Instantiate<GameObject>(((Component)EnergyUI.instance).gameObject, ((Component)EnergyUI.instance).transform.parent);
		((Object)classUI).name = "ClassUI";
		Object.Destroy((Object)(object)classUI.GetComponent<EnergyUI>());
		DestroyIfExists(classUI.transform, "EnergyMax");
		DestroyIfExists(classUI.transform, "Zap");
		DestroyIfExists(classUI.transform, "Scanlines");
		classText = classUI.GetComponent<TextMeshProUGUI>();
		((TMP_Text)classText).fontSize = 32f;
		((Graphic)classText).color = Color.white;
		((TMP_Text)classText).alignment = (TextAlignmentOptions)4097;
		RectTransform component = classUI.GetComponent<RectTransform>();
		component.sizeDelta = new Vector2(260f, 30f);
		component.anchoredPosition = new Vector2(0f, -62f);
		helpIcon = CreateText("HelpIcon", "◩", new Vector2(-120f, -25f), 24f, Color.yellow);
		leftArrow = CreateText("LeftArrow", "◀", new Vector2(-90f, -25f), 24f, Color.yellow);
		rightArrow = CreateText("RightArrow", "▶", new Vector2(-60f, -25f), 24f, Color.yellow);
		helpKey = CreateText("HelpKey", ((object)Plugin.ToggleSkillUIKey.Value/*cast due to .constrained prefix*/).ToString(), new Vector2(-120f, -50f), 18f, Color.grey);
		leftKey = CreateText("LeftKey", ((object)Plugin.PreviousClassKey.Value/*cast due to .constrained prefix*/).ToString(), new Vector2(-90f, -50f), 18f, Color.grey);
		rightKey = CreateText("RightKey", ((object)Plugin.NextClassKey.Value/*cast due to .constrained prefix*/).ToString(), new Vector2(-60f, -50f), 18f, Color.grey);
		Refresh();
	}

	private static TextMeshProUGUI CreateText(string name, string text, Vector2 position, float size, Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(classUI.transform, false);
		val.AddComponent<RectTransform>().anchoredPosition = position;
		TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)obj).font = ((TMP_Text)classText).font;
		((TMP_Text)obj).fontSharedMaterial = ((TMP_Text)classText).fontSharedMaterial;
		((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
		((TMP_Text)obj).fontSize = size;
		((Graphic)obj).color = color;
		((TMP_Text)obj).text = text;
		return obj;
	}

	private static void Refresh()
	{
		if (!((Object)(object)classText == (Object)null))
		{
			((TMP_Text)classText).text = Plugin.SelectedClass.ToString();
		}
	}

	private static void PreviousClass()
	{
		int length = Enum.GetValues(typeof(PlayerClass)).Length;
		Plugin.SelectedClass = (PlayerClass)((int)(Plugin.SelectedClass - 1 + length) % length);
	}

	private static void NextClass()
	{
		int length = Enum.GetValues(typeof(PlayerClass)).Length;
		Plugin.SelectedClass = (PlayerClass)((int)(Plugin.SelectedClass + 1) % length);
	}

	private static void DestroyIfExists(Transform parent, string name)
	{
		Transform val = parent.Find(name);
		if ((Object)(object)val != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)val).gameObject);
		}
	}
}
[BepInPlugin("com.spefire.rpgskillsmod", "RPGSkillsMod", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public const string ModGUID = "com.spefire.rpgskillsmod";

	public const string ModName = "RPGSkillsMod";

	public const string ModVersion = "1.1.0";

	public const string totallyNormalString = "Why would you want to cheat?... :o It's no fun. :') :'D";

	public static ConfigEntry<bool> EnableMod;

	public static ConfigEntry<KeyCode> PreviousClassKey;

	public static ConfigEntry<KeyCode> NextClassKey;

	public static ConfigEntry<KeyCode> SkillKey;

	public static ConfigEntry<KeyCode> SkillKey2;

	public static ConfigEntry<KeyCode> ToggleSkillUIKey;

	internal static ManualLogSource Log;

	public static PlayerClass SelectedClass;

	public static bool DebugAllow;

	private void Awake()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the mod.");
		PreviousClassKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "PreviousClassKey", (KeyCode)287, "Key used to select the previous class.");
		NextClassKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "NextClassKey", (KeyCode)289, "Key used to select the next class.");
		SkillKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "SkillKey", (KeyCode)102, "Key used to activate the primary skill.");
		SkillKey2 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "SkillKey2", (KeyCode)103, "Key used to activate the secondary skill.");
		ToggleSkillUIKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleSkillUIKey", (KeyCode)104, "Key used to show or hide the skill UI.");
		Log.LogInfo((object)"RPGSkillsMod loaded...");
		new Harmony("com.spefire.rpgskillsmod").PatchAll();
		Log.LogInfo((object)"...with Harmony patched !");
	}
}
public class Skill
{
	public string Name { get; set; }

	public string Description { get; set; }

	public List<string> Properties { get; set; }

	public float Cooldown { get; set; }

	public float ActiveDuration { get; protected set; } = 2f;

	public Skill()
	{
		Name = "No skill";
		Description = "";
		Properties = new List<string>();
		Cooldown = 0f;
	}

	public virtual bool Execute()
	{
		return true;
	}

	public virtual void Update()
	{
	}
}
public static class SkillDatabase
{
	private class ClassSkills
	{
		public readonly Skill Primary;

		public readonly Skill Secondary;

		public ClassSkills(Skill primary, Skill secondary)
		{
			Primary = primary;
			Secondary = secondary;
		}
	}

	private static readonly Dictionary<PlayerClass, ClassSkills> Skills = new Dictionary<PlayerClass, ClassSkills>
	{
		{
			PlayerClass.None,
			new ClassSkills(new Skill(), new Skill())
		},
		{
			PlayerClass.Druid,
			new ClassSkills(new DruidSkill(), new NecromancerSkill())
		},
		{
			PlayerClass.Warrior,
			new ClassSkills(new WarriorSkill(), new RangerSkill())
		},
		{
			PlayerClass.Scout,
			new ClassSkills(new ScoutSkill(), new TreasureHunterSkill())
		},
		{
			PlayerClass.Paladin,
			new ClassSkills(new PaladinSkill(), new MonkSkill())
		},
		{
			PlayerClass.Mage,
			new ClassSkills(new AssassinSkill(), new BlacksmithSkill())
		}
	};

	public static Skill Get(PlayerClass playerClass, SkillSlot slot)
	{
		ClassSkills classSkills = Skills[playerClass];
		if (slot != SkillSlot.Primary)
		{
			return classSkills.Secondary;
		}
		return classSkills.Primary;
	}
}