Decompiled source of LevelingSystem Fixed v0.5.19

plugins/Cozyheim_CoreAPI.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CoreAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CoreAPI")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("82567395-190E-4D2E-B63A-E651911C76E4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Cozyheim.DifficultyScaler;

public class DifficultyScalerBase : MonoBehaviour
{
	private readonly Dictionary<DifficultyScalerMultiplier, float> _multipliers = new Dictionary<DifficultyScalerMultiplier, float>();

	public float StartHealth { get; private set; }

	public int Level { get; private set; }

	private void Awake()
	{
		Character component = ((Component)this).GetComponent<Character>();
		if (!((Object)(object)component == (Object)null))
		{
			StartHealth = component.m_health;
		}
	}

	private void Start()
	{
		Setup();
	}

	private void Setup()
	{
		Character component = ((Component)this).GetComponent<Character>();
		ZNetView val = default(ZNetView);
		if ((Object)(object)component == (Object)null || !((Component)this).TryGetComponent<ZNetView>(ref val))
		{
			return;
		}
		ZDO zDO = val.GetZDO();
		if (zDO == null)
		{
			return;
		}
		Level = zDO.GetInt(ZDOVars.s_level, 1);
		float @float = zDO.GetFloat(ZDOVars.s_maxHealth, StartHealth);
		if (!Mathf.Approximately(@float, StartHealth) && !Mathf.Approximately(@float, StartHealth * (float)Level))
		{
			return;
		}
		StartHealth *= Level;
		float num = 1f + GetTotalHealthMultiplier();
		component.SetMaxHealth(StartHealth * num);
		foreach (KeyValuePair<DifficultyScalerMultiplier, float> multiplier in _multipliers)
		{
			GetMultiplier(multiplier.Key);
		}
	}

	public void SetMultiplier(DifficultyScalerMultiplier multiplierType, float multiplierValue)
	{
		if (_multipliers.ContainsKey(multiplierType))
		{
			_multipliers[multiplierType] = multiplierValue;
		}
		else
		{
			_multipliers.Add(multiplierType, multiplierValue);
		}
	}

	public float GetMultiplier(DifficultyScalerMultiplier multiplierType)
	{
		if (!_multipliers.TryGetValue(multiplierType, out var value))
		{
			return 0f;
		}
		if (!IsMultiplierBasedOnLevel(multiplierType))
		{
			return value;
		}
		return (float)(Level - 1) * value;
	}

	public float GetSumOfMultipliers(IEnumerable<DifficultyScalerMultiplier> multiplierTypes)
	{
		return multiplierTypes.Sum((Func<DifficultyScalerMultiplier, float>)GetMultiplier);
	}

	public float GetTotalDamageMultiplier()
	{
		return _multipliers.Sum((KeyValuePair<DifficultyScalerMultiplier, float> keyValuePair) => (keyValuePair.Key != DifficultyScalerMultiplier.HealthMultiplier) ? GetMultiplier(keyValuePair.Key) : 0f);
	}

	public float GetTotalHealthMultiplier()
	{
		return _multipliers.Sum((KeyValuePair<DifficultyScalerMultiplier, float> keyValuePair) => (keyValuePair.Key != 0) ? GetMultiplier(keyValuePair.Key) : 0f);
	}

	public bool IsMultiplierBasedOnLevel(DifficultyScalerMultiplier multiplierType)
	{
		return multiplierType == DifficultyScalerMultiplier.StarMultiplier;
	}
}
public enum DifficultyScalerMultiplier
{
	DamageMultiplier,
	HealthMultiplier,
	NightMultiplier,
	BossKillMultiplier,
	StarMultiplier,
	BiomeMultiplier
}

plugins/Cozyheim_LevelingSystem.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Cozyheim.DifficultyScaler;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using MonoMod.Utils;
using SimpleJson;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LevelingSystem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LevelingSystem")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4d2a4a69-cbcf-4527-b504-7c1d1d3b3696")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public enum SkillCategory
{
	Offensive,
	Defensive,
	Core,
	Utility
}
public enum XPType
{
	Regular,
	MonsterLevel,
	Rested
}
namespace Cozyheim.LevelingSystem;

public class CritTextAnim : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <Start>d__6 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CritTextAnim <>4__this;

		private Vector3 <startSize>5__2;

		private float <f>5__3;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_0188: 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)
			int num = <>1__state;
			CritTextAnim critTextAnim = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				Vector3 zero = Vector3.zero;
				zero += Random.Range(0f - critTextAnim.spread, critTextAnim.spread) * ((Component)Camera.main).transform.right;
				zero += Random.Range(0f, critTextAnim.spread) * ((Component)Camera.main).transform.up;
				Transform transform = ((Component)critTextAnim).transform;
				transform.position += zero;
				Keyframe[] array = (Keyframe[])(object)new Keyframe[5]
				{
					new Keyframe(0f, 0f, 0f, 1f),
					new Keyframe(0.08f, 1.2f, 0f, 2f),
					new Keyframe(0.15f, 1f, -2f, 0f),
					new Keyframe(0.75f, 1f, 0f, -0.5f),
					new Keyframe(1f, 0f, 0f, 0f)
				};
				critTextAnim.animCurve = new AnimationCurve(array);
				<startSize>5__2 = ((Component)critTextAnim).transform.localScale;
				<f>5__3 = 0f;
				break;
			}
			case 1:
				<>1__state = -1;
				<f>5__3 += Time.deltaTime;
				break;
			}
			if (<f>5__3 < critTextAnim.fullAnimTime)
			{
				float num2 = <f>5__3 / critTextAnim.fullAnimTime;
				((Component)critTextAnim).transform.localScale = <startSize>5__2 * critTextAnim.damageSizeScale * critTextAnim.animCurve.Evaluate(num2);
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			Object.Destroy((Object)(object)((Component)critTextAnim).gameObject);
			return false;
		}

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

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

	private AnimationCurve animCurve;

	private float fullAnimTime = 3f;

	private float maxCritSize = 1f;

	private float damageSizeScale = 1f;

	private float spread = 0.5f;

	private void Update()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.eulerAngles = ((Component)Camera.main).transform.eulerAngles;
	}

	[IteratorStateMachine(typeof(<Start>d__6))]
	private IEnumerator Start()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Start>d__6(0)
		{
			<>4__this = this
		};
	}

	private void SetColorAndScale(float damage)
	{
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		Text componentInChildren = ((Component)this).GetComponentInChildren<Text>();
		Color color = default(Color);
		((Color)(ref color))..ctor(0.8f, 0.6f, 0.15f, 1f);
		if (damage < 30f)
		{
			damageSizeScale = 1f;
			color.g = 0.6f;
		}
		else if (damage < 100f)
		{
			damageSizeScale = 1.2f;
			color.g = 0.45f;
		}
		else if (damage < 200f)
		{
			damageSizeScale = 1.4f;
			color.g = 0.3f;
		}
		else if (damage < 300f)
		{
			damageSizeScale = 1.6f;
			color.g = 0.15f;
		}
		else
		{
			damageSizeScale = 1.8f;
			color.g = 0f;
		}
		((Graphic)componentInChildren).color = color;
	}

	public void SetText(string value)
	{
		((Component)this).GetComponentInChildren<Text>().text = value.ToString(CultureInfo.GetCultureInfo("en-US"));
	}

	public void SetText(float value, int decimals = 0)
	{
		decimals = Mathf.Max(0, decimals);
		string text = "N" + decimals;
		SetText(value.ToString(text));
		SetColorAndScale(value);
	}

	public void SetText(int value)
	{
		SetText(value.ToString());
	}
}
[HarmonyPatch]
internal class LevelingDummy_Patch
{
	[HarmonyPrefix]
	[HarmonyPatch(typeof(CraftingStation), "Interact")]
	private static bool CraftingStation_Interact_Prefix(CraftingStation __instance)
	{
		if ((Object)(object)((Component)__instance).transform.parent != (Object)null && ((Object)((Component)__instance).transform.parent).name.StartsWith("LevelingDummy") && !UIManager.Instance.skillsUIVisible)
		{
			UIManager.Instance.ToggleSkillsUI(value: true);
			return false;
		}
		return true;
	}
}
internal class RPC_LevelUpVFX
{
	[CompilerGenerated]
	private sealed class <LevelUpVFX_Server>d__3 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public ZPackage package;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			if (<>1__state != 0)
			{
				return false;
			}
			<>1__state = -1;
			ConsoleLog.Print("LevelUpVFX RPC");
			if (!NetworkHandler.IsServer() || package == null)
			{
				return false;
			}
			ConsoleLog.Print("LevelUpVFX RPC Server");
			long num = package.ReadLong();
			Player player = Player.GetPlayer(num);
			if (!Object.op_Implicit((Object)(object)player))
			{
				ConsoleLog.Print($"Couldn't find a player with id '{num}'. Cancelling level up vfx.", LogType.Error);
				return false;
			}
			ZPackage val = new ZPackage();
			val.Write(num);
			spawnVFX.SendPackage(ZRoutedRpc.Everybody, val);
			ConsoleLog.Print("Player with ID " + num + " (" + player.GetPlayerName() + ") leveled up!");
			return false;
		}

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

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

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

		private object <>2__current;

		public ZPackage package;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				ConsoleLog.Print("SpawnVFX");
				if ((Object)(object)UIManager.Instance != (Object)null)
				{
					ConsoleLog.Print("SpawnVFX !UIManager");
					UIManager.rpc_LevelUpEffect.SendPackage(ZRoutedRpc.Everybody, package);
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				return false;
			}
		}

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

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

	public static CustomRPC levelUpVFX;

	public static CustomRPC spawnVFX;

	public static void SetupRPC()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_0027: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0053: Expected O, but got Unknown
		levelUpVFX = NetworkManager.Instance.AddRPC("LevelUpVFX_Server", new CoroutineHandler(LevelUpVFX_Server), new CoroutineHandler(LevelUpVFX_Server));
		spawnVFX = NetworkManager.Instance.AddRPC("SpawnVFX_Server", new CoroutineHandler(SpawnVFX), new CoroutineHandler(SpawnVFX));
	}

	[IteratorStateMachine(typeof(<LevelUpVFX_Server>d__3))]
	private static IEnumerator LevelUpVFX_Server(long sender, ZPackage package)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LevelUpVFX_Server>d__3(0)
		{
			package = package
		};
	}

	[IteratorStateMachine(typeof(<SpawnVFX>d__4))]
	private static IEnumerator SpawnVFX(long sender, ZPackage package)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SpawnVFX>d__4(0)
		{
			package = package
		};
	}
}
internal class NetworkHandler
{
	public static void Init()
	{
		RPC_LevelUpVFX.SetupRPC();
	}

	public static void LevelUpVFX()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		ConsoleLog.Print("LevelUpVFX");
		ZPackage val = new ZPackage();
		val.Write(GetLocalPlayerID());
		RPC_LevelUpVFX.levelUpVFX.SendPackage(ZRoutedRpc.Everybody, val);
	}

	public static bool IsServer()
	{
		return ZNet.instance.IsServer();
	}

	public static bool IsAdmin()
	{
		if (!SynchronizationManager.Instance.PlayerIsAdmin)
		{
			return false;
		}
		return true;
	}

	private static long GetLocalPlayerID()
	{
		return Player.m_localPlayer.GetPlayerID();
	}
}
internal class SkillCriticalHitDamage : SkillBase
{
	public static SkillCriticalHitDamage Instance;

	public SkillCriticalHitDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.CriticalDamage;
		Instance = this;
	}
}
internal class SkillResistanceSpirit : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_spirit *= num;
			}
		}
	}

	public static SkillResistanceSpirit Instance;

	public SkillResistanceSpirit(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceSpirit;
		Instance = this;
	}
}
internal class SkillResistancePoison : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "AddPoisonDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref float damage)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				damage *= num;
			}
		}
	}

	public static SkillResistancePoison Instance;

	public SkillResistancePoison(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistancePoison;
		Instance = this;
	}
}
internal class SkillResistanceFrost : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_frost *= num;
			}
		}
	}

	public static SkillResistanceFrost Instance;

	public SkillResistanceFrost(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceFrost;
		Instance = this;
	}
}
internal class SkillResistanceLightning : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_lightning *= num;
			}
		}
	}

	public static SkillResistanceLightning Instance;

	public SkillResistanceLightning(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceLightning;
		Instance = this;
	}
}
internal class SkillResistanceFire : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "AddFireDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref float damage)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				damage *= num;
			}
		}
	}

	public static SkillResistanceFire Instance;

	public SkillResistanceFire(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceFire;
		Instance = this;
	}
}
internal class SkillResistancePierce : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_pierce *= num;
			}
		}
	}

	public static SkillResistancePierce Instance;

	public SkillResistancePierce(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistancePierce;
		Instance = this;
	}
}
internal class SkillResistanceBlunt : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_blunt *= num;
			}
		}
	}

	public static SkillResistanceBlunt Instance;

	public SkillResistanceBlunt(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceBlunt;
		Instance = this;
	}
}
internal class SkillResistanceSlash : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_slash *= num;
			}
		}
	}

	public static SkillResistanceSlash Instance;

	public SkillResistanceSlash(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ResistanceSlash;
		Instance = this;
	}
}
internal class SkillConfig
{
	public static List<SkillSettings> skillSettings = new List<SkillSettings>
	{
		new SkillSettings
		{
			skillType = SkillType.HP,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.Stamina,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.Eitr,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.HPRegen,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.StaminaRegen,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.EitrRegen,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Core,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.CarryWeight,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 7.5f,
			category = SkillCategory.Utility,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.Woodcutting,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Utility,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.Mining,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Utility,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.PhysicalDamage,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Offensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ElementalDamage,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Offensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.PhysicalResistance,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceBlunt,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceSlash,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistancePierce,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ElementalResistance,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1.5f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceFire,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceFrost,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceLightning,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistancePoison,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.ResistanceSpirit,
			enabled = true,
			defaultMaxLevel = 30,
			defaultBonusValue = 3f,
			category = SkillCategory.Defensive,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.MovementSpeed,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 1f,
			category = SkillCategory.Utility,
			defaultBaseValue = 0f
		},
		new SkillSettings
		{
			skillType = SkillType.CriticalChance,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 0.5f,
			category = SkillCategory.Offensive,
			defaultBaseValue = 1f
		},
		new SkillSettings
		{
			skillType = SkillType.CriticalDamage,
			enabled = true,
			defaultMaxLevel = 20,
			defaultBonusValue = 5f,
			category = SkillCategory.Offensive,
			defaultBaseValue = 10f
		}
	};

	public static void Init()
	{
		foreach (SkillSettings skillSetting in skillSettings)
		{
			skillSetting.CreateConfigEntries();
		}
	}

	public static SkillSettings GetSkill(SkillType skillType)
	{
		foreach (SkillSettings skillSetting in skillSettings)
		{
			if (skillSetting.skillType == skillType)
			{
				return skillSetting;
			}
		}
		return null;
	}
}
internal class SkillSettings
{
	public SkillCategory category;

	private ConfigEntry<string> configSettings;

	public float defaultBaseValue;

	public float defaultBonusValue;

	public int defaultMaxLevel;

	public bool enabled;

	public SkillType skillType;

	public void CreateConfigEntries()
	{
		string value = enabled + ":" + defaultMaxLevel + ":" + defaultBonusValue + ":" + defaultBaseValue;
		configSettings = Main.CreateConfigEntry("Skills", skillType.ToString(), value, "Settings for " + skillType.ToString() + ". Must follow the following format 'bool:int:float:float' (enabled:maxLevel:bonusValue:baseValue)", synchronizedSetting: true, requiresAdminToChange: true);
	}

	public bool GetEnabled()
	{
		return bool.Parse(configSettings.Value.Split(new char[1] { ':' })[0]);
	}

	public int GetMaxLevel()
	{
		int.TryParse(configSettings.Value.Split(new char[1] { ':' })[1], out var result);
		return result;
	}

	public float GetBonusValue()
	{
		string obj = configSettings.Value.Split(new char[1] { ':' })[2];
		float result;
		bool flag = float.TryParse(obj, out result);
		float result2;
		bool flag2 = float.TryParse(obj.Replace(',', '.'), out result2);
		float result3;
		bool flag3 = float.TryParse(obj.Replace('.', ','), out result3);
		float result4 = 0f;
		if (flag && flag2 && flag3)
		{
			result4 = Mathf.Min(Mathf.Min(result, result2), result3);
		}
		else if (flag && flag2)
		{
			result4 = Mathf.Min(result, result2);
		}
		else if (flag && flag3)
		{
			result4 = Mathf.Min(result, result3);
		}
		else if (flag2 && flag3)
		{
			result4 = Mathf.Min(result2, result3);
		}
		else if (flag)
		{
			result4 = result;
		}
		else if (flag2)
		{
			result4 = result2;
		}
		else if (flag3)
		{
			result4 = result3;
		}
		return result4;
	}

	public float GetBaseValue()
	{
		string[] array = configSettings.Value.Split(new char[1] { ':' });
		string text = ((array.Length >= 4) ? array[3] : defaultBaseValue.ToString());
		float result;
		bool flag = float.TryParse(text, out result);
		float result2;
		bool flag2 = float.TryParse(text.Replace(',', '.'), out result2);
		float result3;
		bool flag3 = float.TryParse(text.Replace('.', ','), out result3);
		float result4 = 0f;
		if (flag && flag2 && flag3)
		{
			result4 = Mathf.Min(Mathf.Min(result, result2), result3);
		}
		else if (flag && flag2)
		{
			result4 = Mathf.Min(result, result2);
		}
		else if (flag && flag3)
		{
			result4 = Mathf.Min(result, result3);
		}
		else if (flag2 && flag3)
		{
			result4 = Mathf.Min(result2, result3);
		}
		else if (flag)
		{
			result4 = result;
		}
		else if (flag2)
		{
			result4 = result2;
		}
		else if (flag3)
		{
			result4 = result3;
		}
		return result4;
	}
}
internal class SkillCriticalHitChance : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		[HarmonyPriority(0)]
		private static void Character_ApplyDamage_Prefix(Character __instance, ref HitData hit, ref bool showDamageText)
		{
			//IL_001b: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && SkillCriticalHitDamage.Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0 && Random.Range(0f, 100f) < Instance.GetBonus())
			{
				float num = 1f + SkillCriticalHitDamage.Instance.GetBonus() / 100f;
				hit.m_damage.m_blunt *= num;
				hit.m_damage.m_slash *= num;
				hit.m_damage.m_pierce *= num;
				hit.m_damage.m_chop *= num;
				hit.m_damage.m_pickaxe *= num;
				hit.m_damage.m_fire *= num;
				hit.m_damage.m_frost *= num;
				hit.m_damage.m_lightning *= num;
				hit.m_damage.m_poison *= num;
				hit.m_damage.m_spirit *= num;
				SkillManager.Instance.SpawnCriticalHitVFX(hit.m_point, hit.GetTotalDamage());
				showDamageText = false;
			}
		}
	}

	public static SkillCriticalHitChance Instance;

	public SkillCriticalHitChance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.CriticalChance;
		Instance = this;
	}
}
internal class SkillEitrRegen : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SEMan), "ModifyEitrRegen")]
		private static void SEMan_ModifyEitrRegen_Postfix(Character ___m_character, ref float eitrMultiplier)
		{
			if (Instance != null && ___m_character.IsPlayer())
			{
				eitrMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f / 2f;
			}
		}
	}

	public static SkillEitrRegen Instance;

	public SkillEitrRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.EitrRegen;
		Instance = this;
	}
}
internal class SkillStaminaRegen : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")]
		private static void SEMan_ModifyStaminaRegen_Postfix(ref float staminaMultiplier)
		{
			if (Instance != null)
			{
				staminaMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f;
			}
		}
	}

	public static SkillStaminaRegen Instance;

	public SkillStaminaRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.StaminaRegen;
		Instance = this;
	}
}
internal class SkillHPRegen : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")]
		private static void SEMan_ModifyHealthRegen_Postfix(ref float regenMultiplier)
		{
			if (Instance != null)
			{
				regenMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f;
			}
		}
	}

	public static SkillHPRegen Instance;

	public SkillHPRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.HPRegen;
		Instance = this;
	}
}
internal class SkillMovementSpeed : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetJogSpeedFactor")]
		private static void Player_GetJogSpeedFactor_Postfix(Player __instance, ref float __result)
		{
			if (Instance != null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				float num = (float)Instance.level * Instance.bonusPerLevel / 100f;
				__result += num;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetRunSpeedFactor")]
		private static void Player_GetRunSpeedFactor_Postfix(Player __instance, ref float __result)
		{
			if (Instance != null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				float num = (float)Instance.level * Instance.bonusPerLevel / 100f;
				float num2 = num * 0.25f;
				float num3 = __result + num * 0.25f;
				float num4 = 1f + ((Character)__instance).GetEquipmentMovementModifier() + num;
				__result = ((num3 > num4 + num2) ? num3 : (num3 + num2));
			}
		}
	}

	public static SkillMovementSpeed Instance;

	public SkillMovementSpeed(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.MovementSpeed;
		Instance = this;
	}
}
internal class SkillElementalResistance : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_lightning *= num;
				hit.m_damage.m_frost *= num;
				hit.m_damage.m_spirit *= num;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "AddFireDamage")]
		private static void Character_FireResistance_Prefix(Character __instance, ref float damage)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				damage *= num;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "AddPoisonDamage")]
		private static void Character_PoisonResistance_Prefix(Character __instance, ref float damage)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				damage *= num;
			}
		}
	}

	public static SkillElementalResistance Instance;

	public SkillElementalResistance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ElementalResistance;
		Instance = this;
	}
}
internal class SkillElementalDamage : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_ElementalDamage_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0)
			{
				float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_fire *= num;
				hit.m_damage.m_lightning *= num;
				hit.m_damage.m_frost *= num;
				hit.m_damage.m_poison *= num;
				hit.m_damage.m_spirit *= num;
			}
		}
	}

	public static SkillElementalDamage Instance;

	public SkillElementalDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.ElementalDamage;
		Instance = this;
	}
}
internal class SkillPhysicalResistance : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0)
			{
				float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_blunt *= num;
				hit.m_damage.m_slash *= num;
				hit.m_damage.m_pierce *= num;
			}
		}
	}

	public static SkillPhysicalResistance Instance;

	public SkillPhysicalResistance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.PhysicalResistance;
		Instance = this;
	}
}
internal class SkillPhysicalDamage : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static void Character_PhysicalDamage_Prefix(Character __instance, ref HitData hit)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0)
			{
				float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f;
				hit.m_damage.m_blunt *= num;
				hit.m_damage.m_slash *= num;
				hit.m_damage.m_pierce *= num;
			}
		}
	}

	public static SkillPhysicalDamage Instance;

	public SkillPhysicalDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.PhysicalDamage;
		Instance = this;
	}
}
internal class SkillOption : MonoBehaviour
{
	public Button addPointButton;

	public Button removePointButton;

	public Button resetPointButton;

	private CanvasGroup addPointButtonGroup;

	private Text bonusText;

	private Text bonusTextShadow;

	private Text description;

	private Image iconImage;

	private Image levelFillBar;

	private Text levelText;

	private Text levelTextShadow;

	private Text maxLevelText;

	private Text nameText;

	private Text nameTextShadow;

	private CanvasGroup removePointButtonGroup;

	private CanvasGroup resetPointButtonGroup;

	private GameObject resetTextGO;

	public void Setup()
	{
		nameText = ((Component)((Component)this).transform.Find("Skill Name")).GetComponent<Text>();
		nameTextShadow = ((Component)((Component)this).transform.Find("Skill Name/Skill Name Shadow")).GetComponent<Text>();
		bonusText = ((Component)((Component)this).transform.Find("Bonus Text")).GetComponent<Text>();
		bonusTextShadow = ((Component)((Component)this).transform.Find("Bonus Text/Bonus Text Shadow")).GetComponent<Text>();
		levelText = ((Component)((Component)this).transform.Find("Skill Level")).GetComponent<Text>();
		levelTextShadow = ((Component)((Component)this).transform.Find("Skill Level/Skill Level Shadow")).GetComponent<Text>();
		maxLevelText = ((Component)((Component)this).transform.Find("Skill Level Ring/Skill Level Max")).GetComponent<Text>();
		description = ((Component)((Component)this).transform.Find("Description")).GetComponent<Text>();
		iconImage = ((Component)((Component)this).transform.Find("Skill Icon")).GetComponent<Image>();
		levelFillBar = ((Component)((Component)this).transform.Find("Skill Level Ring/Skill Level Fill Slider")).GetComponent<Image>();
		addPointButton = ((Component)((Component)this).transform.Find("Add Skill Point (Mask)/Add Skill Point")).GetComponent<Button>();
		addPointButtonGroup = ((Component)((Component)this).transform.Find("Add Skill Point (Mask)/Add Skill Point")).GetComponent<CanvasGroup>();
		removePointButton = ((Component)((Component)this).transform.Find("Remove Skill Point (Mask)/Remove Skill Point")).GetComponent<Button>();
		removePointButtonGroup = ((Component)((Component)this).transform.Find("Remove Skill Point (Mask)/Remove Skill Point")).GetComponent<CanvasGroup>();
		resetPointButton = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Skill Point")).GetComponent<Button>();
		resetPointButtonGroup = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Skill Point")).GetComponent<CanvasGroup>();
		resetTextGO = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Text")).gameObject;
	}

	private void ToggleButtonVisibility(CanvasGroup cnvGroup, bool value)
	{
		cnvGroup.alpha = (value ? 1f : 0f);
		cnvGroup.interactable = value;
	}

	public void UpdateAllButtonVisibility(SkillBase skillInfo)
	{
		ToggleButtonVisibility(addPointButtonGroup, !skillInfo.IsLevelMax());
		ToggleButtonVisibility(removePointButtonGroup, !skillInfo.IsLevelZero());
		ToggleButtonVisibility(resetPointButtonGroup, !skillInfo.IsLevelZero());
		resetTextGO.SetActive(!skillInfo.IsLevelZero());
	}

	public void UpdateInformation(SkillBase skillInfo)
	{
		UpdateAllButtonVisibility(skillInfo);
		nameText.text = skillInfo.GetName();
		nameTextShadow.text = skillInfo.GetName();
		bonusText.text = "+" + skillInfo.GetBonus() + skillInfo.bonusUnit;
		bonusTextShadow.text = "+" + skillInfo.GetBonus() + skillInfo.bonusUnit;
		levelText.text = skillInfo.GetLevel().ToString();
		levelTextShadow.text = skillInfo.GetLevel().ToString();
		maxLevelText.text = skillInfo.GetMaxLevel().ToString();
		iconImage.sprite = Main.assetBundle.LoadAsset<Sprite>(Main.assetsPath + "Sprites/Skill Icons/" + skillInfo.iconName + ".png");
		description.text = "+" + skillInfo.bonusPerLevel + skillInfo.bonusUnit + " / Level";
		float num = 0.1245f;
		float num2 = (float)skillInfo.GetLevel() / (float)skillInfo.GetMaxLevel() * 0.75f;
		levelFillBar.fillAmount = num + num2;
	}
}
internal class SkillStamina : SkillBase
{
	[HarmonyPatch]
	private class SkillStamina_Patch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		private static void Player_GetTotalFoodValue_Postfix(ref float stamina)
		{
			if (Instance != null)
			{
				float num = (float)Instance.level * Instance.bonusPerLevel;
				stamina += num;
			}
		}
	}

	public static SkillStamina Instance;

	public SkillStamina(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Stamina;
		Instance = this;
	}
}
internal class SkillEitr : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		private static void Player_GetTotalFoodValue_Postfix(ref float eitr)
		{
			if (Instance != null)
			{
				eitr += (float)Instance.level * Instance.bonusPerLevel;
			}
		}
	}

	public static SkillEitr Instance;

	public SkillEitr(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Eitr;
		Instance = this;
	}
}
internal class SkillWoodcutting : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		private static void ItemData_GetDamage_Woodcutting_Postfix(ItemData __instance, ref DamageTypes __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			if (Instance != null && (int)__instance.m_shared.m_skillType == 7)
			{
				float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f;
				__result.m_chop *= num;
			}
		}
	}

	public static SkillWoodcutting Instance;

	public SkillWoodcutting(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Woodcutting;
		Instance = this;
	}
}
internal class SkillHunting : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Awake")]
		private static void Player_Awake_Prefix()
		{
			_ = Instance;
		}
	}

	public static SkillHunting Instance;

	public SkillHunting(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Hunting;
		Instance = this;
	}
}
internal class SkillFarming : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Awake")]
		private static void Player_Awake_Prefix()
		{
			_ = Instance;
		}
	}

	public static SkillFarming Instance;

	public SkillFarming(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Farming;
		Instance = this;
	}
}
internal class SkillMining : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		private static void ItemData_GetDamage_Mining_Postfix(ItemData __instance, ref DamageTypes __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (Instance != null && (int)__instance.m_shared.m_skillType == 12)
			{
				float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f;
				__result.m_pickaxe *= num;
			}
		}
	}

	public static SkillMining Instance;

	public SkillMining(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.Mining;
		Instance = this;
	}
}
internal class SkillHP : SkillBase
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetBaseFoodHP")]
		public static void Player_GetBaseFoodHP_Postfix(ref float __result)
		{
			if (Instance != null)
			{
				__result += (float)Instance.level * Instance.bonusPerLevel;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		public static void Player_GetTotalFoodValue_Postfix(ref float hp)
		{
			if (Instance != null && !Main.modJewelcraftingLoaded)
			{
				hp += (float)Instance.level * Instance.bonusPerLevel;
			}
		}
	}

	public static SkillHP Instance;

	public SkillHP(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.HP;
		Instance = this;
	}
}
internal class SkillCarryWeight : SkillBase
{
	[HarmonyPatch]
	private class SkillCarryWeight_Patch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SEMan), "ModifyMaxCarryWeight")]
		private static void Player_ModifyMaxCarryWeight_Postfix(SEMan __instance, Character ___m_character, ref float limit)
		{
			if (Instance != null && ___m_character.IsPlayer())
			{
				limit += (float)Instance.level * Instance.bonusPerLevel;
			}
		}
	}

	public static SkillCarryWeight Instance;

	public SkillCarryWeight(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f)
		: base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus)
	{
		skillType = SkillType.CarryWeight;
		Instance = this;
	}
}
internal enum SkillType
{
	HP,
	HPRegen,
	Stamina,
	StaminaRegen,
	Eitr,
	EitrRegen,
	CarryWeight,
	MovementSpeed,
	Woodcutting,
	Mining,
	PhysicalDamage,
	ElementalDamage,
	PhysicalResistance,
	ElementalResistance,
	CriticalChance,
	CriticalDamage,
	Hunting,
	Farming,
	ResistanceSlash,
	ResistanceBlunt,
	ResistancePierce,
	ResistanceFire,
	ResistanceFrost,
	ResistanceLightning,
	ResistancePoison,
	ResistanceSpirit,
	EndOfEnum
}
internal class SkillBase
{
	private int _level;

	protected SkillOption uiSettings;

	protected SkillType skillType;

	protected int maxLevel;

	public string displayName;

	public float bonusPerLevel;

	public string bonusUnit;

	public string iconName;

	public float baseBonus;

	protected int level
	{
		get
		{
			return _level;
		}
		set
		{
			_level = value;
		}
	}

	public SkillBase(int maxLevel, float bonusPerLevel, string iconName, string displayName, string bonusUnit = "", float baseBonus = 0f)
	{
		level = 0;
		this.maxLevel = maxLevel;
		this.bonusPerLevel = bonusPerLevel;
		this.bonusUnit = bonusUnit;
		this.displayName = displayName;
		this.iconName = iconName;
		this.baseBonus = baseBonus;
	}

	public void SetSkillUI(SkillOption uiSettings)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		((UnityEventBase)uiSettings.addPointButton.onClick).RemoveAllListeners();
		((UnityEventBase)uiSettings.removePointButton.onClick).RemoveAllListeners();
		((UnityEventBase)uiSettings.resetPointButton.onClick).RemoveAllListeners();
		this.uiSettings = uiSettings;
		((UnityEvent)uiSettings.addPointButton.onClick).AddListener((UnityAction)delegate
		{
			SkillManager.Instance.SkillLevelUp(skillType);
		});
		((UnityEvent)uiSettings.removePointButton.onClick).AddListener((UnityAction)delegate
		{
			SkillManager.Instance.SkillLevelDown(skillType);
		});
		((UnityEvent)uiSettings.resetPointButton.onClick).AddListener((UnityAction)delegate
		{
			SkillManager.Instance.SkillReset(skillType);
		});
	}

	public int ResetLevel()
	{
		int result = level;
		level = 0;
		return result;
	}

	public void SetLevel(int level)
	{
		if (level > GetMaxLevel())
		{
			level = GetMaxLevel();
		}
		if (level < 0)
		{
			level = 0;
		}
		this.level = level;
	}

	public bool AddLevel()
	{
		if (IsLevelMax())
		{
			return false;
		}
		level++;
		return true;
	}

	public bool RemoveLevel()
	{
		if (level <= 0)
		{
			return false;
		}
		level--;
		return true;
	}

	public bool IsLevelMax()
	{
		return level == maxLevel;
	}

	public bool IsLevelZero()
	{
		return level == 0;
	}

	public float GetBonus()
	{
		return bonusPerLevel * (float)level + baseBonus;
	}

	public string GetName()
	{
		return displayName;
	}

	public int GetLevel()
	{
		return level;
	}

	public int GetMaxLevel()
	{
		return maxLevel;
	}

	public void UpdateSkillInformation()
	{
		if ((Object)(object)uiSettings != (Object)null)
		{
			uiSettings.UpdateAllButtonVisibility(this);
			uiSettings.UpdateInformation(this);
		}
	}
}
internal class SkillManager : MonoBehaviour
{
	public int unspendPoints;

	public static SkillManager Instance;

	private GameObject criticalHitVFX;

	private GameObject criticalHitText;

	private float critTextOffsetY = 1f;

	private float critTextOffsetTowardsCam = 0.75f;

	internal static Dictionary<SkillType, SkillBase> skills;

	public static void InitSkills()
	{
		skills = new Dictionary<SkillType, SkillBase>();
		foreach (SkillSettings skillSetting in SkillConfig.skillSettings)
		{
			if (skillSetting.GetEnabled())
			{
				switch (skillSetting.skillType)
				{
				case SkillType.HP:
					skills.Add(skillSetting.skillType, new SkillHP(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "HP", "Health", string.Empty, skillSetting.GetBaseValue()));
					break;
				case SkillType.Stamina:
					skills.Add(skillSetting.skillType, new SkillStamina(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Stamina", "Stamina", string.Empty, skillSetting.GetBaseValue()));
					break;
				case SkillType.Eitr:
					skills.Add(skillSetting.skillType, new SkillEitr(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Eitr", "Eitr", string.Empty, skillSetting.GetBaseValue()));
					break;
				case SkillType.HPRegen:
					skills.Add(skillSetting.skillType, new SkillHPRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "HPRegen", "Health Regen", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.StaminaRegen:
					skills.Add(skillSetting.skillType, new SkillStaminaRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "StaminaRegen", "Stamina Regen", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.EitrRegen:
					skills.Add(skillSetting.skillType, new SkillEitrRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "EitrRegen", "Eitr Regen", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.CarryWeight:
					skills.Add(skillSetting.skillType, new SkillCarryWeight(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CarryWeight", "Carry Weight", string.Empty, skillSetting.GetBaseValue()));
					break;
				case SkillType.Woodcutting:
					skills.Add(skillSetting.skillType, new SkillWoodcutting(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Woodcutting", "Woodcutting", "% damage", skillSetting.GetBaseValue()));
					break;
				case SkillType.Mining:
					skills.Add(skillSetting.skillType, new SkillMining(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Mining", "Mining", "% damage", skillSetting.GetBaseValue()));
					break;
				case SkillType.PhysicalDamage:
					skills.Add(skillSetting.skillType, new SkillPhysicalDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalDamage", "Physical Damage", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ElementalDamage:
					skills.Add(skillSetting.skillType, new SkillElementalDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalDamage", "Elemental Damage", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.PhysicalResistance:
					skills.Add(skillSetting.skillType, new SkillPhysicalResistance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Physical Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceSlash:
					skills.Add(skillSetting.skillType, new SkillResistanceSlash(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Slash Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistancePierce:
					skills.Add(skillSetting.skillType, new SkillResistancePierce(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Pierce Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceBlunt:
					skills.Add(skillSetting.skillType, new SkillResistanceBlunt(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Blunt Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ElementalResistance:
					skills.Add(skillSetting.skillType, new SkillElementalResistance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Elemental Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceFire:
					skills.Add(skillSetting.skillType, new SkillResistanceFire(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Fire Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceFrost:
					skills.Add(skillSetting.skillType, new SkillResistanceFrost(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Frost Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceLightning:
					skills.Add(skillSetting.skillType, new SkillResistanceLightning(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Lightning Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistancePoison:
					skills.Add(skillSetting.skillType, new SkillResistancePoison(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Poison Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.ResistanceSpirit:
					skills.Add(skillSetting.skillType, new SkillResistanceSpirit(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Spirit Resistance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.MovementSpeed:
					skills.Add(skillSetting.skillType, new SkillMovementSpeed(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "MovementSpeed", "Movement Speed", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.CriticalChance:
					skills.Add(skillSetting.skillType, new SkillCriticalHitChance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CriticalHitChance", "Critical Hit Chance", "%", skillSetting.GetBaseValue()));
					break;
				case SkillType.CriticalDamage:
					skills.Add(skillSetting.skillType, new SkillCriticalHitDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CriticalHitDamage", "Critical Hit Damage", "%", skillSetting.GetBaseValue()));
					break;
				}
			}
		}
	}

	public void SpawnCriticalHitVFX(Vector3 position, float damage)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (Main.criticalHitVFX.Value)
		{
			if (Main.criticalHitShake.Value)
			{
				GameCamera.instance.AddShake(((Component)Player.m_localPlayer).transform.position, 10f, Main.criticalHitShakeIntensity.Value, false);
			}
			Vector3 val = ((Component)GameCamera.instance).transform.position - position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = position + Vector3.up * critTextOffsetY + normalized * critTextOffsetTowardsCam;
			Object.Instantiate<GameObject>(criticalHitText, val2, Quaternion.identity).GetComponent<CritTextAnim>().SetText(damage, 1);
			Object.Destroy((Object)(object)Object.Instantiate<GameObject>(criticalHitVFX, position, Quaternion.identity), 4f);
		}
	}

	public void UpdateAllSkillInformation()
	{
		foreach (KeyValuePair<SkillType, SkillBase> skill in skills)
		{
			skill.Value.UpdateSkillInformation();
		}
	}

	public void SkillSetLevel(SkillType skillType, int level)
	{
		SkillBase skillByType = GetSkillByType(skillType);
		if (skillByType != null)
		{
			ConsoleLog.Print("Set skill " + skillType.ToString() + " to level " + level);
			skillByType.SetLevel(level);
			UpdateUnspendPoints();
		}
	}

	public int GetTotalSkillsCount()
	{
		return skills.Count;
	}

	public SkillBase GetSkillByIndex(int index)
	{
		if (skills.ContainsKey((SkillType)index))
		{
			return skills[(SkillType)index];
		}
		return null;
	}

	public SkillBase GetSkillByType(SkillType type)
	{
		if (!skills.TryGetValue(type, out var value))
		{
			return null;
		}
		return value;
	}

	public void SkillLevelUp(SkillType skillType)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		SkillBase skillByType = GetSkillByType(skillType);
		if (skillByType == null || !HasUnspendPoints())
		{
			return;
		}
		int num = 1;
		if (Input.GetKey(Main.addMultiplePointsKey.Value))
		{
			num = Mathf.Min(Main.addMultiplePointsAmount.Value, unspendPoints);
		}
		if (Input.GetKey(Main.addMaxPointsKey.Value))
		{
			num = unspendPoints;
		}
		for (int i = 0; i < num; i++)
		{
			if (!skillByType.AddLevel())
			{
				break;
			}
		}
		UpdateUnspendPoints();
	}

	public void SkillLevelDown(SkillType skillType)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		SkillBase skillByType = GetSkillByType(skillType);
		if (skillByType == null)
		{
			return;
		}
		int num = 1;
		if (Input.GetKey(Main.addMultiplePointsKey.Value))
		{
			num = Main.addMultiplePointsAmount.Value;
		}
		if (Input.GetKey(Main.addMaxPointsKey.Value))
		{
			SkillReset(skillType);
			return;
		}
		for (int i = 0; i < num; i++)
		{
			if (!skillByType.RemoveLevel())
			{
				break;
			}
		}
		UpdateUnspendPoints();
	}

	public int SkillReset(SkillType skillType)
	{
		SkillBase skillByType = GetSkillByType(skillType);
		if (skillByType == null)
		{
			return 0;
		}
		int result = skillByType.ResetLevel();
		UpdateUnspendPoints();
		return result;
	}

	public void SkillResetAll()
	{
		foreach (KeyValuePair<SkillType, SkillBase> skill in skills)
		{
			skill.Value.ResetLevel();
		}
		UpdateUnspendPoints();
	}

	public bool IsSkillMaxLevel(SkillType skillType)
	{
		return GetSkillByType(skillType)?.IsLevelMax() ?? false;
	}

	public bool HasUnspendPoints()
	{
		return unspendPoints > 0;
	}

	public int GetSkillPointSpendOnCategory(SkillCategory category)
	{
		int num = 0;
		foreach (SkillSettings skillSetting in SkillConfig.skillSettings)
		{
			if (skillSetting.GetEnabled() && skillSetting.category == category)
			{
				num += GetSkillByType(skillSetting.skillType).GetLevel();
			}
		}
		return num;
	}

	private void Awake()
	{
		Instance = this;
	}

	private void Start()
	{
		InitSkills();
		LoadSkills();
		criticalHitVFX = PrefabManager.Instance.GetPrefab("CriticalHitEffect");
		criticalHitText = PrefabManager.Instance.GetPrefab("CritDamageText");
	}

	public void UpdateUnspendPoints()
	{
		if ((Object)(object)XPManager.Instance != (Object)null && skills != null)
		{
			RecalculateUnspendPoints();
			UIManager.Instance.remainingPoints.text = "Remaining points: " + unspendPoints;
			UIManager.Instance.UpdateCategoryPoints();
			SaveSkills();
			UpdateAllSkillInformation();
		}
	}

	public void RecalculateUnspendPoints()
	{
		int num = Mathf.FloorToInt((float)XPManager.Instance.GetPlayerLevel() * Main.pointsPerLevel.Value);
		foreach (KeyValuePair<SkillType, SkillBase> skill in skills)
		{
			num -= skill.Value.GetLevel();
		}
		unspendPoints = num;
	}

	private void LoadSkills()
	{
		foreach (KeyValuePair<SkillType, SkillBase> skill in skills)
		{
			string key = "LevelingSystem_" + skill.Key;
			if (Player.m_localPlayer.m_customData.ContainsKey(key) && int.TryParse(Player.m_localPlayer.m_customData[key], out var result))
			{
				skill.Value.SetLevel(result);
			}
		}
		UpdateUnspendPoints();
	}

	private void SaveSkills()
	{
		foreach (KeyValuePair<SkillType, SkillBase> skill in skills)
		{
			string key = "LevelingSystem_" + skill.Key;
			Player.m_localPlayer.m_customData[key] = skill.Value.GetLevel().ToString();
		}
	}

	public void DestroySelf()
	{
		SaveSkills();
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	public void ReloadAllSkills()
	{
		InitSkills();
		LoadSkills();
		UIManager.Instance.UpdateUI(instantUpdate: true);
	}
}
internal class PatchXP_Woodcutting : MonoBehaviour
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(TreeBase), "Damage")]
		private static void TreeBase_Damage_Prefix(TreeBase __instance, HitData hit, ZNetView ___m_nview)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier)
			{
				WoodcuttingXP(((Object)__instance).name, hit);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(TreeLog), "Damage")]
		private static void TreeLog_Damage_Prefix(TreeLog __instance, HitData hit, ZNetView ___m_nview)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier)
			{
				WoodcuttingXP(((Object)__instance).name, hit);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Destructible), "Damage")]
		private static void Destructible_Damage_Prefix(Destructible __instance, HitData hit, ZNetView ___m_nview, bool ___m_firstFrame)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && !(!___m_nview.IsValid() || ___m_firstFrame) && hit.m_toolTier >= __instance.m_minToolTier)
			{
				WoodcuttingXP(((Object)__instance).name, hit);
			}
		}

		private static void WoodcuttingXP(string name, HitData hit)
		{
			if (Main.woodcuttingXpEnabled.Value && !((Object)(object)hit.GetAttacker() == (Object)null))
			{
				Player component = ((Component)hit.GetAttacker()).GetComponent<Player>();
				if (!((Object)(object)component == (Object)null) && !(hit.m_damage.m_chop <= 0f) && !(hit.GetTotalDamage() <= 0f))
				{
					long playerID = component.GetPlayerID();
					XPManager.Instance.GetXPFromServer(playerID, name, "Woodcutting");
				}
			}
		}
	}
}
internal class PatchXP_Mining : MonoBehaviour
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(MineRock5), "Awake")]
		private static void MineRock5_Start_Prefix(MineRock5 __instance, ref object[] __state)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				__state = new object[1] { ((Object)__instance).name };
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MineRock5), "Awake")]
		private static void MineRock5_Start_Postfix(MineRock5 __instance, object[] __state)
		{
			if (!((Object)(object)__instance == (Object)null) && __state.Length != 0)
			{
				((Object)__instance).name = (string)__state[0];
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MineRock5), "Damage")]
		private static void MineRock5_Damage_Prefix(MineRock5 __instance, HitData hit, ZNetView ___m_nview)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier)
			{
				MiningXP(((Object)__instance).name, hit);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MineRock), "Damage")]
		private static void MineRock_Damage_Prefix(MineRock __instance, HitData hit, ZNetView ___m_nview)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier)
			{
				MiningXP(((Object)__instance).name, hit);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Destructible), "Damage")]
		private static void Destructible_Damage_Prefix(Destructible __instance, HitData hit, ZNetView ___m_nview, bool ___m_firstFrame)
		{
			if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && !(!___m_nview.IsValid() || ___m_firstFrame) && hit.m_toolTier >= __instance.m_minToolTier)
			{
				MiningXP(((Object)__instance).name, hit);
			}
		}

		private static void MiningXP(string name, HitData hit)
		{
			if (Main.miningXpEnabled.Value && !(hit.m_damage.m_pickaxe <= 0f) && !((Object)(object)hit.GetAttacker() == (Object)null))
			{
				Player component = ((Component)hit.GetAttacker()).GetComponent<Player>();
				if (!((Object)(object)component == (Object)null) && !(hit.GetTotalDamage() <= 0f))
				{
					long playerID = component.GetPlayerID();
					XPManager.Instance.GetXPFromServer(playerID, name, "Mining");
				}
			}
		}
	}
}
internal class PatchXP_Pickable : MonoBehaviour
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Beehive), "Interact")]
		private static void Beehive_Interact_Prefix(Beehive __instance, Humanoid character, ZNetView ___m_nview)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)character == (Object)null || (Object)(object)___m_nview == (Object)null || !Main.pickableXpEnabled.Value)
			{
				return;
			}
			int @int = ___m_nview.GetZDO().GetInt("level", 0);
			if (@int > 0)
			{
				Player component = ((Component)character).GetComponent<Player>();
				if (!((Object)(object)component == (Object)null))
				{
					long playerID = component.GetPlayerID();
					XPManager.Instance.GetXPFromServer(playerID, ((Object)__instance).name, "Pickable", @int);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Pickable), "RPC_SetPicked")]
		private static void Pickable_RPCSetPicked_Prefix(Pickable __instance, long sender, bool picked, bool ___m_picked)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			ZDOID zDOID;
			if (!((Object)(object)__instance == (Object)null))
			{
				zDOID = ((Character)localPlayer).GetZDOID();
				if (((ZDOID)(ref zDOID)).UserID == sender)
				{
					if (picked == ___m_picked || !picked)
					{
						ConsoleLog.Print("Already picked!", LogType.Error);
						return;
					}
					long playerID = localPlayer.GetPlayerID();
					XPManager.Instance.GetXPFromServer(playerID, ((Object)__instance).name, "Pickable");
					return;
				}
			}
			object arg = sender;
			zDOID = ((Character)Player.m_localPlayer).GetZDOID();
			ConsoleLog.Print($"Sender id ({arg}) doesn't match with nview uid ({((ZDOID)(ref zDOID)).UserID})", LogType.Error);
		}
	}
}
[HarmonyPatch]
internal class XPBarFade_Patch
{
	[HarmonyPrefix]
	[HarmonyPatch(typeof(Hud), "UpdateBlackScreen")]
	private static void Player_SetSleeping_Prefix(Player player)
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		float fadeTime = 1f;
		if ((Object)(object)player != (Object)null)
		{
			if (((Character)player).IsDead())
			{
				fadeTime = 9.5f;
			}
			if (player.IsSleeping())
			{
				fadeTime = 3f;
			}
		}
		if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ((Character)player).IsTeleporting() || Game.instance.IsShuttingDown() || player.IsSleeping())
		{
			if ((Object)(object)UIManager.Instance == (Object)null)
			{
				ConsoleLog.Print("UIManager is missing! Can't fade out XPBar", LogType.Error);
			}
			else
			{
				UIManager.Instance.FadeOutXPBar(fadeTime);
			}
		}
		else if ((Object)(object)UIManager.Instance == (Object)null)
		{
			ConsoleLog.Print("UIManager is missing! Can't fade out XPBar", LogType.Error);
		}
		else
		{
			UIManager.Instance.FadeInXPBar(fadeTime);
		}
	}
}
public class XPText : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <Start>d__7 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public XPText <>4__this;

		private CanvasGroup <canvasGroup>5__2;

		private float <startSize>5__3;

		private Vector3 <startPosition>5__4;

		private Vector3 <deltaPosition>5__5;

		private float <fullAnimTime>5__6;

		private float <f>5__7;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)
			//IL_008b: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			XPText xPText = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				Transform transform = ((Component)xPText).transform;
				transform.localScale *= Main.xpFontSize.Value / 100f;
				<canvasGroup>5__2 = ((Component)xPText).GetComponentInChildren<CanvasGroup>();
				<startSize>5__3 = ((Component)xPText).transform.localScale.x;
				<startPosition>5__4 = ((Component)xPText).transform.position;
				<deltaPosition>5__5 = Vector3.up * xPText.moveDistance;
				<fullAnimTime>5__6 = xPText.fadeInTime + xPText.visibleTime + xPText.fadeOutTime;
				<f>5__7 = 0f;
				break;
			}
			case 1:
				<>1__state = -1;
				<f>5__7 += Time.deltaTime;
				break;
			}
			if (<f>5__7 < <fullAnimTime>5__6)
			{
				float num2 = <f>5__7 / <fullAnimTime>5__6;
				((Component)xPText).transform.position = <startPosition>5__4 + <deltaPosition>5__5 * num2;
				<canvasGroup>5__2.alpha = 1f;
				((Component)xPText).transform.localScale = Vector3.one * <startSize>5__3;
				if (<f>5__7 < xPText.fadeInTime)
				{
					<canvasGroup>5__2.alpha = <f>5__7 / xPText.fadeInTime;
					((Component)xPText).transform.localScale = <f>5__7 / xPText.fadeInTime * Vector3.one * <startSize>5__3;
				}
				float num3 = xPText.fadeInTime + xPText.visibleTime;
				if (<f>5__7 > num3)
				{
					float num4 = <fullAnimTime>5__6 - num3;
					<canvasGroup>5__2.alpha = 1f - (<f>5__7 - num3) / num4;
					((Component)xPText).transform.localScale = (1f - (<f>5__7 - num3) / num4) * Vector3.one * <startSize>5__3;
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			Object.Destroy((Object)(object)((Component)xPText).gameObject);
			return false;
		}

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

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

	public int xpGained;

	private float fadeInTime = 0.5f;

	private float visibleTime = 1.5f;

	private float fadeOutTime = 1f;

	private float moveDistance = 0.5f;

	public void XPGained(int xp)
	{
		((Component)this).GetComponentInChildren<Text>().text = "+" + xp + " xp";
	}

	private void Update()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.eulerAngles = ((Component)Camera.main).transform.eulerAngles;
	}

	[IteratorStateMachine(typeof(<Start>d__7))]
	private IEnumerator Start()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Start>d__7(0)
		{
			<>4__this = this
		};
	}
}
internal class ChatCommands : MonoBehaviour
{
	[HarmonyPatch]
	private class PatchClass
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Chat), "SendText")]
		private static bool Chat_SendText_Prefix(string text)
		{
			string[] array = text.Split(new char[1] { ' ' });
			if (array.Length >= 2 && array[0].ToLower().Equals("-" + "LevelingSystem".ToLower()))
			{
				string value = array[1].ToLower();
				foreach (KeyValuePair<string, Action> command in commands)
				{
					if (command.Key.ToLower().Equals(value))
					{
						chatArgs = array.ToList();
						chatArgs.RemoveAt(0);
						chatArgs.RemoveAt(0);
						command.Value();
						return false;
					}
				}
			}
			return true;
		}
	}

	private static List<string> chatArgs = new List<string>();

	private static Dictionary<string, Action> commands = new Dictionary<string, Action> { { "Reload", Reload } };

	private static void Reload()
	{
		ConsoleLog.ReloadConfig();
	}
}
internal class XPTable
{
	public enum XPTableType
	{
		Monster,
		Pickable,
		Mining,
		Woodcutting,
		Player
	}

	public static Dictionary<string, string> miningXPMappingTable = new Dictionary<string, string>
	{
		{ "rock4_coast", "Stone" },
		{ "rock4_coast_frac", "Stone" },
		{ "HeathRockPillar", "Stone" },
		{ "HeathRockPillar_frac", "Stone" },
		{ "highstone", "Stone" },
		{ "highstone_frac", "Stone" },
		{ "Rock_3", "Stone" },
		{ "Rock_3_frac", "Stone" },
		{ "Rock_4", "Stone" },
		{ "Rock_4_frac", "Stone" },
		{ "rock2_heath", "Stone" },
		{ "rock2_heath_frac", "Stone" },
		{ "rock4_forest_", "Stone" },
		{ "rock4_forest_frac", "Stone" },
		{ "rock4_heath", "Stone" },
		{ "rock4_heath_frac", "Stone" },
		{ "RockFinger", "Stone" },
		{ "RockFinger_frac", "Stone" },
		{ "RockFingerBroken", "Stone" },
		{ "RockFingerBroken_frac", "Stone" },
		{ "RockThumb", "Stone" },
		{ "RockThumb_frac", "Stone" },
		{ "widestone", "Stone" },
		{ "widestone_frac", "Stone" },
		{ "rock1_mountain", "Stone" },
		{ "rock1_mountain_frac", "Stone" },
		{ "rock2_mountain", "Stone" },
		{ "rock2_mountain_frac", "Stone" },
		{ "rock3_mountain_", "Stone" },
		{ "rock3_mountain_frac", "Stone" },
		{ "tarlump1", "Stone" },
		{ "tarlump1_frac", "Stone" },
		{ "rock_mistlands1", "Stone" },
		{ "rock_mistlands1_frac", "Stone" },
		{ "cliff_mistlands1_creep", "Stone" },
		{ "cliff_mistlands1_creep_frac", "Stone" },
		{ "cliff_mistlands1", "Stone" },
		{ "cliff_mistlands1_frac", "Stone" },
		{ "MineRock_Stone", "Stone" },
		{ "MineRock_Tin", "Tin" },
		{ "MineRock_Copper", "Copper" },
		{ "rock4_copper", "Copper" },
		{ "rock4_copper_frac", "Copper" },
		{ "MineRock_Iron", "Iron" },
		{ "mudpile_old", "Iron" },
		{ "mudpile", "Iron" },
		{ "mudpile_frac", "Iron" },
		{ "mudpile2", "Iron" },
		{ "mudpile2_frac", "Iron" },
		{ "giant_helmet1", "Iron" },
		{ "giant_helmet1_destruction", "Iron" },
		{ "giant_helmet2", "Iron" },
		{ "giant_helmet2_destruction", "Iron" },
		{ "giant_sword1", "Iron" },
		{ "giant_sword1_destruction", "Iron" },
		{ "giant_sword2", "Iron" },
		{ "giant_sword2_destruction", "Iron" },
		{ "MineRock_Obsidian", "Obsidian" },
		{ "Leviathan", "Chitin" },
		{ "rock3_silver", "Silver" },
		{ "rock3_silver_frac", "Silver" },
		{ "silvervein", "Silver" },
		{ "silvervein_frac", "Silver" },
		{ "MineRock_Meteorite", "Flametal" },
		{ "giant_brain", "SoftTissue" },
		{ "giant_brain_frac", "SoftTissue" },
		{ "giant_ribs", "BlackMarble" },
		{ "giant_ribs_frac", "BlackMarble" },
		{ "giant_skull", "BlackMarble" },
		{ "giant_skull_frac", "BlackMarble" }
	};

	public static Dictionary<string, string> woodcuttingXPMappingTable = new Dictionary<string, string>
	{
		{ "beech_log", "Beech" },
		{ "beech_log_half", "Beech" },
		{ "Beech_Stub", "Beech" },
		{ "Beech1", "Beech" },
		{ "FirTree_log", "Fir" },
		{ "FirTree_log_half", "Fir" },
		{ "FirTree", "Fir" },
		{ "FirTree_Stub", "Fir" },
		{ "PineTree_log", "Pine" },
		{ "PineTree_log_half", "Pine" },
		{ "PineTree_log_halfOLD", "Pine" },
		{ "PineTree_logOLD", "Pine" },
		{ "PineTree", "Pine" },
		{ "Pinetree_01", "Pine" },
		{ "Pinetree_01_Stub", "Pine" },
		{ "Birch_log", "Birch" },
		{ "Birch_log_half", "Birch" },
		{ "Birch1", "Birch" },
		{ "Birch1_aut", "Birch" },
		{ "Birch2", "Birch" },
		{ "Birch2_aut", "Birch" },
		{ "BirchStub", "Birch" },
		{ "Oak_log", "Oak" },
		{ "Oak_log_half", "Oak" },
		{ "Oak1", "Oak" },
		{ "OakStub", "Oak" },
		{ "SwampTree1_log", "Ancient" },
		{ "SwampTree1", "Ancient" },
		{ "SwampTree1_Stub", "Ancient" },
		{ "yggashoot_log", "Yggdrasil" },
		{ "yggashoot_log_half", "Yggdrasil" },
		{ "YggaShoot1", "Yggdrasil" },
		{ "YggaShoot2", "Yggdrasil" },
		{ "YggaShoot3", "Yggdrasil" }
	};

	public static Dictionary<string, int> miningXPTable = new Dictionary<string, int>
	{
		{ "Stone", 3 },
		{ "Copper", 6 },
		{ "Tin", 6 },
		{ "Iron", 9 },
		{ "Obsidian", 12 },
		{ "Chitin", 12 },
		{ "Silver", 15 },
		{ "Flametal", 15 },
		{ "BlackMarble", 18 },
		{ "SoftTissue", 18 }
	};

	public static Dictionary<string, int> woodcuttingXPTable = new Dictionary<string, int>
	{
		{ "Beech", 6 },
		{ "Fir", 12 },
		{ "Pine", 18 },
		{ "Birch", 24 },
		{ "Ancient", 30 },
		{ "Oak", 40 },
		{ "Yggdrasil", 100 }
	};

	public static Dictionary<string, int> pickableXPTable = new Dictionary<string, int>
	{
		{ "Pickable_Branch", 2 },
		{ "Pickable_Stone", 2 },
		{ "Pickable_Dandelion", 2 },
		{ "Pickable_Mushroom", 2 },
		{ "RaspberryBush", 3 },
		{ "BlueberryBush", 6 },
		{ "Pickable_Carrot", 4 },
		{ "Pickable_SeedCarrot", 4 },
		{ "Pickable_Flint", 4 },
		{ "Pickable_ForestCryptRemains01", 8 },
		{ "Pickable_ForestCryptRemains02", 8 },
		{ "Pickable_ForestCryptRemains03", 8 },
		{ "Pickable_ForestCryptRemains04", 8 },
		{ "Pickable_ForestCryptRandom", 8 },
		{ "Pickable_Mushroom_yellow", 4 },
		{ "Pickable_Thistle", 4 },
		{ "Pickable_Tin", 4 },
		{ "Pickable_SurtlingCoreStand", 30 },
		{ "Pickable_BogIronOre", 6 },
		{ "Pickable_Turnip", 6 },
		{ "Pickable_SeedTurnip", 6 },
		{ "Pickable_SunkenCryptRandom", 12 },
		{ "Pickable_Obsidian", 8 },
		{ "Pickable_Onion", 8 },
		{ "Pickable_SeedOnion", 8 },
		{ "hanging_hairstrands", 16 },
		{ "Pickable_Hairstrands01", 16 },
		{ "Pickable_Hairstrands02", 16 },
		{ "Pickable_MeatPile", 16 },
		{ "Pickable_MountainCaveCrystal", 16 },
		{ "Pickable_MountainCaveObsidian", 16 },
		{ "Pickable_MountainCaveRandom", 16 },
		{ "Pickable_MountainRemains01_buried", 16 },
		{ "Pickable_DragonEgg", 1200 },
		{ "CloudberryBush", 10 },
		{ "Pickable_Barley", 10 },
		{ "Pickable_Barley_Wild", 10 },
		{ "Pickable_Flax", 10 },
		{ "Pickable_Flax_Wild", 10 },
		{ "Pickable_Tar", 10 },
		{ "Pickable_TarBig", 20 },
		{ "goblin_totempole", 3000 },
		{ "Pickable_Mushroom_JotunPuffs", 12 },
		{ "Pickable_Mushroom_Magecap", 12 },
		{ "Pickable_RoyalJelly", 12 },
		{ "Pickable_DvergrMineTreasure", 24 },
		{ "Pickable_BlackCoreStand", 6000 },
		{ "Pickable_Item", 10 },
		{ "Pickable_DolmenTreasure", 10 },
		{ "Pickable_Meteorite", 10 },
		{ "LuredWisp", 100 },
		{ "piece_beehive", 10 }
	};

	public static Dictionary<string, int> monsterXPTable = new Dictionary<string, int>
	{
		{ "Deer", 5 },
		{ "Neck", 5 },
		{ "Boar", 8 },
		{ "Greyling", 8 },
		{ "Eikthyr", 96 },
		{ "Greydwarf", 22 },
		{ "Skeleton", 30 },
		{ "Ghost", 36 },
		{ "Greydwarf_Shaman", 40 },
		{ "Skeleton_Poison", 53 },
		{ "Greydwarf_Elite", 69 },
		{ "Troll", 243 },
		{ "gd_king", 833 },
		{ "Surtling", 85 },
		{ "Blob", 99 },
		{ "Leech", 120 },
		{ "Draugr", 139 },
		{ "Wraith", 156 },
		{ "BlobElite", 187 },
		{ "Draugr_Elite", 224 },
		{ "Abomination", 783 },
		{ "Bonemass", 2685 },
		{ "Bat", 109 },
		{ "Ulv", 457 },
		{ "Wolf", 479 },
		{ "Hatchling", 609 },
		{ "Cultist", 762 },
		{ "Fenring", 1067 },
		{ "Serpent", 3200 },
		{ "StoneGolem", 1600 },
		{ "Dragon", 12800 },
		{ "Deathsquito", 620 },
		{ "BlobTar", 782 },
		{ "GoblinShaman", 980 },
		{ "Goblin", 1126 },
		{ "GoblinBrute", 1904 },
		{ "Lox", 2264 },
		{ "GoblinKing", 24693 },
		{ "Hare", 34 },
		{ "SeekerBrood", 483 },
		{ "Tick", 504 },
		{ "DvergerMageSupport", 1207 },
		{ "Seeker", 1517 },
		{ "DvergerMageFire", 1897 },
		{ "Dverger", 1966 },
		{ "DvergerMage", 1966 },
		{ "DvergerMageIce", 2586 },
		{ "SeekerBrute", 6001 },
		{ "Gjall", 18002 },
		{ "SeekerQueen", 72008 },
		{ "FallenValkyrie", 7500 },
		{ "Charred_Melee", 1750 },
		{ "Charred_Archer", 1250 },
		{ "Charred_Mage", 1500 },
		{ "Charred_Twitcher", 650 },
		{ "Charred_Melee_Fader", 1250 },
		{ "Morgen", 8000 },
		{ "BonemawSerpent", 5500 },
		{ "Asksvin", 2500 },
		{ "Volture", 1250 },
		{ "BlobLava", 2500 },
		{ "DvergerAshlands", 1750 },
		{ "Charred_Melee_Dyrnwyn", 27450 },
		{ "Fader", 100000 }
	};

	public static int[] playerXPTable;

	public static void GenerateDefaultPlayerXPTable()
	{
		int num = 90;
		float num2 = 80f;
		float num3 = 80f;
		float num4 = 0.09f;
		float num5 = 0.00033f;
		int num6 = 0;
		List<int> list = new List<int>();
		for (int i = 1; i <= num; i++)
		{
			int num7 = (int)(num2 + num3 * (float)(i - 1));
			num2 *= 1f + num4;
			num4 += num5;
			list.Add(num7);
			num6 += num7;
			_ = i % 10;
		}
		playerXPTable = list.ToArray();
	}

	public static void UpdatePickableXPTable()
	{
		ConsoleLog.Print("Level System: Creating Pickable XP Table", LogType.Message);
		string text = "PickableXP";
		string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json");
		Array.Sort(files);
		CreateListsFromJSON(files, XPTableType.Pickable);
	}

	public static void UpdateWoodcuttingXPTable()
	{
		ConsoleLog.Print("Level System: Creating Woodcutting XP Table", LogType.Message);
		string text = "WoodcuttingXP";
		string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json");
		Array.Sort(files);
		CreateListsFromJSON(files, XPTableType.Woodcutting);
	}

	public static void UpdateMiningXPTable()
	{
		ConsoleLog.Print("Level System: Creating Mining XP Table", LogType.Message);
		string text = "MiningXP";
		string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json");
		Array.Sort(files);
		CreateListsFromJSON(files, XPTableType.Mining);
	}

	public static void UpdateMonsterXPTable()
	{
		ConsoleLog.Print("Level System: Creating Monster XP Table", LogType.Message);
		string text = "MonsterXP";
		string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json");
		Array.Sort(files);
		CreateListsFromJSON(files, XPTableType.Monster);
	}

	public static void UpdatePlayerXPTable()
	{
		ConsoleLog.Print("Level System: Creating Player XP Table", LogType.Message);
		string text = "PlayerXP";
		string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json");
		Array.Sort(files);
		int[] array = Array.Empty<int>();
		string[] array2 = files;
		foreach (string path in array2)
		{
			string text2 = File.ReadAllText(path);
			Dictionary<string, int> dictionary;
			try
			{
				dictionary = SimpleJson.DeserializeObject<Dictionary<string, int>>(text2);
			}
			catch (Exception ex)
			{
				ConsoleLog.Print("Could not read player xp table file: '" + Path.GetFileName(path) + "'. Please make sure the json is valid and doesn't contain comments\n\nError Message: '" + ex.Message + "'", LogType.Warning);
				continue;
			}
			array = dictionary.Values.ToArray();
			ConsoleLog.Print("Reading file: " + Path.GetFileName(path) + " (" + dictionary.Count + " values)", LogType.Message);
			if (array.Length != 0)
			{
				break;
			}
		}
		if (array.Length == 0)
		{
			throw new IOException("Could not find a valid player xp table. Please check for any errors further up, that might've occurred during the loading of the xp tables.");
		}
		playerXPTable = array.ToArray();
	}

	public static int GetMonsterXP(string name)
	{
		name = name.Replace("(Clone)", "");
		ConsoleLog.Print("Monster XP Table -> Looking for " + name + " -> Found: " + monsterXPTable.ContainsKey(name));
		if (!monsterXPTable.ContainsKey(name))
		{
			return 0;
		}
		return monsterXPTable[name];
	}

	public static int GetPickableXP(string name)
	{
		name = name.Replace("(Clone)", "");
		if (!pickableXPTable.ContainsKey(name))
		{
			return 0;
		}
		return pickableXPTable[name];
	}

	public static int GetMiningXP(string name)
	{
		name = name.Replace("(Clone)", "");
		string text = (miningXPMappingTable.ContainsKey(name) ? miningXPMappingTable[name] : "");
		if (string.IsNullOrEmpty(text))
		{
			if (!miningXPTable.ContainsKey(name))
			{
				return 0;
			}
			return miningXPTable[name];
		}
		if (!miningXPTable.ContainsKey(text))
		{
			return 0;
		}
		return miningXPTable[text];
	}

	public static int GetWoodcuttingXP(string name)
	{
		name = name.Replace("(Clone)", "");
		string key = (woodcuttingXPMappingTable.ContainsKey(name) ? woodcuttingXPMappingTable[name] : "");
		if (!woodcuttingXPTable.ContainsKey(key))
		{
			return 0;
		}
		return woodcuttingXPTable[key];
	}

	private static void CreateListsFromJSON(string[] jsonFiles, XPTableType xpTableType)
	{
		switch (xpTableType)
		{
		case XPTableType.Monster:
			monsterXPTable.Clear();
			break;
		case XPTableType.Pickable:
			pickableXPTable.Clear();
			break;
		case XPTableType.Woodcutting:
			woodcuttingXPTable.Clear();
			break;
		case XPTableType.Mining:
			miningXPTable.Clear();
			break;
		}
		foreach (string path in jsonFiles)
		{
			string text = File.ReadAllText(path);
			Dictionary<string, int> dictionary;
			try
			{
				dictionary = SimpleJson.DeserializeObject<Dictionary<string, int>>(text);
			}
			catch (Exception ex)
			{
				ConsoleLog.Print("Could not read xp table file: '" + Path.GetFileName(path) + "'. Please make sure the json is valid and doesn't contain comments\n\nError Message: '" + ex.Message + "'", LogType.Warning);
				continue;
			}
			ConsoleLog.Print("Reading file: " + Path.GetFileName(path) + " (" + dictionary.Count + " values)", LogType.Message);
			Extensions.AddRange<string, int>(xpTableType switch
			{
				XPTableType.Monster => monsterXPTable, 
				XPTableType.Pickable => pickableXPTable, 
				XPTableType.Woodcutting => woodcuttingXPTable, 
				XPTableType.Mining => miningXPTable, 
				_ => new Dictionary<string, int>(), 
			}, dictionary);
		}
		switch (xpTableType)
		{
		case XPTableType.Monster:
			ValidateXpTable("Monster", monsterXPTable);
			break;
		case XPTableType.Pickable:
			ValidateXpTable("Pickable", pickableXPTable);
			break;
		case XPTableType.Woodcutting:
			ValidateXpTable("Woodcutting", woodcuttingXPTable);
			break;
		case XPTableType.Mining:
			ValidateXpTable("Mining", miningXPTable);
			break;
		}
		static void ValidateXpTable(string name, IReadOnlyDictionary<string, int> xpTable)
		{
			if (xpTable.Count > 0)
			{
				return;
			}
			throw new IOException("No xp table was found for '" + name + "'. Please make sure that you have at least one valid .json file that represents an xp table for '" + name + "'.");
		}
	}
}
internal class MonsterXP
{
	public uint monsterID;

	public List<PlayerDamage> playerDamages;

	public MonsterXP(uint monsterID)
	{
		this.monsterID = monsterID;
		playerDamages = new List<PlayerDamage>();
	}

	public void AddDamage(long playerID, float damage, string playerName = "")
	{
		foreach (PlayerDamage playerDamage in playerDamages)
		{
			if (playerDamage.playerID == playerID)
			{
				playerDamage.playerTotalDamage += damage;
				return;
			}
		}
		playerDamages.Add(new PlayerDamage
		{
			playerID = playerID,
			playerTotalDamage = damage,
			playerName = playerName
		});
	}

	public float GetTotalDamageDealt()
	{
		float num = 0f;
		foreach (PlayerDamage playerDamage in playerDamages)
		{
			num += playerDamage.playerTotalDamage;
		}
		return num;
	}
}
internal class PlayerDamage
{
	public string playerName;

	public long playerID;

	public float playerTotalDamage;
}
internal class XPManager : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <RPC_AddMonsterDamage>d__10 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public ZPackage package;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				if (!ZNet.instance.IsServer())
				{
					ConsoleLog.Print("Expected server instance but got a non-server instance. Rejecting RPC", LogType.Error);
					return false;
				}
				uint monsterID = package.ReadUInt();
				long playerID = package.ReadLong();
				float damage = package.ReadSingle();
				string playerName = package.ReadString();
				MonsterXP monsterXP = Instance.GetMonsterXP(monsterID);
				if (monsterXP != null)
				{
					ConsoleLog.Print("Updated monster damage (Server)");
					monsterXP.AddDamage(playerID, damage, playerName);
				}
				else
				{
					ConsoleLog.Print("Created new monster damage (Server)");
					Instance.CreateNewMonsterXP(monsterID).AddDamage(playerID, damage, playerName);
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			case 1:
				<>1__state = -1;
				return false;
			}
		}

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

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

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

		private object <>2__current;

		public ZPackage package;

		public long sender;

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

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

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

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

		private bool MoveNext()
		{
			if (<>1__state != 0)
			{
				return false;
			}
			<>1__state = -1;
			if (!ZNet.instance.IsServer())
			{
				ConsoleLog.Print("Expected server instance but got a non-server instance. Rejecting RPC", LogType.Error);
				return false;
			}
			long playerId = package.ReadLong();
			string text = package.ReadString();
			string text2 = package.ReadString();
			int num = package.ReadInt();
			ConsoleLog.Print("Server: Recieved GetXP Call (" + text + " - " + text2 + " - " + num + ")");
			int num2;
			switch (text2)
			{
			case "Woodcutting":
				num2 = XPTable.GetWoodcuttingXP(text);
				break;
			case "Mining":
				num2 = XPTable.GetMiningXP(text);
				break;
			case "Pickable":
				num2 = XPTable.GetPickableXP(text);
				break;
			default:
				return false;
			}
			if (num2 <= 0)
			{
				return false;
			}
			ConsoleLog.Print("Server: Found XP = " + num2);
			RewardXP(sender, playerId, num2 * num, text2);
			return false;
		}

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

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

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

		private object <>2__current;

		public ZPackage package;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			if (<>1__state != 0)
			{
				return false;
			}
			<>1__state = -1;
			if (!ZNet.instance.IsServer())
			{
				return false;
			}
			uint monsterID = package.ReadUInt();
			uint num = package.ReadUInt();
			string text = package.ReadString();
			ConsoleLog.Print("Monster died (Server) - " + text);
			MonsterXP monsterXP = Instance.GetMonsterXP(monsterID);
			if (monsterXP != null)
			{
				float totalDamageDealt = monsterXP.GetTotalDamageDealt();
				float num2 = 0f;
				float num3 = 0f;
				float num4 = 0f;
				float num5 = 0f;
				float num6 = 0f;
				float num7 = 0f;
				bool flag = package.ReadBool();
				if (flag)
				{
					num2 = package.ReadSingle();
					num3 = package.ReadSingle();
					num4 = package.ReadSingle();
					num5 = package.ReadSingle();
					num6 = package.ReadSingle();
					num7 = package.ReadSingle();
				}
				foreach (PlayerDamage playerDamage in monsterXP.playerDamages)
				{
					ZPackage val = new ZPackage();
					float num8 = playerDamage.playerTotalDamage / totalDamageDealt;
					float num9 = Mathf.Min(1f - Main.baseXpSpreadMin.Value / 100f, 1f);
					float num10 = Mathf.Max(1f + Main.baseXpSpreadMax.Value / 100f, 1f);
					float num11 = Mathf.Max(0f, Main.monsterLvlXPMultiplier.Value / 100f);
					float num12 = Mathf.Max(0f, Main.allXPMultiplier.Value / 100f);
					float num13 = Mathf.Max(0f, Main.restedXPMultiplier.Value / 100f);
					float num14 = (float)XPTable.GetMonsterXP(text) * num8 * Random.Range(num9, num10) * num12;
					if (flag && Main.modDifficultyScalerLoaded && Main.enableDifficultyScalerXP.Value)
					{
						float num15 = num2 * Main.difficultyScalerOverallHealthRatio.Value;
						float num16 = num3 * Main.difficultyScalerOverallDamageRatio.Value;
						float num17 = num4 * Main.difficultyScalerBiomeRatio.Value;
						float num18 = num5 * Main.difficultyScalerBossRatio.Value;
						float num19 = num6 * Main.difficultyScalerBossRatio.Value;
						float num20 = num7 * Main.difficultyScalerStarRatio.Value;
						float num21 = 0f;
						ConsoleLog.Print("XP before scaling: " + num14);
						if (Main.difficultyScalerOverallHealth.Value)
						{
							num21 += num15;
						}
						if (Main.difficultyScalerOverallDamage.Value)
						{
							num21 += num16;
						}
						if (Main.difficultyScalerBiome.Value)
						{
							num21 += num17;
						}
						if (Main.difficultyScalerNight.Value)
						{
							num21 += num18;
						}
						if (Main.difficultyScalerBo