Decompiled source of JGRPG v0.1.61

BepInEx/plugins/JGRPG.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("JGRPG")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JGRPG")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.1.61")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.61.0")]
namespace JGRPG;

internal static class AbilityBuffStatusEffects
{
	private static bool _registered;

	private static StatusEffect _huntersMark;

	private static StatusEffect _explosiveShot;

	private static StatusEffect _rangersRally;

	private static StatusEffect _ullrsQuiver;

	private static StatusEffect _rage;

	private static StatusEffect _fury;

	private static StatusEffect _vorpal;

	private static StatusEffect _thorsHammer;

	private static StatusEffect _fortify;

	private static StatusEffect _guardiansRally;

	private static StatusEffect _retaliation;

	public static void Register()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
		if (!_registered)
		{
			_registered = true;
			_huntersMark = CreateStatusEffect("JGRPG_HuntersMarkDisplay", "Hunter's Mark", new Color(0.65f, 0.2f, 0.2f, 1f));
			_explosiveShot = CreateStatusEffect("JGRPG_ExplosiveShotDisplay", "Explosive Shot", new Color(0.85f, 0.4f, 0.12f, 1f));
			_rangersRally = CreateStatusEffect("JGRPG_RangersRallyDisplay", "Ranger's Rally", new Color(0.2f, 0.6f, 0.25f, 1f));
			_ullrsQuiver = CreateStatusEffect("JGRPG_UllrsQuiverDisplay", "Ullr's Quiver", new Color(0.2f, 0.45f, 0.75f, 1f));
			_rage = CreateStatusEffect("JGRPG_RageDisplay", "Rage", new Color(0.75f, 0.12f, 0.08f, 1f));
			_fury = CreateStatusEffect("JGRPG_FuryDisplay", "Fury", new Color(0.85f, 0.3f, 0.08f, 1f));
			_vorpal = CreateStatusEffect("JGRPG_VorpalDisplay", "Vorpal", new Color(0.55f, 0.1f, 0.65f, 1f));
			_thorsHammer = CreateStatusEffect("JGRPG_ThorsHammerDisplay", "Thor's Hammer", new Color(0.25f, 0.55f, 0.9f, 1f));
			_fortify = CreateStatusEffect("JGRPG_FortifyDisplay", "Fortify", new Color(0.3f, 0.45f, 0.65f, 1f));
			_guardiansRally = CreateStatusEffect("JGRPG_GuardiansRallyDisplay", "Guardian's Rally", new Color(0.45f, 0.6f, 0.8f, 1f));
			_retaliation = CreateStatusEffect("JGRPG_RetaliationDisplay", "Retaliation", new Color(0.7f, 0.25f, 0.2f, 1f));
			RegisterEffect(_huntersMark);
			RegisterEffect(_explosiveShot);
			RegisterEffect(_rangersRally);
			RegisterEffect(_ullrsQuiver);
			RegisterEffect(_rage);
			RegisterEffect(_fury);
			RegisterEffect(_vorpal);
			RegisterEffect(_thorsHammer);
			RegisterEffect(_fortify);
			RegisterEffect(_guardiansRally);
			RegisterEffect(_retaliation);
		}
	}

	public static void ShowHuntersMark(float duration)
	{
		ShowOnLocalPlayer(_huntersMark, duration);
	}

	public static void ShowExplosiveShot(float duration)
	{
		ShowOnLocalPlayer(_explosiveShot, duration);
	}

	public static void ShowUllrsQuiver(float duration)
	{
		ShowOnLocalPlayer(_ullrsQuiver, duration);
	}

	public static void ShowRage(float duration)
	{
		ShowOnLocalPlayer(_rage, duration);
	}

	public static void ShowFury(float duration)
	{
		ShowOnLocalPlayer(_fury, duration);
	}

	public static void ShowVorpal(float duration)
	{
		ShowOnLocalPlayer(_vorpal, duration);
	}

	public static void ShowThorsHammer(float duration)
	{
		ShowOnLocalPlayer(_thorsHammer, duration);
	}

	public static void ShowFortify(float duration)
	{
		ShowOnLocalPlayer(_fortify, duration);
	}

	public static void ShowRetaliation(float duration)
	{
		ShowOnLocalPlayer(_retaliation, duration);
	}

	public static void ShowGuardiansRally(float duration, float radius)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		List<Player> list = new List<Player>();
		Player.GetPlayersInRange(((Component)localPlayer).transform.position, radius, list);
		foreach (Player item in list)
		{
			if (TankGuardianRally.Affects(item))
			{
				ShowOnPlayer(item, _guardiansRally, duration);
			}
		}
	}

	public static void ShowForActivatedAbility(int slot)
	{
		if (CharacterProgression.Class == CharacterClass.Tank)
		{
			switch (slot)
			{
			case 2:
				ShowFortify(TankAbilities.GetFortifyDuration());
				break;
			case 4:
				ShowGuardiansRally(TankGuardianRally.GetDuration(), TankGuardianRally.GetRadius());
				break;
			case 1:
			case 3:
			case 5:
				break;
			}
		}
		else if (CharacterProgression.Class == CharacterClass.Berserker)
		{
			switch (slot)
			{
			case 1:
				ShowRage(BerserkerAbilities.GetRageDuration());
				break;
			case 3:
				ShowFury(BerserkerAbilities.GetFuryDuration());
				break;
			case 4:
				ShowVorpal(BerserkerAbilities.GetVorpalDuration());
				break;
			case 5:
				ShowThorsHammer(BerserkerAbilities.GetThorsHammerDuration());
				break;
			case 2:
				break;
			}
		}
		else if (CharacterProgression.Class == CharacterClass.Ranger)
		{
			switch (slot)
			{
			case 1:
				ShowHuntersMark(10f);
				break;
			case 2:
				ShowExplosiveShot(10f);
				break;
			case 4:
				ShowRangersRally(10f + (float)CharacterProgression.GetTalentRank("Ranger_ExtendedRally"), 20f);
				break;
			case 5:
				ShowUllrsQuiver(10f);
				break;
			case 3:
				break;
			}
		}
	}

	public static void ShowRangersRally(float duration, float radius)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		List<Player> list = new List<Player>();
		Player.GetPlayersInRange(((Component)localPlayer).transform.position, radius, list);
		foreach (Player item in list)
		{
			ShowOnPlayer(item, _rangersRally, duration);
		}
	}

	private static void ShowOnLocalPlayer(StatusEffect effect, float duration)
	{
		ShowOnPlayer(Player.m_localPlayer, effect, duration);
	}

	private static void ShowOnPlayer(Player player, StatusEffect effect, float duration)
	{
		if (!((Object)(object)player == (Object)null) && !((Object)(object)effect == (Object)null) && !(duration <= 0f))
		{
			StatusEffect val = ((Character)player).GetSEMan().AddStatusEffect(effect, true, 0, 0f, (short)(-1));
			if (!((Object)(object)val == (Object)null))
			{
				val.m_ttl = duration;
				val.ResetTime();
			}
		}
	}

	private static void RegisterEffect(StatusEffect effect)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(effect, false));
	}

	private static StatusEffect CreateStatusEffect(string internalName, string displayName, Color iconColor)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		StatusEffect obj = ScriptableObject.CreateInstance<StatusEffect>();
		((Object)obj).name = internalName;
		obj.m_name = displayName;
		obj.m_icon = CreateIcon(iconColor);
		obj.m_ttl = 10f;
		return obj;
	}

	private static Sprite CreateIcon(Color fillColor)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
		((Object)val).name = "JGRPG_AbilityStatusIcon";
		((Texture)val).filterMode = (FilterMode)0;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(0.05f, 0.05f, 0.05f, 1f);
		for (int i = 0; i < 32; i++)
		{
			for (int j = 0; j < 32; j++)
			{
				bool flag = j < 3 || i < 3 || j >= 29 || i >= 29;
				val.SetPixel(j, i, flag ? val2 : fillColor);
			}
		}
		val.Apply();
		return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f);
	}
}
[HarmonyPatch(typeof(ClassAbilityCooldowns), "StartCooldown")]
internal static class AbilityDisplayCooldownPatch
{
	[HarmonyPostfix]
	private static void Postfix(object[] __args)
	{
		if (__args != null && __args.Length >= 1 && __args[0] != null)
		{
			int slot;
			try
			{
				slot = Convert.ToInt32(__args[0]);
			}
			catch
			{
				return;
			}
			AbilityBuffStatusEffects.ShowForActivatedAbility(slot);
			AbilityHUD.Refresh();
		}
	}
}
[HarmonyPatch(typeof(ClassAbilityManager), "TryActivate")]
internal static class ClassAbilityUnlockPatch
{
	[HarmonyPrefix]
	private static bool Prefix(object[] __args)
	{
		if (__args == null || __args.Length < 1 || __args[0] == null)
		{
			return true;
		}
		if (CharacterProgression.Class == CharacterClass.None)
		{
			return true;
		}
		int slot;
		try
		{
			slot = Convert.ToInt32(__args[0]);
		}
		catch
		{
			return true;
		}
		return ClassAbilityUnlocks.IsUnlocked(slot);
	}
}
[HarmonyPatch(typeof(Player), "UseHotbarItem")]
internal static class AbilityHotbarPatch
{
	[HarmonyPrefix]
	private static bool Prefix(Player __instance, int __0)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return true;
		}
		if (CharacterProgression.Class == CharacterClass.None)
		{
			return true;
		}
		KeyboardShortcut value;
		switch (__0)
		{
		case 1:
			if (JGRPG.Ability1KeyConfig != null)
			{
				value = JGRPG.Ability1KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return false;
				}
			}
			break;
		case 2:
			if (JGRPG.Ability2KeyConfig != null)
			{
				value = JGRPG.Ability2KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return false;
				}
			}
			break;
		case 3:
			if (JGRPG.Ability3KeyConfig != null)
			{
				value = JGRPG.Ability3KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return false;
				}
			}
			break;
		case 4:
			if (JGRPG.Ability4KeyConfig != null)
			{
				value = JGRPG.Ability4KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return false;
				}
			}
			break;
		case 5:
			if (JGRPG.Ability5KeyConfig != null)
			{
				value = JGRPG.Ability5KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return false;
				}
			}
			break;
		}
		return true;
	}
}
internal static class AbilityHUD
{
	private sealed class SlotView
	{
		public GameObject Root;

		public Image Background;

		public Text NameText;

		public Text CooldownText;
	}

	private static readonly SlotView[] Slots = new SlotView[6];

	private static GameObject _root;

	private static bool _registered;

	private static readonly Color ReadyColor = new Color(0.08f, 0.08f, 0.08f, 0.82f);

	private static readonly Color CooldownColor = new Color(0.28f, 0.28f, 0.28f, 0.88f);

	public static void Register()
	{
		if (!_registered)
		{
			_registered = true;
			GUIManager.OnCustomGUIAvailable += Build;
		}
	}

	private static void Build()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		if (GUIManager.IsHeadless())
		{
			return;
		}
		if (Object.op_Implicit((Object)(object)_root))
		{
			Object.Destroy((Object)(object)_root);
		}
		if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null) && GUIManager.Instance != null)
		{
			_root = new GameObject("JGRPG_AbilityHUD", new Type[1] { typeof(RectTransform) });
			_root.layer = 5;
			_root.transform.SetParent(GUIManager.CustomGUIFront.transform, false);
			RectTransform component = _root.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0f);
			component.anchorMax = new Vector2(0.5f, 0f);
			component.pivot = new Vector2(0.5f, 0f);
			component.anchoredPosition = new Vector2(0f, 135f);
			component.sizeDelta = new Vector2(900f, 70f);
			_root.AddComponent<AbilityHUDUpdater>();
			for (int i = 1; i <= 5; i++)
			{
				CreateSlot(i);
			}
			Refresh();
		}
	}

	private static void CreateSlot(int slot)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0071: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject($"JGRPG_Ability_{slot}", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		val.layer = 5;
		val.transform.SetParent(_root.transform, false);
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0.5f, 0.5f);
		component.anchorMax = new Vector2(0.5f, 0.5f);
		component.pivot = new Vector2(0.5f, 0.5f);
		component.sizeDelta = new Vector2(166f, 58f);
		component.anchoredPosition = new Vector2((float)(slot - 3) * 174f, 0f);
		Image component2 = val.GetComponent<Image>();
		((Graphic)component2).color = ReadyColor;
		Text component3 = GUIManager.Instance.CreateText("", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), GUIManager.Instance.AveriaSerifBold, 15, Color.white, true, Color.black, 158f, 28f, false).GetComponent<Text>();
		component3.alignment = (TextAnchor)4;
		Text component4 = GUIManager.Instance.CreateText("", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -14f), GUIManager.Instance.AveriaSerifBold, 19, Color.white, true, Color.black, 158f, 28f, false).GetComponent<Text>();
		component4.alignment = (TextAnchor)4;
		Slots[slot] = new SlotView
		{
			Root = val,
			Background = component2,
			NameText = component3,
			CooldownText = component4
		};
	}

	public static void Refresh()
	{
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)_root))
		{
			return;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null || CharacterProgression.Class == CharacterClass.None)
		{
			for (int i = 1; i <= 5; i++)
			{
				SlotView slotView = Slots[i];
				if (slotView != null && Object.op_Implicit((Object)(object)slotView.Root))
				{
					slotView.Root.SetActive(false);
				}
			}
			return;
		}
		for (int j = 1; j <= 5; j++)
		{
			SlotView slotView2 = Slots[j];
			if (slotView2 != null && Object.op_Implicit((Object)(object)slotView2.Root))
			{
				string abilityName = GetAbilityName(CharacterProgression.Class, j);
				bool flag = !string.IsNullOrEmpty(abilityName) && ClassAbilityUnlocks.IsUnlocked(j);
				slotView2.Root.SetActive(flag);
				if (flag)
				{
					slotView2.NameText.text = abilityName;
					float remaining = ClassAbilityCooldowns.GetRemaining(j);
					bool flag2 = remaining > 0f;
					((Graphic)slotView2.Background).color = (flag2 ? CooldownColor : ReadyColor);
					((Graphic)slotView2.NameText).color = (Color)(flag2 ? new Color(0.72f, 0.72f, 0.72f, 1f) : Color.white);
					slotView2.CooldownText.text = (flag2 ? $"{remaining:0.0}s" : "");
				}
			}
		}
	}

	private static string GetAbilityName(CharacterClass characterClass, int slot)
	{
		if (characterClass == CharacterClass.Ranger)
		{
			switch (slot)
			{
			case 1:
				return "Hunter's Mark";
			case 2:
				return "Explosive Shot";
			case 3:
				return "Rapid Shot";
			case 4:
				return "Ranger's Rally";
			case 5:
				return "Ullr's Quiver";
			}
		}
		if (characterClass == CharacterClass.Tank)
		{
			switch (slot)
			{
			case 1:
				return "Provoke";
			case 2:
				return "Fortify";
			case 3:
				return "Thunderclap";
			case 4:
				return "Guardian's Rally";
			case 5:
				return "Odin's Glare";
			}
		}
		if (characterClass == CharacterClass.Berserker)
		{
			switch (slot)
			{
			case 1:
				return "Rage";
			case 2:
				return "Whirlwind";
			case 3:
				return "Fury";
			case 4:
				return "Vorpal";
			case 5:
				return "Thor's Hammer";
			}
		}
		return null;
	}
}
internal sealed class AbilityHUDUpdater : MonoBehaviour
{
	private float _nextUpdate;

	private void Update()
	{
		if (!(Time.unscaledTime < _nextUpdate))
		{
			_nextUpdate = Time.unscaledTime + 0.05f;
			AbilityHUD.Refresh();
		}
	}
}
[HarmonyPatch(typeof(Player), "OnDestroy")]
internal static class AbilityCooldownLogoutResetPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			ClassAbilityCooldowns.ClearAll();
			Logger.LogInfo((object)"JGRPG ability cooldowns cleared because the local player was destroyed.");
		}
	}
}
internal static class BerserkerAbilities
{
	private static float _rageEndTime;

	private static Player _ragePlayer;

	private static float _furyEndTime;

	private static Player _furyPlayer;

	private static float _vorpalEndTime;

	private static Player _vorpalPlayer;

	private static float _thorsHammerEndTime;

	private static Player _thorsHammerPlayer;

	public static void TryActivate(int abilitySlot)
	{
		switch (abilitySlot)
		{
		case 1:
			TryActivateRage();
			break;
		case 2:
			TryActivateWhirlwind();
			break;
		case 3:
			TryActivateFury();
			break;
		case 4:
			TryActivateVorpal();
			break;
		case 5:
			TryActivateThorsHammer();
			break;
		default:
			Logger.LogInfo((object)("JGRPG Berserker ability " + $"{abilitySlot} not implemented yet."));
			break;
		}
	}

	private static void TryActivateRage()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(1))
		{
			float rageDuration = GetRageDuration();
			float rageCooldown = GetRageCooldown();
			_ragePlayer = localPlayer;
			_rageEndTime = Time.time + rageDuration;
			ClassAbilityCooldowns.StartCooldown(1, rageCooldown);
			Logger.LogInfo((object)("JGRPG Rage activated. " + $"Duration: {rageDuration:0.0}s. " + "Melee Damage: +10%. Incoming Damage: " + $"+{GetRageIncomingDamageBonus() * 100f:0}%. " + $"Cooldown: {rageCooldown:0.0}s."));
		}
	}

	private static void TryActivateWhirlwind()
	{
		//IL_0031: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || CharacterProgression.Class != CharacterClass.Berserker || !ClassAbilityCooldowns.IsReady(2))
		{
			return;
		}
		ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon();
		if (currentWeapon == null || !BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) || !((Character)localPlayer).HaveStamina(30f))
		{
			return;
		}
		float whirlwindRadius = GetWhirlwindRadius();
		float whirlwindCooldown = GetWhirlwindCooldown();
		float randomSkillFactor = ((Character)localPlayer).GetRandomSkillFactor(currentWeapon.m_shared.m_skillType);
		float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(localPlayer);
		List<Character> list = new List<Character>();
		Character.GetCharactersInRange(((Component)localPlayer).transform.position, whirlwindRadius, list);
		int num = 0;
		foreach (Character item in list)
		{
			if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)localPlayer) && !item.IsDead() && BaseAI.IsEnemy((Character)(object)localPlayer, item))
			{
				HitData val = new HitData();
				val.m_damage = currentWeapon.GetDamage();
				((DamageTypes)(ref val.m_damage)).Modify(0.75f * randomSkillFactor * totalMeleeDamageMultiplier);
				val.m_toolTier = (short)currentWeapon.m_shared.m_toolTier;
				val.m_skillLevel = ((Character)localPlayer).GetSkillLevel(currentWeapon.m_shared.m_skillType);
				val.m_itemLevel = (short)currentWeapon.m_quality;
				val.m_itemWorldLevel = (byte)currentWeapon.m_worldLevel;
				val.m_blockable = currentWeapon.m_shared.m_blockable;
				val.m_dodgeable = currentWeapon.m_shared.m_dodgeable;
				val.m_skill = currentWeapon.m_shared.m_skillType;
				val.m_point = item.GetCenterPoint();
				Vector3 dir = ((Component)item).transform.position - ((Component)localPlayer).transform.position;
				dir.y = 0f;
				if (((Vector3)(ref dir)).sqrMagnitude > 0.001f)
				{
					((Vector3)(ref dir)).Normalize();
				}
				else
				{
					dir = ((Component)localPlayer).transform.forward;
				}
				val.m_dir = dir;
				val.SetAttacker((Character)(object)localPlayer);
				val.m_hitType = (HitType)2;
				item.Damage(val);
				num++;
			}
		}
		((Character)localPlayer).UseStamina(30f);
		ClassAbilityCooldowns.StartCooldown(2, whirlwindCooldown);
		Logger.LogInfo((object)("JGRPG Whirlwind activated. " + $"Radius: {whirlwindRadius:0.0}m. " + "Damage: 75% weapon damage. " + $"Targets hit: {num}. " + $"Stamina: {30f:0}. " + $"Cooldown: {whirlwindCooldown:0.0}s."));
	}

	private static void TryActivateFury()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(3) && ((Character)localPlayer).HaveStamina(40f))
		{
			float furyHealthFraction = GetFuryHealthFraction();
			float num = ((Character)localPlayer).GetMaxHealth() * furyHealthFraction;
			if (((Character)localPlayer).GetHealth() > num)
			{
				((Character)localPlayer).SetHealth(num);
			}
			_furyPlayer = localPlayer;
			_furyEndTime = Time.time + GetFuryDuration();
			localPlayer.m_foodRegenTimer = 0f;
			((Character)localPlayer).UseStamina(40f);
			float furyCooldown = GetFuryCooldown();
			ClassAbilityCooldowns.StartCooldown(3, furyCooldown);
			Logger.LogInfo((object)("JGRPG Fury activated. Health floor: " + $"{furyHealthFraction * 100f:0}% max HP. " + $"Duration: {GetFuryDuration():0.0}s. " + "Health Regen: 0. " + $"Stamina: {40f:0}. " + $"Cooldown: {furyCooldown:0.0}s."));
		}
	}

	private static void TryActivateVorpal()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(4))
		{
			ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon();
			if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) && ((Character)localPlayer).HaveStamina(30f))
			{
				float vorpalDuration = GetVorpalDuration();
				float vorpalCooldown = GetVorpalCooldown();
				_vorpalPlayer = localPlayer;
				_vorpalEndTime = Time.time + vorpalDuration;
				((Character)localPlayer).UseStamina(30f);
				ClassAbilityCooldowns.StartCooldown(4, vorpalCooldown);
				Logger.LogInfo((object)("JGRPG Vorpal activated. " + $"Duration: {vorpalDuration:0.0}s. " + "Execute threshold: 30% HP. Damage: +50%. " + $"Stamina: {30f:0}. " + $"Cooldown: {vorpalCooldown:0.0}s."));
			}
		}
	}

	private static void TryActivateThorsHammer()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(5))
		{
			ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon();
			if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) && ((Character)localPlayer).HaveStamina(50f))
			{
				float thorsHammerDuration = GetThorsHammerDuration();
				float thorsHammerCooldown = GetThorsHammerCooldown();
				_thorsHammerPlayer = localPlayer;
				_thorsHammerEndTime = Time.time + thorsHammerDuration;
				((Character)localPlayer).UseStamina(50f);
				ClassAbilityCooldowns.StartCooldown(5, thorsHammerCooldown);
				Logger.LogInfo((object)("JGRPG Thor's Hammer activated. " + $"Duration: {thorsHammerDuration:0.0}s. " + "Melee Damage: +20%. Physical Damage: converted to Lightning. " + $"Stamina: {50f:0}. " + $"Cooldown: {thorsHammerCooldown:0.0}s."));
			}
		}
	}

	public static bool IsRageActive()
	{
		return IsRageActive(Player.m_localPlayer);
	}

	public static bool IsRageActive(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)_ragePlayer == (Object)null || (Object)(object)player != (Object)(object)_ragePlayer || CharacterProgression.Class != CharacterClass.Berserker)
		{
			return false;
		}
		if (((Character)player).IsDead())
		{
			ClearActiveEffects();
			return false;
		}
		if (Time.time >= _rageEndTime)
		{
			ClearActiveEffects();
			return false;
		}
		return true;
	}

	public static float GetRageDuration()
	{
		if (CharacterProgression.GetTalentRank("Berserker_EndlessRage") <= 0)
		{
			return 10f;
		}
		return 60f;
	}

	public static float GetRageCooldown()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_QuickenedRage");
		return Mathf.Max(0f, 20f - (float)talentRank);
	}

	public static float GetRageIncomingDamageBonus()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_PainResistant");
		return Mathf.Max(0f, 0.1f - (float)talentRank * 0.01f);
	}

	public static float GetWhirlwindRadius()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_OdinsRage");
		return 5f + (float)talentRank * 2.5f;
	}

	public static float GetWhirlwindCooldown()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_OdinsPresence");
		return Mathf.Max(0f, 30f - (float)talentRank);
	}

	public static bool IsFuryActive()
	{
		return IsFuryActive(Player.m_localPlayer);
	}

	public static bool IsFuryActive(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)_furyPlayer == (Object)null || (Object)(object)player != (Object)(object)_furyPlayer || CharacterProgression.Class != CharacterClass.Berserker)
		{
			return false;
		}
		if (((Character)player).IsDead())
		{
			ClearFury();
			return false;
		}
		if (Time.time >= _furyEndTime)
		{
			ClearFury();
			return false;
		}
		return true;
	}

	public static float GetFuryDuration()
	{
		return 10f;
	}

	public static float GetFuryHealthFraction()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_ReasonedFury");
		return 0.3f + (float)talentRank * 0.05f;
	}

	public static float GetFuryCooldown()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_QuickFury");
		return Mathf.Max(0f, 30f - (float)talentRank * 2f);
	}

	private static void ClearFury()
	{
		_furyEndTime = 0f;
		_furyPlayer = null;
	}

	public static bool IsVorpalActive()
	{
		return IsVorpalActive(Player.m_localPlayer);
	}

	public static bool IsVorpalActive(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)_vorpalPlayer == (Object)null || (Object)(object)player != (Object)(object)_vorpalPlayer || CharacterProgression.Class != CharacterClass.Berserker)
		{
			return false;
		}
		if (((Character)player).IsDead())
		{
			ClearVorpal();
			return false;
		}
		if (Time.time >= _vorpalEndTime)
		{
			ClearVorpal();
			return false;
		}
		return true;
	}

	public static float GetVorpalDuration()
	{
		return 10f;
	}

	public static float GetVorpalCooldown()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_Slayer");
		return Mathf.Max(0f, 30f - (float)talentRank);
	}

	private static void ClearVorpal()
	{
		_vorpalEndTime = 0f;
		_vorpalPlayer = null;
	}

	public static bool IsThorsHammerActive()
	{
		return IsThorsHammerActive(Player.m_localPlayer);
	}

	public static bool IsThorsHammerActive(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)_thorsHammerPlayer == (Object)null || (Object)(object)player != (Object)(object)_thorsHammerPlayer || CharacterProgression.Class != CharacterClass.Berserker)
		{
			return false;
		}
		if (((Character)player).IsDead())
		{
			ClearThorsHammer();
			return false;
		}
		if (Time.time >= _thorsHammerEndTime)
		{
			ClearThorsHammer();
			return false;
		}
		return true;
	}

	public static float GetThorsHammerDuration()
	{
		return 10f;
	}

	public static float GetThorsHammerCooldown()
	{
		int talentRank = CharacterProgression.GetTalentRank("Berserker_ThorsMight");
		return Mathf.Max(0f, 60f - (float)talentRank * 5f);
	}

	private static void ClearThorsHammer()
	{
		_thorsHammerEndTime = 0f;
		_thorsHammerPlayer = null;
	}

	public static void ClearActiveEffects()
	{
		_rageEndTime = 0f;
		_ragePlayer = null;
		ClearFury();
		ClearVorpal();
		ClearThorsHammer();
	}
}
[HarmonyPatch(typeof(Player), "OnDeath")]
internal static class BerserkerRageDeathPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance)
	{
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			BerserkerAbilities.ClearActiveEffects();
			ClassAbilityCooldowns.ClearAll();
			AbilityHUD.Refresh();
		}
	}
}
[HarmonyPatch(typeof(Player), "PlayerAttackInput")]
internal static class BerserkerAttackSpeedPatch
{
	private static Animator _animator;

	private static float _baseAnimatorSpeed = 1f;

	private static float _lastAppliedSpeed = 1f;

	private static bool _applied;

	[HarmonyPostfix]
	private static void Postfix(Player __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			Animator animator = ((Character)__instance).m_animator;
			if ((Object)(object)animator == (Object)null)
			{
				ClearState();
				return;
			}
			if (!ShouldBoostAttack(__instance))
			{
				RestoreAnimator(animator);
				return;
			}
			float attackSpeedMultiplier = GetAttackSpeedMultiplier();
			ApplyMultiplier(animator, attackSpeedMultiplier);
		}
	}

	private static bool ShouldBoostAttack(Player player)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		if (CharacterProgression.Class != CharacterClass.Berserker)
		{
			return false;
		}
		if (GetTotalAttackSpeedRanks() <= 0)
		{
			return false;
		}
		ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
		if (currentWeapon == null)
		{
			return false;
		}
		if (!BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType))
		{
			return false;
		}
		return ((Character)player).InAttack();
	}

	private static int GetTotalAttackSpeedRanks()
	{
		return CharacterProgression.GetTalentRank("Berserker_AttackSpeed1") + CharacterProgression.GetTalentRank("Berserker_AttackSpeed2") + CharacterProgression.GetTalentRank("Berserker_AttackSpeed3");
	}

	private static float GetAttackSpeedMultiplier()
	{
		int totalAttackSpeedRanks = GetTotalAttackSpeedRanks();
		return 1f + (float)totalAttackSpeedRanks * 0.025f;
	}

	private static void ApplyMultiplier(Animator animator, float multiplier)
	{
		float speed = animator.speed;
		if (!_applied || (Object)(object)_animator != (Object)(object)animator)
		{
			_animator = animator;
			_baseAnimatorSpeed = speed;
		}
		else if (Mathf.Abs(speed - _lastAppliedSpeed) > 0.0001f)
		{
			_baseAnimatorSpeed = speed;
		}
		float lastAppliedSpeed = (animator.speed = _baseAnimatorSpeed * multiplier);
		_lastAppliedSpeed = lastAppliedSpeed;
		_applied = true;
	}

	private static void RestoreAnimator(Animator animator)
	{
		if (_applied)
		{
			if ((Object)(object)_animator == (Object)(object)animator && Mathf.Abs(animator.speed - _lastAppliedSpeed) <= 0.0001f)
			{
				animator.speed = _baseAnimatorSpeed;
			}
			ClearState();
		}
	}

	private static void ClearState()
	{
		_animator = null;
		_baseAnimatorSpeed = 1f;
		_lastAppliedSpeed = 1f;
		_applied = false;
	}
}
[HarmonyPatch(typeof(Player), "UpdateFood")]
internal static class BerserkerFuryHealthRegenPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance, bool forceUpdate)
	{
		if (!((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || forceUpdate) && BerserkerAbilities.IsFuryActive(__instance))
		{
			__instance.m_foodRegenTimer = 0f;
		}
	}
}
internal static class BerserkerPassiveBonuses
{
	public static float GetMeleeDamageBonus()
	{
		return (float)(CharacterProgression.GetTalentRank("Berserker_MeleeDamage1") + CharacterProgression.GetTalentRank("Berserker_MeleeDamage2") + CharacterProgression.GetTalentRank("Berserker_MeleeDamage3")) * 0.03f;
	}

	public static float GetDesperationDamageBonus()
	{
		return (float)(CharacterProgression.GetTalentRank("Berserker_Desperation1") + CharacterProgression.GetTalentRank("Berserker_Desperation2") + CharacterProgression.GetTalentRank("Berserker_Desperation3")) * 0.05f;
	}

	public static float GetTotalMeleeDamageMultiplier(Player player)
	{
		float num = GetMeleeDamageBonus();
		if ((Object)(object)player != (Object)null && ((Character)player).GetHealth() < ((Character)player).GetMaxHealth() * 0.5f)
		{
			num += GetDesperationDamageBonus();
		}
		if (BerserkerAbilities.IsRageActive(player))
		{
			num += 0.1f;
		}
		if (BerserkerAbilities.IsThorsHammerActive(player))
		{
			num += 0.2f;
		}
		return 1f + num;
	}

	public static float GetStaminaRegenMultiplier()
	{
		int num = CharacterProgression.GetTalentRank("Berserker_StaminaRegeneration1") + CharacterProgression.GetTalentRank("Berserker_StaminaRegeneration2");
		return 1f + (float)num * 0.05f;
	}

	public static float GetArmorBonus()
	{
		return (float)CharacterProgression.GetTalentRank("Berserker_Armored") * 5f;
	}

	public static float GetMaxStaminaBonus()
	{
		return (float)(CharacterProgression.GetTalentRank("Berserker_Endurance1") + CharacterProgression.GetTalentRank("Berserker_Endurance2")) * 5f;
	}

	public static float GetMovementSpeedMultiplier()
	{
		int num = CharacterProgression.GetTalentRank("Berserker_RelentlessPursuit1") + CharacterProgression.GetTalentRank("Berserker_RelentlessPursuit2");
		return 1f + (float)num * 0.05f;
	}

	public static float GetMaxHealthBonus()
	{
		return (float)CharacterProgression.GetTalentRank("Berserker_Vitality1") * 5f;
	}

	public static float GetSprintStaminaReduction()
	{
		return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_Tireless") * 0.05f, 0f, 0.95f);
	}

	public static float GetEndlessThirstStaminaFraction()
	{
		return Mathf.Clamp01((float)CharacterProgression.GetTalentRank("Berserker_EndlessThirst") * 0.04f);
	}

	public static float GetOdinsStrengthReduction()
	{
		return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_OdinsStrength") * 0.025f, 0f, 0.95f);
	}

	public static float GetTooAngryToDieReduction()
	{
		return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_TooAngryToDie") * 0.05f, 0f, 0.95f);
	}

	public static float GetIncomingDamageMultiplier(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return 1f;
		}
		float num = 0f;
		if (((Character)player).GetHealth() < ((Character)player).GetMaxHealth() * 0.5f)
		{
			num -= GetTooAngryToDieReduction();
		}
		if (BerserkerAbilities.IsRageActive())
		{
			num += BerserkerAbilities.GetRageIncomingDamageBonus();
		}
		return 1f + num;
	}

	public static bool IsMeleeWeaponSkill(SkillType skillType)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Invalid comparison between Unknown and I4
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Invalid comparison between Unknown and I4
		if ((int)skillType != 7 && (int)skillType != 3 && (int)skillType != 2 && (int)skillType != 4 && (int)skillType != 5)
		{
			return (int)skillType == 1;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Attack), "ModifyDamage")]
internal static class BerserkerMeleeDamagePatch
{
	[HarmonyPostfix]
	private static void Postfix(Attack __instance, HitData hitData)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (CharacterProgression.Class == CharacterClass.Berserker && __instance != null && hitData != null && !((Object)(object)__instance.m_character == (Object)null) && !((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && __instance.m_weapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(__instance.m_weapon.m_shared.m_skillType))
		{
			float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(Player.m_localPlayer);
			if (totalMeleeDamageMultiplier != 1f)
			{
				((DamageTypes)(ref hitData.m_damage)).Modify(totalMeleeDamageMultiplier);
			}
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })]
internal static class BerserkerStaminaRegenPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance, out float __state)
	{
		__state = -1f;
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			float staminaRegenMultiplier = BerserkerPassiveBonuses.GetStaminaRegenMultiplier();
			if (staminaRegenMultiplier != 1f)
			{
				__state = __instance.m_staminaRegen;
				__instance.m_staminaRegen *= staminaRegenMultiplier;
			}
		}
	}

	[HarmonyPostfix]
	private static void Postfix(Player __instance, float __state)
	{
		if (!((Object)(object)__instance == (Object)null) && !(__state < 0f))
		{
			__instance.m_staminaRegen = __state;
		}
	}
}
[HarmonyPatch(typeof(Player), "GetBodyArmor")]
internal static class BerserkerArmoredPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			__result += BerserkerPassiveBonuses.GetArmorBonus();
		}
	}
}
[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
internal static class BerserkerMaxStatsPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float hp, ref float stamina)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			hp += BerserkerPassiveBonuses.GetMaxHealthBonus();
			stamina += BerserkerPassiveBonuses.GetMaxStaminaBonus();
		}
	}
}
[HarmonyPatch(typeof(Player), "GetJogSpeedFactor")]
internal static class BerserkerRelentlessPursuitJogPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			__result *= BerserkerPassiveBonuses.GetMovementSpeedMultiplier();
		}
	}
}
[HarmonyPatch(typeof(Player), "GetRunSpeedFactor")]
internal static class BerserkerRelentlessPursuitRunPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			__result *= BerserkerPassiveBonuses.GetMovementSpeedMultiplier();
		}
	}
}
[HarmonyPatch(typeof(Player), "GetEquipmentRunStaminaModifier")]
internal static class BerserkerTirelessPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			__result -= BerserkerPassiveBonuses.GetSprintStaminaReduction();
		}
	}
}
[HarmonyPatch(typeof(Player), "GetEquipmentAttackStaminaModifier")]
internal static class BerserkerOdinsStrengthPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
			if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType))
			{
				__result -= BerserkerPassiveBonuses.GetOdinsStrengthReduction();
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
internal static class BerserkerTooAngryToDiePatch
{
	[HarmonyPrefix]
	private static void Prefix(Character __instance, HitData hit)
	{
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			float incomingDamageMultiplier = BerserkerPassiveBonuses.GetIncomingDamageMultiplier(Player.m_localPlayer);
			if (incomingDamageMultiplier != 1f)
			{
				((DamageTypes)(ref hit.m_damage)).Modify(incomingDamageMultiplier);
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
internal static class BerserkerEndlessThirstPatch
{
	[HarmonyPrefix]
	private static void Prefix(Character __instance, HitData hit, out bool __state)
	{
		__state = false;
		if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)Player.m_localPlayer == (Object)null))
		{
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !__instance.IsDead() && !(__instance.GetHealth() <= 0f) && BaseAI.IsEnemy((Character)(object)val, __instance))
			{
				__state = true;
			}
		}
	}

	[HarmonyPostfix]
	private static void Postfix(Character __instance, bool __state)
	{
		if (__state && !((Object)(object)__instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && (__instance.IsDead() || !(__instance.GetHealth() > 0f)))
		{
			float endlessThirstStaminaFraction = BerserkerPassiveBonuses.GetEndlessThirstStaminaFraction();
			if (!(endlessThirstStaminaFraction <= 0f))
			{
				Player localPlayer = Player.m_localPlayer;
				((Character)localPlayer).AddStamina(((Character)localPlayer).GetMaxStamina() * endlessThirstStaminaFraction);
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
internal static class BerserkerCombatAbilityDamagePatch
{
	[HarmonyPrefix]
	private static void Prefix(Character __instance, HitData hit)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || hit == null || (Object)(object)Player.m_localPlayer == (Object)null || CharacterProgression.Class != CharacterClass.Berserker)
		{
			return;
		}
		Character attacker = hit.GetAttacker();
		Player val = (Player)(object)((attacker is Player) ? attacker : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !BerserkerPassiveBonuses.IsMeleeWeaponSkill(hit.m_skill) || hit.m_ranged)
		{
			return;
		}
		bool flag = BerserkerAbilities.IsVorpalActive(val);
		bool flag2 = BerserkerAbilities.IsThorsHammerActive(val);
		if (!flag && !flag2)
		{
			return;
		}
		if (flag)
		{
			float maxHealth = __instance.GetMaxHealth();
			if (maxHealth > 0f && __instance.GetHealth() / maxHealth <= 0.3f)
			{
				float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(val);
				if (totalMeleeDamageMultiplier > 0f)
				{
					float num = (totalMeleeDamageMultiplier + 0.5f) / totalMeleeDamageMultiplier;
					((DamageTypes)(ref hit.m_damage)).Modify(num);
				}
			}
		}
		if (flag2)
		{
			float blunt = hit.m_damage.m_blunt;
			float slash = hit.m_damage.m_slash;
			float pierce = hit.m_damage.m_pierce;
			float num2 = blunt + slash + pierce;
			hit.m_damage.m_blunt = 0f;
			hit.m_damage.m_slash = 0f;
			hit.m_damage.m_pierce = 0f;
			hit.m_damage.m_lightning += num2;
		}
	}
}
internal static class BossProgression
{
	public static int GetWorldLevelCap()
	{
		if ((Object)(object)ZoneSystem.instance == (Object)null)
		{
			return 10;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_fader"))
		{
			return 90;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_queen"))
		{
			return 70;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_goblinking"))
		{
			return 60;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_dragon"))
		{
			return 50;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_bonemass"))
		{
			return 40;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_gdking"))
		{
			return 30;
		}
		if (ZoneSystem.instance.GetGlobalKey("defeated_eikthyr"))
		{
			return 20;
		}
		return 10;
	}

	public static bool TryGetBossInfo(Character character, out string globalKey, out int newLevelCap)
	{
		globalKey = null;
		newLevelCap = 0;
		if ((Object)(object)character == (Object)null)
		{
			return false;
		}
		return TryGetBossInfo(((Object)character).name, out globalKey, out newLevelCap);
	}

	public static bool TryGetBossInfo(string prefabName, out string globalKey, out int newLevelCap)
	{
		globalKey = null;
		newLevelCap = 0;
		if (string.IsNullOrEmpty(prefabName))
		{
			return false;
		}
		prefabName = prefabName.Replace("(Clone)", "");
		switch (prefabName)
		{
		case "Eikthyr":
			globalKey = "defeated_eikthyr";
			newLevelCap = 20;
			return true;
		case "gd_king":
			globalKey = "defeated_gdking";
			newLevelCap = 30;
			return true;
		case "Bonemass":
			globalKey = "defeated_bonemass";
			newLevelCap = 40;
			return true;
		case "Dragon":
			globalKey = "defeated_dragon";
			newLevelCap = 50;
			return true;
		case "GoblinKing":
			globalKey = "defeated_goblinking";
			newLevelCap = 60;
			return true;
		case "SeekerQueen":
			globalKey = "defeated_queen";
			newLevelCap = 70;
			return true;
		case "Fader":
			globalKey = "defeated_fader";
			newLevelCap = 90;
			return true;
		default:
			return false;
		}
	}
}
internal enum CharacterClass
{
	None,
	Tank,
	Berserker,
	Ranger
}
internal static class CharacterProgression
{
	public static CharacterClass Class { get; private set; } = CharacterClass.None;

	public static int AvailableTalentPoints
	{
		get
		{
			int num = WorldProgression.Level - SpentTalentPoints;
			if (num >= 0)
			{
				return num;
			}
			return 0;
		}
	}

	public static int SpentTalentPoints { get; private set; } = 0;

	public static Dictionary<string, int> TalentRanks { get; private set; } = new Dictionary<string, int>();

	public static void SetClass(CharacterClass characterClass)
	{
		Class = characterClass;
	}

	public static void ChangeClass(CharacterClass characterClass)
	{
		Class = characterClass;
		SpentTalentPoints = 0;
		TalentRanks.Clear();
	}

	public static void RestoreTalentRank(string talentId, int rank)
	{
		if (!string.IsNullOrWhiteSpace(talentId) && rank > 0)
		{
			if (TalentRanks.TryGetValue(talentId, out var value))
			{
				SpentTalentPoints -= value;
			}
			TalentRanks[talentId] = rank;
			SpentTalentPoints += rank;
		}
	}

	public static int GetTalentRank(string talentId)
	{
		if (string.IsNullOrWhiteSpace(talentId))
		{
			return 0;
		}
		if (TalentRanks.TryGetValue(talentId, out var value))
		{
			return value;
		}
		return 0;
	}

	public static bool TryPurchaseTalentRank(string talentId)
	{
		if (string.IsNullOrWhiteSpace(talentId) || AvailableTalentPoints <= 0)
		{
			return false;
		}
		if (!TalentCatalog.Talents.TryGetValue(talentId, out var value))
		{
			return false;
		}
		if (value.Class != Class)
		{
			return false;
		}
		if (WorldProgression.Level < value.MinimumLevel)
		{
			return false;
		}
		int value2 = 0;
		TalentRanks.TryGetValue(talentId, out value2);
		if (value2 >= value.MaxRank)
		{
			return false;
		}
		value2++;
		TalentRanks[talentId] = value2;
		SpentTalentPoints++;
		return true;
	}

	public static bool ResetTalents()
	{
		if (SpentTalentPoints <= 0 && TalentRanks.Count <= 0)
		{
			return false;
		}
		TalentRanks.Clear();
		SpentTalentPoints = 0;
		return true;
	}

	public static void Reset()
	{
		Class = CharacterClass.None;
		TalentRanks.Clear();
		SpentTalentPoints = 0;
	}
}
internal static class CharacterProgressionSave
{
	private static string GetSavePath(Player player)
	{
		long worldUID = ZNet.instance.GetWorldUID();
		long playerID = player.GetPlayerID();
		string text = Path.Combine(Paths.ConfigPath, "JGRPG", "Characters");
		Directory.CreateDirectory(text);
		return Path.Combine(text, $"character_{playerID}_world_{worldUID}.txt");
	}

	public static void Save(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		string savePath = GetSavePath(player);
		List<string> list = new List<string> { $"Class={CharacterProgression.Class}" };
		foreach (KeyValuePair<string, int> talentRank in CharacterProgression.TalentRanks)
		{
			list.Add($"Talent.{talentRank.Key}={talentRank.Value}");
		}
		File.WriteAllLines(savePath, list);
		Logger.LogInfo((object)("JGRPG character progression saved: " + $"Class {CharacterProgression.Class}"));
	}

	public static void Load(Player player)
	{
		CharacterProgression.Reset();
		if ((Object)(object)player == (Object)null || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		string savePath = GetSavePath(player);
		if (!File.Exists(savePath))
		{
			Logger.LogInfo((object)"JGRPG character progression: no save found");
			return;
		}
		string[] array = File.ReadAllLines(savePath);
		foreach (string text in array)
		{
			if (text.StartsWith("Class="))
			{
				if (Enum.TryParse<CharacterClass>(text.Substring("Class=".Length), out var result))
				{
					CharacterProgression.SetClass(result);
				}
			}
			else
			{
				if (!text.StartsWith("Talent."))
				{
					continue;
				}
				int num = text.IndexOf('=');
				if (num > "Talent.".Length)
				{
					string talentId = text.Substring("Talent.".Length, num - "Talent.".Length);
					if (int.TryParse(text.Substring(num + 1), out var result2))
					{
						CharacterProgression.RestoreTalentRank(talentId, result2);
					}
				}
			}
		}
		Logger.LogInfo((object)("JGRPG character progression loaded: " + $"Class {CharacterProgression.Class}"));
	}
}
internal static class ClassAbilityCooldowns
{
	private static readonly float[] ReadyTimes = new float[6];

	public static bool IsReady(int abilitySlot)
	{
		if (abilitySlot < 1 || abilitySlot > 5)
		{
			return false;
		}
		return Time.time >= ReadyTimes[abilitySlot];
	}

	public static float GetRemaining(int abilitySlot)
	{
		if (abilitySlot < 1 || abilitySlot > 5)
		{
			return 0f;
		}
		float num = ReadyTimes[abilitySlot] - Time.time;
		return Mathf.Max(0f, num);
	}

	public static void StartCooldown(int abilitySlot, float duration)
	{
		if (abilitySlot >= 1 && abilitySlot <= 5)
		{
			if (duration < 0f)
			{
				duration = 0f;
			}
			ReadyTimes[abilitySlot] = Time.time + duration;
		}
	}

	public static void ClearAll()
	{
		for (int i = 1; i <= 5; i++)
		{
			ReadyTimes[i] = 0f;
		}
	}
}
internal static class ClassAbilityManager
{
	public static void TryActivate(int abilitySlot)
	{
		if (abilitySlot >= 1 && abilitySlot <= 5 && CharacterProgression.Class != CharacterClass.None)
		{
			switch (CharacterProgression.Class)
			{
			case CharacterClass.Ranger:
				RangerAbilities.TryActivate(abilitySlot);
				break;
			case CharacterClass.Tank:
				TankAbilities.TryActivate(abilitySlot);
				break;
			case CharacterClass.Berserker:
				BerserkerAbilities.TryActivate(abilitySlot);
				break;
			}
		}
	}
}
internal static class ClassAbilityUnlocks
{
	public static int GetRequiredLevel(int slot)
	{
		return slot switch
		{
			1 => 1, 
			2 => 21, 
			3 => 41, 
			4 => 61, 
			5 => 81, 
			_ => int.MaxValue, 
		};
	}

	public static bool IsUnlocked(int slot)
	{
		return WorldProgression.Level >= GetRequiredLevel(slot);
	}
}
[HarmonyPatch(typeof(Character), "Awake")]
internal static class EnemySpawnBiomePatch
{
	private const string SpawnBiomeKey = "JGRPG_SpawnBiome";

	[HarmonyPostfix]
	private static void Postfix(Character __instance)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected I4, but got Unknown
		if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer() && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner())
		{
			ZDO zDO = __instance.m_nview.GetZDO();
			if (zDO != null && zDO.GetInt("JGRPG_SpawnBiome", -1) == -1)
			{
				Biome val = Heightmap.FindBiome(((Component)__instance).transform.position);
				zDO.Set("JGRPG_SpawnBiome", (int)val);
			}
		}
	}

	public static Biome GetSpawnBiome(Character character)
	{
		//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)
		if ((Object)(object)character != (Object)null && (Object)(object)character.m_nview != (Object)null && character.m_nview.IsValid())
		{
			ZDO zDO = character.m_nview.GetZDO();
			if (zDO != null)
			{
				int num = zDO.GetInt("JGRPG_SpawnBiome", -1);
				if (num != -1)
				{
					return (Biome)num;
				}
			}
		}
		return Heightmap.FindBiome(((Component)character).transform.position);
	}
}
internal static class EnemyXP
{
	public static double GetStarMultiplier(int stars)
	{
		if (stars < 0)
		{
			stars = 0;
		}
		return 1.0 + (double)stars * 0.5;
	}

	private static int GetCurrentBiomeTier()
	{
		if (WorldProgression.Level <= 10)
		{
			return 0;
		}
		if (WorldProgression.Level <= 20)
		{
			return 1;
		}
		if (WorldProgression.Level <= 30)
		{
			return 2;
		}
		if (WorldProgression.Level <= 40)
		{
			return 3;
		}
		if (WorldProgression.Level <= 50)
		{
			return 4;
		}
		if (WorldProgression.Level <= 60)
		{
			return 5;
		}
		if (WorldProgression.Level <= 70)
		{
			return 6;
		}
		return 7;
	}

	private static int GetBiomeTier(Biome biome)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected I4, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Invalid comparison between Unknown and I4
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Invalid comparison between Unknown and I4
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Invalid comparison between Unknown and I4
		if ((int)biome <= 16)
		{
			switch (biome - 1)
			{
			case 0:
				return 0;
			case 1:
				return 2;
			case 3:
				goto IL_0051;
			case 2:
				goto IL_005b;
			}
			if ((int)biome == 8)
			{
				return 1;
			}
			if ((int)biome == 16)
			{
				return 4;
			}
		}
		else if ((int)biome <= 64)
		{
			if ((int)biome == 32)
			{
				return 6;
			}
			if ((int)biome == 64)
			{
				return 7;
			}
		}
		else
		{
			if ((int)biome == 256)
			{
				goto IL_0051;
			}
			if ((int)biome == 512)
			{
				return 5;
			}
		}
		goto IL_005b;
		IL_0051:
		return 3;
		IL_005b:
		return int.MaxValue;
	}

	public static double GetBiomeMultiplier(Biome biome)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		int currentBiomeTier = GetCurrentBiomeTier();
		int biomeTier = GetBiomeTier(biome);
		if (biomeTier >= currentBiomeTier)
		{
			return 1.0;
		}
		return (currentBiomeTier - biomeTier) switch
		{
			1 => 0.5, 
			2 => 0.25, 
			_ => 0.0, 
		};
	}

	public static long CalculateBaseXP(float baseMaxHealth, int stars)
	{
		if (baseMaxHealth <= 0f)
		{
			return 0L;
		}
		return (long)Math.Round((double)baseMaxHealth * GetStarMultiplier(stars));
	}

	public static long CalculateXP(float baseMaxHealth, int stars, Biome biome)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		long num = CalculateBaseXP(baseMaxHealth, stars);
		if (num <= 0)
		{
			return 0L;
		}
		double biomeMultiplier = GetBiomeMultiplier(biome);
		return (long)Math.Round((double)num * biomeMultiplier);
	}
}
[HarmonyPatch]
internal static class ExplosiveShotAttackPatch
{
	[HarmonyPatch(typeof(Attack), "Start")]
	[HarmonyPostfix]
	private static void AttackStartPostfix(Attack __instance, bool __result)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Invalid comparison between Unknown and I4
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Invalid comparison between Unknown and I4
		if (__result && !((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && (int)__instance.m_attackType == 2 && __instance.m_weapon != null)
		{
			SkillType skillType = __instance.m_weapon.m_shared.m_skillType;
			if (((int)skillType == 8 || (int)skillType == 14) && ExplosiveShotSystem.IsActive())
			{
				ExplosiveShotAttackTracker.StartAttack(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	[HarmonyPrefix]
	private static void FireProjectileBurstPrefix(Attack __instance)
	{
		ExplosiveShotAttackTracker.BeginProjectileBurst(__instance);
	}

	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	[HarmonyPostfix]
	private static void FireProjectileBurstPostfix()
	{
		ExplosiveShotAttackTracker.EndProjectileBurst();
	}

	[HarmonyPatch(typeof(Projectile), "Setup")]
	[HarmonyPostfix]
	private static void ProjectileSetupPostfix(Projectile __instance)
	{
		ExplosiveShotAttackTracker.RegisterProjectile(__instance);
	}

	[HarmonyPatch(typeof(Attack), "Stop")]
	[HarmonyPostfix]
	private static void AttackStopPostfix(Attack __instance)
	{
		ExplosiveShotAttackTracker.EndAttack(__instance);
	}
}
internal static class ExplosiveShotAttackTracker
{
	private static int _nextAttackId = 1;

	private static int _currentAttackId;

	private static readonly Dictionary<Attack, int> AttackIds = new Dictionary<Attack, int>();

	private static readonly Dictionary<int, int> ProjectileAttackIds = new Dictionary<int, int>();

	private static readonly HashSet<int> ExplodedAttackIds = new HashSet<int>();

	private static readonly HashSet<int> ExplodedProjectileIds = new HashSet<int>();

	public static int CreateAttackGroup()
	{
		int nextAttackId = _nextAttackId;
		_nextAttackId++;
		return nextAttackId;
	}

	public static void RegisterAttackToGroup(Attack attack, int attackId)
	{
		if (attack != null && attackId > 0)
		{
			AttackIds[attack] = attackId;
		}
	}

	public static void StartAttack(Attack attack)
	{
		if (attack != null)
		{
			AttackIds[attack] = CreateAttackGroup();
		}
	}

	public static void BeginProjectileBurst(Attack attack)
	{
		_currentAttackId = 0;
		if (attack != null && AttackIds.TryGetValue(attack, out var value))
		{
			_currentAttackId = value;
		}
	}

	public static void EndProjectileBurst()
	{
		_currentAttackId = 0;
	}

	public static void RegisterProjectile(Projectile projectile)
	{
		if (!((Object)(object)projectile == (Object)null) && _currentAttackId != 0)
		{
			ProjectileAttackIds[((Object)projectile).GetInstanceID()] = _currentAttackId;
		}
	}

	public static bool TryClaimExplosion(Projectile projectile)
	{
		if ((Object)(object)projectile == (Object)null)
		{
			return false;
		}
		int instanceID = ((Object)projectile).GetInstanceID();
		if (!ProjectileAttackIds.TryGetValue(instanceID, out var value))
		{
			return false;
		}
		if (UllrsQuiverProjectileTracker.IsUllrProjectile(projectile))
		{
			return ExplodedProjectileIds.Add(instanceID);
		}
		return ExplodedAttackIds.Add(value);
	}

	public static void EndAttack(Attack attack)
	{
		if (attack != null)
		{
			AttackIds.Remove(attack);
		}
	}

	public static void Clear()
	{
		AttackIds.Clear();
		ProjectileAttackIds.Clear();
		ExplodedAttackIds.Clear();
		ExplodedProjectileIds.Clear();
		_currentAttackId = 0;
		_nextAttackId = 1;
	}
}
[HarmonyPatch(typeof(Projectile), "OnHit")]
internal static class ExplosiveShotDamagePatch
{
	[HarmonyPostfix]
	private static void Postfix(Projectile __instance, Collider collider, Vector3 hitPoint)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || (Object)(object)collider == (Object)null)
		{
			return;
		}
		Character owner = __instance.m_owner;
		Player val = (Player)(object)((owner is Player) ? owner : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || __instance.m_originalHitData == null)
		{
			return;
		}
		GameObject val2 = Projectile.FindHitObject(collider);
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Character component = val2.GetComponent<Character>();
		if ((Object)(object)component == (Object)null || component.IsTamed() || !BaseAI.IsEnemy((Character)(object)val, component) || !ExplosiveShotAttackTracker.TryClaimExplosion(__instance))
		{
			return;
		}
		float explosionRadius = ExplosiveShotSystem.GetExplosionRadius();
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)val) && !allCharacter.IsTamed() && BaseAI.IsEnemy((Character)(object)val, allCharacter) && !(Vector3.Distance(hitPoint, ((Component)allCharacter).transform.position) > explosionRadius))
			{
				ExplosiveShotSystem.ApplyExplosionDamage(allCharacter, val, __instance.m_originalHitData);
			}
		}
	}
}
internal static class ExplosiveShotSystem
{
	private const float Duration = 10f;

	private const float BaseCooldown = 30f;

	private const float BaseRadius = 5f;

	public const float ExplosionDamageMultiplier = 0.5f;

	public const float StaminaCost = 30f;

	private static float _endTime;

	public static DamageTypes GetExplosionDamage(HitData originalHit)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		DamageTypes damage = originalHit.m_damage;
		((DamageTypes)(ref damage)).Modify(0.5f);
		return damage;
	}

	public static void ApplyExplosionDamage(Character target, Player attacker, HitData originalHit)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && !((Object)(object)attacker == (Object)null) && originalHit != null)
		{
			HitData val = new HitData();
			val.m_damage = GetExplosionDamage(originalHit);
			val.m_point = ((Component)target).transform.position;
			Vector3 val2 = ((Component)target).transform.position - ((Component)attacker).transform.position;
			val.m_dir = ((Vector3)(ref val2)).normalized;
			val.m_attacker = ((Character)attacker).GetZDOID();
			val.m_ranged = false;
			target.Damage(val);
		}
	}

	public static float GetCooldownDuration()
	{
		int talentRank = CharacterProgression.GetTalentRank("Ranger_AlchemistTrained");
		return Mathf.Max(0f, 30f - (float)talentRank);
	}

	public static float GetExplosionRadius()
	{
		int talentRank = CharacterProgression.GetTalentRank("Ranger_Volatile");
		return 5f + (float)talentRank * 2.5f;
	}

	public static void Activate()
	{
		ExplosiveShotAttackTracker.Clear();
		_endTime = Time.time + 10f;
	}

	public static bool IsActive()
	{
		return Time.time < _endTime;
	}

	public static float GetRemainingDuration()
	{
		return Mathf.Max(0f, _endTime - Time.time);
	}

	public static void Clear()
	{
		_endTime = 0f;
		ExplosiveShotAttackTracker.Clear();
	}
}
[HarmonyPatch(typeof(ZoneSystem), "SetGlobalKey", new Type[] { typeof(string) })]
internal static class GlobalKeyPatch
{
	[HarmonyPostfix]
	private static void Postfix(string name)
	{
		if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
		{
			int levelCap = WorldProgression.LevelCap;
			WorldProgression.SetLevelCap(BossProgression.GetWorldLevelCap());
			if (WorldProgression.LevelCap > levelCap)
			{
				Logger.LogInfo((object)("JGRPG level cap increased: " + $"{levelCap} -> {WorldProgression.LevelCap} " + "after global key '" + name + "'"));
				WorldProgressionNetwork.Broadcast();
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
internal static class HuntersMarkDamagePatch
{
	[HarmonyPrefix]
	private static void Prefix(Character __instance, HitData hit)
	{
		if ((Object)(object)__instance == (Object)null || hit == null)
		{
			return;
		}
		float damageBonus = HuntersMarkSystem.GetDamageBonus(__instance);
		if (!(damageBonus <= 0f))
		{
			Character attacker = hit.GetAttacker();
			if (!((Object)(object)attacker == (Object)null) && attacker.IsPlayer())
			{
				((DamageTypes)(ref hit.m_damage)).Modify(1f + damageBonus);
			}
		}
	}
}
internal static class HuntersMarkNetwork
{
	public static CustomRPC MarkRPC { get; private set; }

	public static void Register()
	{
		//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
		MarkRPC = NetworkManager.Instance.AddRPC("HuntersMark", new CoroutineHandler(ServerReceive), new CoroutineHandler(ClientReceive));
	}

	public static void SendMark(Character target)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target == (Object)null || (Object)(object)ZNet.instance == (Object)null || MarkRPC == null)
		{
			return;
		}
		ZDOID zDOID = target.GetZDOID();
		if (!(zDOID == ZDOID.None))
		{
			float damageBonus = HuntersMarkSystem.GetDamageBonus();
			if (ZNet.instance.IsServer())
			{
				BroadcastMark(zDOID, damageBonus);
			}
			else if (ZRoutedRpc.instance != null)
			{
				ZPackage val = new ZPackage();
				val.Write(zDOID);
				val.Write(damageBonus);
				MarkRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val);
			}
		}
	}

	private static void BroadcastMark(ZDOID targetID, float damageBonus)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && MarkRPC != null)
		{
			List<ZNetPeer> peers = ZNet.instance.GetPeers();
			if (peers != null && peers.Count != 0)
			{
				ZPackage val = new ZPackage();
				val.Write(targetID);
				val.Write(damageBonus);
				MarkRPC.SendPackage(peers, val);
			}
		}
	}

	private static Character FindCharacter(ZDOID targetID)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			return null;
		}
		GameObject val = ZNetScene.instance.FindInstance(targetID);
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		return val.GetComponent<Character>();
	}

	private static IEnumerator ServerReceive(long sender, ZPackage package)
	{
		ZDOID targetID = package.ReadZDOID();
		float damageBonus = package.ReadSingle();
		Character val = FindCharacter(targetID);
		if (!((Object)(object)val == (Object)null))
		{
			HuntersMarkSystem.ApplyMark(val, damageBonus);
			BroadcastMark(targetID, damageBonus);
			yield return null;
		}
	}

	private static IEnumerator ClientReceive(long sender, ZPackage package)
	{
		ZDOID targetID = package.ReadZDOID();
		float damageBonus = package.ReadSingle();
		Character val = FindCharacter(targetID);
		if ((Object)(object)val != (Object)null)
		{
			HuntersMarkSystem.ApplyMark(val, damageBonus);
		}
		yield return null;
	}
}
internal static class HuntersMarkSystem
{
	private class MarkData
	{
		public float EndTime;

		public float DamageBonus;
	}

	private const float MarkDuration = 10f;

	private const float BaseCooldown = 20f;

	private static readonly Dictionary<ZDOID, MarkData> Marks = new Dictionary<ZDOID, MarkData>();

	public static float GetCooldownDuration()
	{
		int talentRank = CharacterProgression.GetTalentRank("Ranger_HuntersInsight");
		return Mathf.Max(0f, 20f - (float)talentRank);
	}

	public static float GetDamageBonus()
	{
		float num = 0.1f;
		if (CharacterProgression.GetTalentRank("Ranger_MarkedWeakness") > 0)
		{
			num += 0.05f;
		}
		int talentRank = CharacterProgression.GetTalentRank("Ranger_PackHunter");
		return num + (float)talentRank * 0.025f;
	}

	public static bool HasGroupHunt()
	{
		return CharacterProgression.GetTalentRank("Ranger_GroupHunt") > 0;
	}

	public static List<Character> GetTargets(Player player, Character primaryTarget)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = new List<Character>();
		if ((Object)(object)player == (Object)null || (Object)(object)primaryTarget == (Object)null)
		{
			return list;
		}
		list.Add(primaryTarget);
		if (!HasGroupHunt())
		{
			return list;
		}
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)primaryTarget) && !((Object)(object)allCharacter == (Object)(object)player) && !allCharacter.IsTamed() && BaseAI.IsEnemy((Character)(object)player, allCharacter))
			{
				Vector3 val = ((Component)allCharacter).transform.position - ((Component)primaryTarget).transform.position;
				if (!(((Vector3)(ref val)).sqrMagnitude > 100f))
				{
					list.Add(allCharacter);
				}
			}
		}
		return list;
	}

	public static void ApplyMark(Character target)
	{
		ApplyMark(target, GetDamageBonus());
	}

	public static void ApplyMark(Character target, float damageBonus)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null))
		{
			ZDOID zDOID = target.GetZDOID();
			if (!(zDOID == ZDOID.None))
			{
				Marks[zDOID] = new MarkData
				{
					EndTime = Time.time + 10f,
					DamageBonus = damageBonus
				};
			}
		}
	}

	public static bool IsMarked(Character target)
	{
		return GetMarkData(target) != null;
	}

	public static float GetDamageBonus(Character target)
	{
		return GetMarkData(target)?.DamageBonus ?? 0f;
	}

	public static float GetRemainingDuration(Character target)
	{
		MarkData markData = GetMarkData(target);
		if (markData == null)
		{
			return 0f;
		}
		return Mathf.Max(0f, markData.EndTime - Time.time);
	}

	private static MarkData GetMarkData(Character target)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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)
		if ((Object)(object)target == (Object)null)
		{
			return null;
		}
		ZDOID zDOID = target.GetZDOID();
		if (zDOID == ZDOID.None)
		{
			return null;
		}
		if (!Marks.TryGetValue(zDOID, out var value))
		{
			return null;
		}
		if (Time.time >= value.EndTime)
		{
			Marks.Remove(zDOID);
			return null;
		}
		return value;
	}

	public static void Clear()
	{
		Marks.Clear();
	}
}
[BepInPlugin("com.jongr.jgrpg", "JGRPG", "0.1.61")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
internal class JGRPG : BaseUnityPlugin
{
	public const string PluginGUID = "com.jongr.jgrpg";

	public const string PluginName = "JGRPG";

	public const string PluginVersion = "0.1.61";

	private Harmony _harmony;

	internal static ConfigEntry<CharacterClass> SelectedClassConfig;

	internal static ConfigEntry<KeyboardShortcut> TalentMenuKeyConfig;

	internal static ConfigEntry<KeyboardShortcut> Ability1KeyConfig;

	internal static ConfigEntry<KeyboardShortcut> Ability2KeyConfig;

	internal static ConfigEntry<KeyboardShortcut> Ability3KeyConfig;

	internal static ConfigEntry<KeyboardShortcut> Ability4KeyConfig;

	internal static ConfigEntry<KeyboardShortcut> Ability5KeyConfig;

	internal static ConfigEntry<GamepadButton> Ability1GamepadConfig;

	internal static ConfigEntry<GamepadButton> Ability2GamepadConfig;

	internal static ConfigEntry<GamepadButton> Ability3GamepadConfig;

	internal static ConfigEntry<GamepadButton> Ability4GamepadConfig;

	internal static ConfigEntry<GamepadButton> Ability5GamepadConfig;

	internal static ConfigEntry<GamepadButton> AbilityGamepadModifierConfig;

	internal static ConfigEntry<GamepadButton> TalentMenuGamepadConfig;

	internal static ConfigEntry<GamepadButton> TalentNavUpGamepadConfig;

	internal static ConfigEntry<GamepadButton> TalentNavRightGamepadConfig;

	internal static ConfigEntry<GamepadButton> TalentNavDownGamepadConfig;

	internal static ConfigEntry<GamepadButton> TalentNavLeftGamepadConfig;

	private ButtonConfig _ability1Button;

	private ButtonConfig _ability2Button;

	private ButtonConfig _ability3Button;

	private ButtonConfig _ability4Button;

	private ButtonConfig _ability5Button;

	internal static ButtonConfig _abilityGamepadModifierButton;

	private ButtonConfig _talentMenuGamepadButton;

	private ButtonConfig _talentNavUpButton;

	private ButtonConfig _talentNavRightButton;

	private ButtonConfig _talentNavDownButton;

	private ButtonConfig _talentNavLeftButton;

	public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

	private static bool IsTextInputActive()
	{
		if (((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible())
		{
			return true;
		}
		if ((Object)(object)EventSystem.current != (Object)null)
		{
			GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
			if ((Object)(object)currentSelectedGameObject != (Object)null)
			{
				TMP_InputField val = currentSelectedGameObject.GetComponent<TMP_InputField>();
				if ((Object)(object)val == (Object)null)
				{
					val = currentSelectedGameObject.GetComponentInParent<TMP_InputField>();
				}
				if ((Object)(object)val != (Object)null && val.isFocused)
				{
					return true;
				}
			}
		}
		return false;
	}

	private void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Expected O, but got Unknown
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Expected O, but got Unknown
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_033e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0367: Expected O, but got Unknown
		//IL_037d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Expected O, but got Unknown
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03db: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e7: Expected O, but got Unknown
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0401: Unknown result type (might be due to invalid IL or missing references)
		//IL_040c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Expected O, but got Unknown
		//IL_0440: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_045b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0467: Expected O, but got Unknown
		//IL_047d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_048d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a4: Expected O, but got Unknown
		//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e1: Expected O, but got Unknown
		//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0507: Unknown result type (might be due to invalid IL or missing references)
		//IL_0512: Unknown result type (might be due to invalid IL or missing references)
		//IL_051e: Expected O, but got Unknown
		//IL_0534: Unknown result type (might be due to invalid IL or missing references)
		//IL_0539: Unknown result type (might be due to invalid IL or missing references)
		//IL_0544: Unknown result type (might be due to invalid IL or missing references)
		//IL_054f: Unknown result type (might be due to invalid IL or missing references)
		//IL_055b: Expected O, but got Unknown
		//IL_058a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0594: Expected O, but got Unknown
		SelectedClassConfig = ((BaseUnityPlugin)this).Config.Bind<CharacterClass>("Character", "SelectedClass", CharacterClass.None, "Class to select for the current character when no class has been chosen yet.");
		TalentMenuKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "TalentMenu", new KeyboardShortcut((KeyCode)117, Array.Empty<KeyCode>()), "Key used to open and close the JGRPG talent tree.");
		Ability1KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability1", new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 1.");
		Ability2KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability2", new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 2.");
		Ability3KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability3", new KeyboardShortcut((KeyCode)51, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 3.");
		Ability4KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability4", new KeyboardShortcut((KeyCode)52, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 4.");
		Ability5KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability5", new KeyboardShortcut((KeyCode)53, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 5.");
		Ability1GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability1Gamepad", (GamepadButton)1, "Gamepad button used for class ability 1.");
		Ability2GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability2Gamepad", (GamepadButton)4, "Gamepad button used for class ability 2.");
		Ability3GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability3Gamepad", (GamepadButton)2, "Gamepad button used for class ability 3.");
		Ability4GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability4Gamepad", (GamepadButton)3, "Gamepad button used for class ability 4.");
		Ability5GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability5Gamepad", (GamepadButton)5, "Gamepad button used for class ability 5.");
		AbilityGamepadModifierConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "AbilityGamepadModifier", (GamepadButton)9, "Gamepad modifier held while pressing a class ability button.");
		TalentMenuGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentMenuGamepad", (GamepadButton)8, "Gamepad button used with the gamepad modifier to open and close the JGRPG talent tree.");
		TalentNavUpGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavUpGamepad", (GamepadButton)1, "Gamepad button used to navigate up in the JGRPG talent tree.");
		TalentNavRightGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavRightGamepad", (GamepadButton)4, "Gamepad button used to navigate right in the JGRPG talent tree.");
		TalentNavDownGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavDownGamepad", (GamepadButton)2, "Gamepad button used to navigate down in the JGRPG talent tree.");
		TalentNavLeftGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavLeftGamepad", (GamepadButton)3, "Gamepad button used to navigate left in the JGRPG talent tree.");
		_talentNavUpButton = new ButtonConfig
		{
			Name = "JGRPG_TalentNavUp",
			GamepadConfig = TalentNavUpGamepadConfig,
			BlockOtherInputs = true,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavUpButton);
		_talentNavRightButton = new ButtonConfig
		{
			Name = "JGRPG_TalentNavRight",
			GamepadConfig = TalentNavRightGamepadConfig,
			BlockOtherInputs = true,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavRightButton);
		_talentNavDownButton = new ButtonConfig
		{
			Name = "JGRPG_TalentNavDown",
			GamepadConfig = TalentNavDownGamepadConfig,
			BlockOtherInputs = true,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavDownButton);
		_talentNavLeftButton = new ButtonConfig
		{
			Name = "JGRPG_TalentNavLeft",
			GamepadConfig = TalentNavLeftGamepadConfig,
			BlockOtherInputs = true,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavLeftButton);
		_abilityGamepadModifierButton = new ButtonConfig
		{
			Name = "JGRPG_AbilityModifier",
			GamepadConfig = AbilityGamepadModifierConfig,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _abilityGamepadModifierButton);
		_talentMenuGamepadButton = new ButtonConfig
		{
			Name = "JGRPG_TalentMenu",
			GamepadConfig = TalentMenuGamepadConfig,
			BlockOtherInputs = true,
			ActiveInCustomGUI = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _talentMenuGamepadButton);
		_ability1Button = new ButtonConfig
		{
			Name = "JGRPG_Ability1",
			GamepadConfig = Ability1GamepadConfig,
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _ability1Button);
		_ability2Button = new ButtonConfig
		{
			Name = "JGRPG_Ability2",
			GamepadConfig = Ability2GamepadConfig,
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _ability2Button);
		_ability3Button = new ButtonConfig
		{
			Name = "JGRPG_Ability3",
			GamepadConfig = Ability3GamepadConfig,
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _ability3Button);
		_ability4Button = new ButtonConfig
		{
			Name = "JGRPG_Ability4",
			GamepadConfig = Ability4GamepadConfig,
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _ability4Button);
		_ability5Button = new ButtonConfig
		{
			Name = "JGRPG_Ability5",
			GamepadConfig = Ability5GamepadConfig,
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.jongr.jgrpg", _ability5Button);
		WorldProgressionNetwork.Register();
		TalentUI.Register();
		AbilityHUD.Register();
		AbilityBuffStatusEffects.Register();
		_harmony = new Harmony("com.jongr.jgrpg");
		_harmony.PatchAll();
		Logger.LogInfo((object)"JGRPG has loaded");
	}

	private void Update()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		if (TalentUI.IsOpen && Input.GetKeyDown((KeyCode)27))
		{
			TalentUI.Toggle();
		}
		else
		{
			if (IsTextInputActive() && !TalentUI.IsOpen)
			{
				return;
			}
			KeyboardShortcut value;
			if (TalentMenuKeyConfig != null)
			{
				value = TalentMenuKeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					TalentUI.Toggle();
				}
			}
			if (ZInput.instance != null && _abilityGamepadModifierButton != null && _talentMenuGamepadButton != null && ZInput.GetButton(_abilityGamepadModifierButton.Name) && ZInput.GetButtonDown(_talentMenuGamepadButton.Name))
			{
				TalentUI.Toggle();
				return;
			}
			if (TalentUI.IsOpen)
			{
				if (_talentNavUpButton != null && ZInput.GetButtonDown(_talentNavUpButton.Name))
				{
					TalentUI.NavigateSelection(0, 1);
				}
				else if (_talentNavRightButton != null && ZInput.GetButtonDown(_talentNavRightButton.Name))
				{
					TalentUI.NavigateSelection(1, 0);
				}
				else if (_talentNavDownButton != null && ZInput.GetButtonDown(_talentNavDownButton.Name))
				{
					TalentUI.NavigateSelection(0, -1);
				}
				else if (_talentNavLeftButton != null && ZInput.GetButtonDown(_talentNavLeftButton.Name))
				{
					TalentUI.NavigateSelection(-1, 0);
				}
				return;
			}
			if (Ability1KeyConfig != null)
			{
				value = Ability1KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ClassAbilityManager.TryActivate(1);
				}
			}
			if (Ability2KeyConfig != null)
			{
				value = Ability2KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ClassAbilityManager.TryActivate(2);
				}
			}
			if (Ability3KeyConfig != null)
			{
				value = Ability3KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ClassAbilityManager.TryActivate(3);
				}
			}
			if (Ability4KeyConfig != null)
			{
				value = Ability4KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ClassAbilityManager.TryActivate(4);
				}
			}
			if (Ability5KeyConfig != null)
			{
				value = Ability5KeyConfig.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ClassAbilityManager.TryActivate(5);
				}
			}
			if (ZInput.instance != null && _abilityGamepadModifierButton != null && ZInput.GetButton(_abilityGamepadModifierButton.Name))
			{
				if (_ability1Button != null && ZInput.GetButtonDown(_ability1Button.Name))
				{
					ClassAbilityManager.TryActivate(1);
				}
				if (_ability2Button != null && ZInput.GetButtonDown(_ability2Button.Name))
				{
					ClassAbilityManager.TryActivate(2);
				}
				if (_ability3Button != null && ZInput.GetButtonDown(_ability3Button.Name))
				{
					ClassAbilityManager.TryActivate(3);
				}
				if (_ability4Button != null && ZInput.GetButtonDown(_ability4Button.Name))
				{
					ClassAbilityManager.TryActivate(4);
				}
				if (_ability5Button != null && ZInput.GetButtonDown(_ability5Button.Name))
				{
					ClassAbilityManager.TryActivate(5);
				}
			}
		}
	}
}
internal static class LevelRequirements
{
	public static readonly int[] XPToNextLevel = new int[91]
	{
		0, 80, 87, 95, 103, 111, 119, 127, 135, 143,
		500, 1587, 1746, 1905, 2064, 2222, 2381, 2540, 2698, 2857,
		2500, 2381, 2619, 2857, 3095, 3333, 3571, 3810, 4048, 4286,
		5000, 1984, 2183, 2381, 2579, 2778, 2976, 3175, 3373, 3571,
		7500, 3968, 4365, 4762, 5159, 5556, 5952, 6349, 6746, 7143,
		40000, 6349, 6984, 7619, 8254, 8889, 9524, 10159, 10794, 11428,
		12500, 7937, 8730, 9524, 10317, 11111, 11905, 12698, 13492, 14286,
		25000, 4155, 4571, 4986, 5402, 5817, 6233, 6648, 7064, 7479,
		7895, 8310, 8726, 9141, 9557, 9972, 10388, 10803, 11219, 11634,
		0
	};
}
[HarmonyPatch(typeof(Character), "RPC_Damage")]
internal static class PlayerKillPatch
{
	[HarmonyPrefix]
	private static void Prefix(Character __instance, ref bool __state)
	{
		__state = (Object)(object)__instance != (Object)null && __instance.GetHealth() > 0f;
	}

	[HarmonyPostfix]
	private static void Postfix(Character __instance, HitData hit, bool __state)
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner() || !__state || __insta