Decompiled source of WaysOfTheGods v1.0.1

WaysOfTheGods.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("WaysOfTheGods")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("WaysOfTheGods")]
[assembly: AssemblyTitle("WaysOfTheGods")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ClassiDiValheim
{
	public class SpellDef
	{
		public string Name;

		public int UnlockLevel;

		public float Cooldown;

		public float StaminaCost;

		public string IconItem;

		public Action<Player, int> CastAction;

		public Func<int, string> Describe;
	}
	public static class Abilities
	{
		private static readonly Dictionary<string, float> CooldownEnd = new Dictionary<string, float>();

		public static bool DebugUnlockAll;

		public static readonly SpellDef[] MageSpells = new SpellDef[8]
		{
			new SpellDef
			{
				Name = "Fireball",
				UnlockLevel = 10,
				Cooldown = 6f,
				StaminaCost = 20f,
				IconItem = "StaffFireball",
				CastAction = CastFireball,
				Describe = (int lvl) => $"Hurl a fireball ({FireballDamage(lvl)} damage)"
			},
			new SpellDef
			{
				Name = "Frost Nova",
				UnlockLevel = 20,
				Cooldown = 15f,
				StaminaCost = 30f,
				IconItem = "FreezeGland",
				CastAction = CastFrostNova,
				Describe = (int lvl) => $"Explosion of frost around you ({FrostNovaDamage(lvl)} damage, 8 m)"
			},
			new SpellDef
			{
				Name = "Ice Shards",
				UnlockLevel = 30,
				Cooldown = 10f,
				StaminaCost = 30f,
				IconItem = "StaffIceShards",
				CastAction = CastIceShards,
				Describe = (int lvl) => $"Fan of 5 freezing shards ({IceShardDamage(lvl)} damage each)"
			},
			new SpellDef
			{
				Name = "Lightning Bolt",
				UnlockLevel = 40,
				Cooldown = 12f,
				StaminaCost = 35f,
				IconItem = "StaffLightning",
				CastAction = CastLightningBolt,
				Describe = (int lvl) => $"Crackling projectile ({LightningBoltDamage(lvl)} damage)"
			},
			new SpellDef
			{
				Name = "Ring of Fire",
				UnlockLevel = 50,
				Cooldown = 20f,
				StaminaCost = 45f,
				IconItem = "SurtlingCore",
				CastAction = CastRingOfFire,
				Describe = (int lvl) => $"12 fireballs in every direction ({RingFireDamage(lvl)} damage each)"
			},
			new SpellDef
			{
				Name = "Rune Shield",
				UnlockLevel = 60,
				Cooldown = 60f,
				StaminaCost = 40f,
				IconItem = "StaffShield",
				CastAction = CastRuneShield,
				Describe = (int lvl) => "Protective dome (8 m, 20 s): armors whoever is inside, dissolves projectiles and repels enemies"
			},
			new SpellDef
			{
				Name = "Lightning Storm",
				UnlockLevel = 70,
				Cooldown = 30f,
				StaminaCost = 60f,
				IconItem = "Thunderstone",
				CastAction = CastLightningStorm,
				Describe = (int lvl) => $"8 bolts strike nearby enemies ({StormBoltDamage(lvl)} damage each)"
			},
			new SpellDef
			{
				Name = "Wrath of the Gods",
				UnlockLevel = 80,
				Cooldown = 60f,
				StaminaCost = 80f,
				IconItem = "GoblinTotem",
				CastAction = CastWrathOfTheGods,
				Describe = (int lvl) => $"Meteor rain in front of you ({MeteorDamage(lvl)} damage each)"
			}
		};

		public static readonly SpellDef[] BerserkerSpells = new SpellDef[8]
		{
			new SpellDef
			{
				Name = "War Cry",
				UnlockLevel = 10,
				Cooldown = 10f,
				StaminaCost = 15f,
				IconItem = "Club",
				CastAction = CastWarCry,
				Describe = (int lvl) => $"Repels and damages nearby enemies ({WarCryDamage(lvl)} damage, 6 m)"
			},
			new SpellDef
			{
				Name = "Charge",
				UnlockLevel = 20,
				Cooldown = 8f,
				StaminaCost = 20f,
				IconItem = "ShieldWood",
				CastAction = CastCharge,
				Describe = (int lvl) => $"Forward dash that tramples enemies ({ChargeDamage(lvl)} damage)"
			},
			new SpellDef
			{
				Name = "Spear Throw",
				UnlockLevel = 30,
				Cooldown = 6f,
				StaminaCost = 20f,
				IconItem = "SpearBronze",
				CastAction = CastSpearThrow,
				Describe = (int lvl) => $"Hurl an ancient spear ({SpearDamage(lvl)} damage)"
			},
			new SpellDef
			{
				Name = "Seismic Blow",
				UnlockLevel = 40,
				Cooldown = 15f,
				StaminaCost = 30f,
				IconItem = "SledgeIron",
				CastAction = CastSeismicBlow,
				Describe = (int lvl) => $"Make the earth tremble ({SeismicDamage(lvl)} damage, 8 m)"
			},
			new SpellDef
			{
				Name = "Berserker Fury",
				UnlockLevel = 50,
				Cooldown = 45f,
				StaminaCost = 30f,
				IconItem = "TrophyWolf",
				CastAction = CastFury,
				Describe = (int lvl) => "+40% damage and nearly free attacks for 15 seconds"
			},
			new SpellDef
			{
				Name = "Iron Skin",
				UnlockLevel = 60,
				Cooldown = 60f,
				StaminaCost = 30f,
				IconItem = "ArmorIronChest",
				CastAction = CastIronSkin,
				Describe = (int lvl) => "Your skin turns to iron: massive defense for 20 seconds"
			},
			new SpellDef
			{
				Name = "Whirlwind",
				UnlockLevel = 70,
				Cooldown = 25f,
				StaminaCost = 45f,
				IconItem = "SwordIron",
				CastAction = CastWhirlwind,
				Describe = (int lvl) => $"Spinning blades for 3 seconds ({WhirlwindDamage(lvl)} damage per hit, 4 m)"
			},
			new SpellDef
			{
				Name = "Titanic Slam",
				UnlockLevel = 80,
				Cooldown = 60f,
				StaminaCost = 60f,
				IconItem = "SledgeDemolisher",
				CastAction = CastTitanicSlam,
				Describe = (int lvl) => $"Leap skyward and crash down ({SlamDamage(lvl)} damage, 10 m)"
			}
		};

		public static readonly SpellDef[] NecromancerSpells = new SpellDef[8]
		{
			new SpellDef
			{
				Name = "Life Drain",
				UnlockLevel = 10,
				Cooldown = 8f,
				StaminaCost = 20f,
				IconItem = "Bloodbag",
				CastAction = CastLifeDrain,
				Describe = (int lvl) => $"Drain the life of nearby enemies ({DrainDamage(lvl)} damage, heals you per enemy hit)"
			},
			new SpellDef
			{
				Name = "Summon Skeleton",
				UnlockLevel = 20,
				Cooldown = 10f,
				StaminaCost = 30f,
				IconItem = "TrophySkeleton",
				CastAction = CastSummonSkeleton,
				Describe = (int lvl) => $"Raise a skeleton that fights for you (max {MaxSkeletons(lvl)})"
			},
			new SpellDef
			{
				Name = "Ooze Bomb",
				UnlockLevel = 30,
				Cooldown = 8f,
				StaminaCost = 25f,
				IconItem = "Ooze",
				CastAction = CastOozeBomb,
				Describe = (int lvl) => $"Throw a bomb that bursts into a poison cloud ({OozeDamage(lvl)} poison damage)"
			},
			new SpellDef
			{
				Name = "Toxic Cloud",
				UnlockLevel = 40,
				Cooldown = 20f,
				StaminaCost = 40f,
				IconItem = "Guck",
				CastAction = CastToxicCloud,
				Describe = (int lvl) => $"Bonemass miasma in front of you: 6 waves of poison ({ToxicTickDamage(lvl)} damage each, 6 m)"
			},
			new SpellDef
			{
				Name = "Spectral Wave",
				UnlockLevel = 50,
				Cooldown = 18f,
				StaminaCost = 45f,
				IconItem = "Entrails",
				CastAction = CastSpectralWave,
				Describe = (int lvl) => $"Wave of spirits that rends and repels ({SpectralDamage(lvl)} damage, 8 m)"
			},
			new SpellDef
			{
				Name = "Bone Armor",
				UnlockLevel = 60,
				Cooldown = 60f,
				StaminaCost = 30f,
				IconItem = "BoneFragments",
				CastAction = CastBoneArmor,
				Describe = (int lvl) => "Ancient bones armor you for 20 seconds"
			},
			new SpellDef
			{
				Name = "Putrid Rain",
				UnlockLevel = 70,
				Cooldown = 30f,
				StaminaCost = 60f,
				IconItem = "BombOoze",
				CastAction = CastPutridRain,
				Describe = (int lvl) => $"8 ooze bombs rain down in front of you ({OozeDamage(lvl)} poison damage each)"
			},
			new SpellDef
			{
				Name = "Army of the Dead",
				UnlockLevel = 80,
				Cooldown = 90f,
				StaminaCost = 80f,
				IconItem = "TrophyDraugrElite",
				CastAction = CastArmyOfTheDead,
				Describe = (int lvl) => $"4 skeletons rise from the ground plus a spectral blast ({SpectralDamage(lvl)} damage, 10 m)"
			}
		};

		private static readonly List<Character> Minions = new List<Character>();

		public static SpellDef[] GetSpells(PlayerClass cls)
		{
			return cls switch
			{
				PlayerClass.Mage => MageSpells, 
				PlayerClass.Berserker => BerserkerSpells, 
				PlayerClass.Necromancer => NecromancerSpells, 
				_ => new SpellDef[0], 
			};
		}

		private static int FireballDamage(int lvl)
		{
			return 20 + (int)(1.5f * (float)lvl);
		}

		private static int FrostNovaDamage(int lvl)
		{
			return 15 + (int)(1.2f * (float)lvl);
		}

		private static int IceShardDamage(int lvl)
		{
			return 10 + (int)(0.8f * (float)lvl);
		}

		private static int LightningBoltDamage(int lvl)
		{
			return 30 + 2 * lvl;
		}

		private static int RingFireDamage(int lvl)
		{
			return 15 + lvl;
		}

		private static int StormBoltDamage(int lvl)
		{
			return 25 + (int)(1.5f * (float)lvl);
		}

		private static int MeteorDamage(int lvl)
		{
			return 60 + 2 * lvl;
		}

		private static int WarCryDamage(int lvl)
		{
			return 10 + (int)(0.8f * (float)lvl);
		}

		private static int ChargeDamage(int lvl)
		{
			return 15 + lvl;
		}

		private static int SpearDamage(int lvl)
		{
			return 25 + (int)(1.8f * (float)lvl);
		}

		private static int SeismicDamage(int lvl)
		{
			return 30 + (int)(1.6f * (float)lvl);
		}

		private static int WhirlwindDamage(int lvl)
		{
			return 12 + lvl;
		}

		private static int SlamDamage(int lvl)
		{
			return 50 + 2 * lvl;
		}

		private static int DrainDamage(int lvl)
		{
			return 12 + lvl;
		}

		private static int DrainHeal(int lvl)
		{
			return 5 + (int)(0.3f * (float)lvl);
		}

		private static int OozeDamage(int lvl)
		{
			return 20 + (int)(1.5f * (float)lvl);
		}

		private static int ToxicTickDamage(int lvl)
		{
			return 8 + (int)(0.6f * (float)lvl);
		}

		private static int SpectralDamage(int lvl)
		{
			return 20 + (int)(1.5f * (float)lvl);
		}

		private static int MaxSkeletons(int lvl)
		{
			return Mathf.Clamp(1 + lvl / 20, 1, 5);
		}

		public static IEnumerable<string> GetUnlockedAt(PlayerClass cls, int level)
		{
			return from s in GetSpells(cls)
				where s.UnlockLevel == level
				select s.Name;
		}

		public static float GetCooldownRemaining(string spellName)
		{
			float value;
			return CooldownEnd.TryGetValue(spellName, out value) ? Mathf.Max(0f, value - Time.time) : 0f;
		}

		public static bool IsUnlocked(Player player, SpellDef spell)
		{
			int num = (DebugUnlockAll ? 80 : ClassSystem.GetLevel(player));
			return num >= spell.UnlockLevel;
		}

		public static void CastSpell(Player player, int index)
		{
			SpellDef[] spells = GetSpells(ClassSystem.GetClass(player));
			if (index < 0 || index >= spells.Length)
			{
				return;
			}
			SpellDef spellDef = spells[index];
			int level = ClassSystem.GetLevel(player);
			if (!IsUnlocked(player, spellDef))
			{
				((Character)player).Message((MessageType)1, $"{spellDef.Name} unlocks at level {spellDef.UnlockLevel}", 0, (Sprite)null);
				return;
			}
			float cooldownRemaining = GetCooldownRemaining(spellDef.Name);
			if (cooldownRemaining > 0f)
			{
				((Character)player).Message((MessageType)1, $"{spellDef.Name} on cooldown ({cooldownRemaining:0}s)", 0, (Sprite)null);
				return;
			}
			if (!((Character)player).HaveStamina(spellDef.StaminaCost))
			{
				((Character)player).Message((MessageType)1, "Not enough stamina", 0, (Sprite)null);
				return;
			}
			((Character)player).UseStamina(spellDef.StaminaCost);
			spellDef.CastAction(player, level);
			CooldownEnd[spellDef.Name] = Time.time + spellDef.Cooldown;
		}

		private static void CastFireball(Player player, int level)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "throw_bomb", "throw", "spear_throw", "staff_fireball0", "gpower");
			HitData val = new HitData();
			val.m_damage.m_fire = FireballDamage(level);
			val.m_pushForce = 40f;
			val.SetAttacker((Character)(object)player);
			LaunchProjectile(player, "Imp_fireball_projectile", AimDirection(player), 25f, val);
			Effects.TryPlayAt(EyePosition(player), "sfx_imp_fireball_launch");
		}

		private static void CastFrostNova(Player player, int level)
		{
			//IL_002a: 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)
			Effects.TryCastAnimation(player, "gpower");
			int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit)
			{
				hit.m_damage.m_frost = FrostNovaDamage(level);
			}, 80f, new string[1] { "fx_iceshard_hit" });
			Effects.TryPlayAt(((Component)player).transform.position, "fx_fenring_icenova");
			((Character)player).Message((MessageType)1, (num > 0) ? $"Frost Nova: {num} enemies hit" : "Frost Nova: no enemies in range", 0, (Sprite)null);
		}

		private static void CastIceShards(Player player, int level)
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "staff_rapidfire", "gpower");
			Vector3 val = AimDirection(player);
			float[] array = new float[5] { -20f, -10f, 0f, 10f, 20f };
			foreach (float num in array)
			{
				Vector3 dir = Quaternion.AngleAxis(num, Vector3.up) * val;
				HitData val2 = new HitData();
				val2.m_damage.m_frost = IceShardDamage(level);
				val2.m_pushForce = 20f;
				val2.SetAttacker((Character)(object)player);
				LaunchProjectile(player, "staff_iceshard_projectile", dir, 30f, val2);
			}
			Effects.TryPlayAt(EyePosition(player), "fx_iceshard_launch");
		}

		private static void CastLightningBolt(Player player, int level)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0050: 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)
			Effects.TryCastAnimation(player, "staff_lightningshot", "gpower");
			HitData val = new HitData();
			val.m_damage.m_lightning = LightningBoltDamage(level);
			val.m_pushForce = 60f;
			val.SetAttacker((Character)(object)player);
			LaunchProjectile(player, "staff_lightning_projectile", AimDirection(player), 35f, val);
			Effects.TryPlayAt(EyePosition(player), "vfx_lightningstaff_fire");
		}

		private static void CastRingOfFire(Player player, int level)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "gpower");
			for (int i = 0; i < 12; i++)
			{
				Vector3 dir = Quaternion.AngleAxis((float)i * 30f, Vector3.up) * ((Component)player).transform.forward;
				HitData val = new HitData();
				val.m_damage.m_fire = RingFireDamage(level);
				val.m_pushForce = 40f;
				val.SetAttacker((Character)(object)player);
				LaunchProjectile(player, "Imp_fireball_projectile", dir, 20f, val);
			}
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_imp_fireball_launch");
		}

		private static void CastRuneShield(Player player, int level)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0035: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "staff_shield", "gpower");
			Vector3 position = ((Component)player).transform.position;
			GameObject val = new GameObject("cdv_rune_dome");
			val.transform.position = position;
			RuneDome runeDome = val.AddComponent<RuneDome>();
			runeDome.Owner = player;
			runeDome.Radius = 8f;
			runeDome.EndTime = Time.time + 20f;
			GameObject val2 = Effects.FindPrefab("vfx_StaffShield");
			if ((Object)(object)val2 != (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(val2, position, Quaternion.identity, val.transform);
				MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val4 in componentsInChildren)
				{
					Object.DestroyImmediate((Object)(object)val4);
				}
				val3.transform.localScale = Vector3.one * 5.6f;
			}
			Effects.TryPlayAt(position, 4f, "fx_StaffShield_Hit");
		}

		private static void CastLightningStorm(Player player, int level)
		{
			Effects.TryCastAnimation(player, "staff_summon", "gpower");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(LightningStorm(player, level));
		}

		private static IEnumerator LightningStorm(Player player, int level)
		{
			for (int i = 0; i < 8; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				List<Character> enemies = EnemiesAround(((Component)player).transform.position, 12f);
				Vector3 point;
				if (enemies.Count > 0)
				{
					point = ((Component)enemies[Random.Range(0, enemies.Count)]).transform.position;
				}
				else
				{
					Vector2 offset = Random.insideUnitCircle * 8f;
					point = ((Component)player).transform.position + new Vector3(offset.x, 0f, offset.y);
				}
				SpawnLightningBolt(player, point, level);
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		private static void SpawnLightningBolt(Player player, Vector3 point, int level)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Effects.FindPrefab("lightningAOE");
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, point, Quaternion.identity);
				Aoe[] componentsInChildren = val2.GetComponentsInChildren<Aoe>(true);
				foreach (Aoe val3 in componentsInChildren)
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
				Object.Destroy((Object)(object)val2, 4f);
			}
			Effects.TryPlayAt(point, 6f, "sfx_thunder");
			DamageEnemiesAround(player, point, 3f, delegate(HitData hit)
			{
				hit.m_damage.m_lightning = StormBoltDamage(level);
			}, 60f, null);
		}

		private static void CastWrathOfTheGods(Player player, int level)
		{
			Effects.TryCastAnimation(player, "gpower");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(MeteorRain(player, level));
		}

		private static IEnumerator MeteorRain(Player player, int level)
		{
			Vector3 center = ((Component)player).transform.position + ((Component)player).transform.forward * 8f;
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_fader_meteor_start");
			for (int i = 0; i < 10; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				Vector2 offset = Random.insideUnitCircle * 6f;
				Vector3 target = center + new Vector3(offset.x, 0f, offset.y);
				Vector2 lateral = Random.insideUnitCircle * 3f;
				Vector3 spawn = target + new Vector3(lateral.x, 22f, lateral.y);
				Vector3 val = target - spawn;
				Vector3 dir = ((Vector3)(ref val)).normalized;
				HitData hit = new HitData();
				hit.m_damage.m_fire = MeteorDamage(level);
				hit.m_damage.m_blunt = 20f;
				hit.m_pushForce = 100f;
				hit.SetAttacker((Character)(object)player);
				GameObject prefab = Effects.FindPrefab("projectile_meteor", "projectile_meteor_fader");
				if ((Object)(object)prefab != (Object)null)
				{
					GameObject go = Object.Instantiate<GameObject>(prefab, spawn, Quaternion.LookRotation(dir));
					SetupProjectile(go, player, dir * 28f, hit);
				}
				yield return (object)new WaitForSeconds(0.35f);
			}
		}

		private static void CastWarCry(Player player, int level)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "emote_challenge", "challenge", "gpower");
			int num = DamageEnemiesAround(player, ((Component)player).transform.position, 6f, delegate(HitData hit)
			{
				hit.m_damage.m_blunt = WarCryDamage(level);
			}, 150f, new string[1] { "vfx_clubhit" });
			Effects.TryPlayAt(((Component)player).transform.position, "fx_eikthyr_stomp");
			((Character)player).Message((MessageType)1, (num > 0) ? $"War Cry: {num} enemies repelled" : "War Cry: no enemies in range", 0, (Sprite)null);
		}

		private static void CastCharge(Player player, int level)
		{
			Effects.TryCastAnimation(player, "sword_secondary", "unarmed_kick");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(ChargeDash(player, level));
		}

		private static IEnumerator ChargeDash(Player player, int level)
		{
			Vector3 dir = ((Component)player).transform.forward;
			dir.y = 0f;
			dir = ((Vector3)(ref dir)).normalized;
			HashSet<Character> alreadyHit = new HashSet<Character>();
			float end = Time.time + 0.5f;
			bool first = true;
			while (Time.time < end && (Object)(object)player != (Object)null && !((Character)player).IsDead())
			{
				yield return (object)new WaitForFixedUpdate();
				if ((Object)(object)player == (Object)null || ((Character)player).IsDead())
				{
					yield break;
				}
				Vector3 velocity = dir * 16f;
				velocity.y = (first ? 3f : ((Character)player).m_body.linearVelocity.y);
				((Character)player).m_body.linearVelocity = velocity;
				((Character)player).m_body.MovePosition(((Character)player).m_body.position + dir * 16f * Time.fixedDeltaTime);
				((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
				first = false;
				foreach (Character enemy in EnemiesAround(((Component)player).transform.position, 2.5f))
				{
					if (alreadyHit.Add(enemy))
					{
						HitData hit = new HitData();
						hit.m_damage.m_blunt = ChargeDamage(level);
						hit.m_pushForce = 90f;
						hit.m_point = ((Component)enemy).transform.position;
						hit.m_dir = dir;
						hit.SetAttacker((Character)(object)player);
						enemy.Damage(hit);
						Effects.TryPlayAt(((Component)enemy).transform.position + Vector3.up, "vfx_HitSparks");
					}
				}
			}
			if (!((Object)(object)player == (Object)null) && !((Character)player).IsDead())
			{
				Effects.TryCastAnimation(player, "sword_secondary", "unarmed_kick");
				Vector3 finisherCenter = ((Component)player).transform.position + dir * 1.5f;
				int finisherHits = DamageEnemiesAround(player, finisherCenter, 2.5f, delegate(HitData val)
				{
					val.m_damage.m_blunt = (float)ChargeDamage(level) * 1.5f;
				}, 120f, new string[1] { "vfx_clubhit" });
				if (finisherHits > 0)
				{
					((Character)player).Message((MessageType)1, $"Charge: finishing blow on {finisherHits} enemies", 0, (Sprite)null);
				}
			}
		}

		private static void CastSpearThrow(Player player, int level)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "spear_throw", "throw", "swing_longsword0");
			HitData val = new HitData();
			val.m_damage.m_pierce = SpearDamage(level);
			val.m_pushForce = 60f;
			val.SetAttacker((Character)(object)player);
			LaunchProjectile(player, "ancientbarkspear_projectile", AimDirection(player), 32f, val, "bronzespear_projectile");
		}

		private static void CastSeismicBlow(Player player, int level)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "swing_sledge", "battleaxe_attack0", "gpower");
			int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit)
			{
				hit.m_damage.m_blunt = SeismicDamage(level);
			}, 100f, new string[1] { "vfx_clubhit" });
			Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp");
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_gdking_stomp");
			((Character)player).Message((MessageType)1, (num > 0) ? $"Seismic Blow: {num} enemies hit" : "Seismic Blow: no enemies in range", 0, (Sprite)null);
		}

		private static void CastFury(Player player, int level)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "emote_roar", "roar", "emote_challenge");
			PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Furia");
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_trollfire_roar");
		}

		private static void CastIronSkin(Player player, int level)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "emote_flex", "flex", "gpower");
			PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Ferro");
			Effects.TryPlayAt(((Component)player).transform.position, "fx_StaffShield_Hit");
		}

		private static void CastWhirlwind(Player player, int level)
		{
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(Whirlwind(player, level));
		}

		private static IEnumerator Whirlwind(Player player, int level)
		{
			for (int i = 0; i < 6; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				Effects.TryCastAnimation(player, "atgeir_secondary", "battleaxe_attack0", "swing_longsword0", "swing_axe0", "atgeir_attack0", "sword_secondary", "unarmed_attack0");
				DamageEnemiesAround(player, ((Component)player).transform.position, 4f, delegate(HitData hit)
				{
					hit.m_damage.m_slash = WhirlwindDamage(level);
				}, 40f, new string[1] { "vfx_HitSparks" });
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		private static void CastTitanicSlam(Player player, int level)
		{
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(TitanSlam(player, level));
		}

		private static IEnumerator TitanSlam(Player player, int level)
		{
			float launchEnd = Time.time + 0.25f;
			while (Time.time < launchEnd && (Object)(object)player != (Object)null && !((Character)player).IsDead())
			{
				yield return (object)new WaitForFixedUpdate();
				if ((Object)(object)player == (Object)null || ((Character)player).IsDead())
				{
					yield break;
				}
				((Character)player).m_body.linearVelocity = ((Component)player).transform.forward * 6f + Vector3.up * 14f;
				((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
			}
			yield return (object)new WaitForSeconds(0.15f);
			float timeout = Time.time + 3f;
			while (Time.time < timeout && (Object)(object)player != (Object)null && !((Character)player).IsDead() && !((Character)player).IsOnGround())
			{
				((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
				yield return null;
			}
			if (!((Object)(object)player == (Object)null) && !((Character)player).IsDead())
			{
				((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
				int hits = DamageEnemiesAround(player, ((Component)player).transform.position, 10f, delegate(HitData hit)
				{
					hit.m_damage.m_blunt = SlamDamage(level);
				}, 150f, new string[1] { "vfx_clubhit" });
				Effects.TryPlayAt(((Component)player).transform.position, "fx_fader_meteor_hit");
				Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp");
				Effects.TryPlayAt(((Component)player).transform.position, "sfx_gdking_stomp");
				((Character)player).Message((MessageType)1, (hits > 0) ? $"Titanic Slam: {hits} enemies hit" : "Titanic Slam!", 0, (Sprite)null);
			}
		}

		private static void CastLifeDrain(Player player, int level)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "gpower");
			int num = DamageEnemiesAround(player, ((Component)player).transform.position, 6f, delegate(HitData hit)
			{
				hit.m_damage.m_spirit = DrainDamage(level);
			}, 20f, new string[1] { "vfx_HitSparks" });
			if (num > 0)
			{
				((Character)player).Heal((float)(DrainHeal(level) * num), true);
				Effects.TryPlayAt(((Component)player).transform.position, "vfx_Potion_health_medium");
				((Character)player).Message((MessageType)1, $"Life Drain: {num} souls drained", 0, (Sprite)null);
			}
			else
			{
				((Character)player).Message((MessageType)1, "Life Drain: no enemies in range", 0, (Sprite)null);
			}
		}

		private static void CastSummonSkeleton(Player player, int level)
		{
			Effects.TryCastAnimation(player, "staff_summon", "gpower");
			SummonSkeleton(player, level);
		}

		private static void SummonSkeleton(Player player, int level)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003b: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * 2f;
			Vector3 position = ((Component)player).transform.position + new Vector3(val.x, 0.2f, val.y);
			Character val2 = SpawnMinion(player, "Skeleton_Friendly", position);
			if (!((Object)(object)val2 == (Object)null))
			{
				Minions.RemoveAll((Character m) => (Object)(object)m == (Object)null || m.IsDead());
				Minions.Add(val2);
				int num = MaxSkeletons(level);
				while (Minions.Count > num)
				{
					DespawnMinion(Minions[0]);
					Minions.RemoveAt(0);
				}
				Effects.TryPlayAt(position, "fx_summon_skeleton_spawn", "fx_summon_skeleton");
				Effects.TryPlayAt(position, "sfx_skull_summon_skeleton");
			}
		}

		private static void CastOozeBomb(Player player, int level)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//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_005f: 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)
			Effects.TryCastAnimation(player, "throw_bomb", "spear_throw");
			HitData val = new HitData();
			val.m_damage.m_poison = OozeDamage(level);
			val.m_pushForce = 30f;
			val.SetAttacker((Character)(object)player);
			LaunchProjectile(player, "oozebomb_projectile", AimDirection(player) + Vector3.up * 0.15f, 18f, val);
		}

		private static void CastToxicCloud(Player player, int level)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "gpower");
			Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * 5f;
			Effects.TryPlayAt(val, 10f, "fx_Bonemass_aoe_start");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(ToxicCloud(player, val, level));
		}

		private static IEnumerator ToxicCloud(Player player, Vector3 center, int level)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 6; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				DamageEnemiesAround(player, center, 6f, delegate(HitData hit)
				{
					hit.m_damage.m_poison = ToxicTickDamage(level);
				}, 0f, null);
				yield return (object)new WaitForSeconds(1f);
			}
		}

		private static void CastSpectralWave(Player player, int level)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "staff_summon", "gpower");
			int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit)
			{
				hit.m_damage.m_spirit = SpectralDamage(level);
				hit.m_damage.m_slash = (float)SpectralDamage(level) / 2f;
			}, 120f, new string[2] { "fx_charred_summoned_death", "vfx_HitSparks" });
			Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp");
			((Character)player).Message((MessageType)1, (num > 0) ? $"Spectral Wave: {num} enemies hit" : "Spectral Wave: no enemies in range", 0, (Sprite)null);
		}

		private static void CastBoneArmor(Player player, int level)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "gpower");
			PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Ossa");
			Effects.TryPlayAt(((Component)player).transform.position, "fx_StaffShield_Hit");
		}

		private static void CastPutridRain(Player player, int level)
		{
			Effects.TryCastAnimation(player, "staff_summon", "gpower");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(PutridRain(player, level));
		}

		private static IEnumerator PutridRain(Player player, int level)
		{
			Vector3 center = ((Component)player).transform.position + ((Component)player).transform.forward * 8f;
			for (int i = 0; i < 8; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				Vector2 offset = Random.insideUnitCircle * 5f;
				Vector3 target = center + new Vector3(offset.x, 0f, offset.y);
				Vector2 lateral = Random.insideUnitCircle * 2f;
				Vector3 spawn = target + new Vector3(lateral.x, 18f, lateral.y);
				Vector3 val = target - spawn;
				Vector3 dir = ((Vector3)(ref val)).normalized;
				HitData hit = new HitData();
				hit.m_damage.m_poison = OozeDamage(level);
				hit.m_pushForce = 30f;
				hit.SetAttacker((Character)(object)player);
				GameObject prefab = Effects.FindPrefab("oozebomb_projectile");
				if ((Object)(object)prefab != (Object)null)
				{
					GameObject go = Object.Instantiate<GameObject>(prefab, spawn, Quaternion.LookRotation(dir));
					SetupProjectile(go, player, dir * 20f, hit);
				}
				yield return (object)new WaitForSeconds(0.35f);
			}
		}

		private static void CastArmyOfTheDead(Player player, int level)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Effects.TryCastAnimation(player, "staff_summon", "gpower");
			Effects.TryPlayAt(((Component)player).transform.position, "fx_summon_start");
			((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(DeadArmy(player, level));
			DamageEnemiesAround(player, ((Component)player).transform.position, 10f, delegate(HitData hit)
			{
				hit.m_damage.m_spirit = SpectralDamage(level);
				hit.m_damage.m_slash = (float)SpectralDamage(level) / 2f;
			}, 120f, new string[2] { "fx_charred_summoned_death", "vfx_HitSparks" });
		}

		private static IEnumerator DeadArmy(Player player, int level)
		{
			for (int i = 0; i < 4; i++)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				SummonSkeleton(player, level);
				yield return (object)new WaitForSeconds(0.4f);
			}
		}

		private static Character SpawnMinion(Player player, string prefabName, Vector3 position)
		{
			//IL_0034: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Effects.FindPrefab(prefabName);
			if ((Object)(object)val == (Object)null)
			{
				((Character)player).Message((MessageType)1, "The summon fails... (prefab not found)", 0, (Sprite)null);
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.LookRotation(((Component)player).transform.forward));
			Character component = val2.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_faction = (Faction)0;
				component.SetTamed(true);
			}
			MonsterAI component2 = val2.GetComponent<MonsterAI>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_alertRange = 30f;
				component2.SetFollowTarget(((Component)player).gameObject);
			}
			return component;
		}

		public static void UpdateMinions(Player player)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			Minions.RemoveAll((Character m) => (Object)(object)m == (Object)null || m.IsDead());
			foreach (Character minion in Minions)
			{
				if ((Object)(object)minion == (Object)null || minion.IsDead())
				{
					continue;
				}
				MonsterAI component = ((Component)minion).GetComponent<MonsterAI>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Character targetCreature = component.m_targetCreature;
				if ((Object)(object)targetCreature != (Object)null && !targetCreature.IsDead())
				{
					continue;
				}
				List<Character> list = EnemiesAround(((Component)minion).transform.position, 25f);
				if (list.Count != 0)
				{
					Character targetCreature2 = list.OrderBy((Character e) => Vector3.Distance(((Component)e).transform.position, ((Component)minion).transform.position)).First();
					component.m_targetCreature = targetCreature2;
					((BaseAI)component).SetAlerted(true);
				}
			}
		}

		private static void DespawnMinion(Character minion)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)minion == (Object)null))
			{
				Effects.TryPlayAt(((Component)minion).transform.position, 5f, "fx_charred_summoned_death", "vfx_odin_despawn");
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					ZNetScene.instance.Destroy(((Component)minion).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)minion).gameObject);
				}
			}
		}

		private static Vector3 AimDirection(Player player)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			return ((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : ((Component)player).transform.forward;
		}

		private static Vector3 EyePosition(Player player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)player).transform.position + Vector3.up * 1.6f;
		}

		private static void LaunchProjectile(Player player, string prefabName, Vector3 dir, float speed, HitData hit, params string[] fallbackNames)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_006a: 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)
			List<string> list = new List<string> { prefabName };
			list.AddRange(fallbackNames);
			GameObject val = Effects.FindPrefab(list.ToArray());
			if ((Object)(object)val == (Object)null)
			{
				((Character)player).Message((MessageType)1, "The ability fails... (prefab not found)", 0, (Sprite)null);
				return;
			}
			Vector3 val2 = EyePosition(player) + dir * 0.7f;
			GameObject go = Object.Instantiate<GameObject>(val, val2, Quaternion.LookRotation(dir));
			SetupProjectile(go, player, dir * speed, hit);
		}

		private static List<Character> EnemiesAround(Vector3 center, float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return (from c in Character.GetAllCharacters()
				where (Object)(object)c != (Object)null && !c.IsPlayer() && !c.IsTamed() && !c.IsDead() && (int)c.GetFaction() != 0 && Vector3.Distance(center, ((Component)c).transform.position) <= radius
				select c).ToList();
		}

		private static int DamageEnemiesAround(Player player, Vector3 center, float radius, Action<HitData> setDamage, float pushForce, string[] perTargetVfx)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (Character item in EnemiesAround(center, radius))
			{
				HitData val = new HitData();
				setDamage(val);
				val.m_pushForce = pushForce;
				val.m_point = ((Component)item).transform.position;
				Vector3 val2 = ((Component)item).transform.position - center;
				val.m_dir = ((Vector3)(ref val2)).normalized;
				val.SetAttacker((Character)(object)player);
				item.Damage(val);
				if (perTargetVfx != null)
				{
					Effects.TryPlayAt(((Component)item).transform.position + Vector3.up, perTargetVfx);
				}
				num++;
			}
			return num;
		}

		private static void SetupProjectile(GameObject go, Player owner, Vector3 velocity, HitData hit)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			Projectile component = go.GetComponent<Projectile>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			MethodInfo methodInfo = typeof(Projectile).GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.Name == "Setup");
			if (methodInfo == null)
			{
				Logger.LogWarning((object)"Projectile.Setup not found");
				return;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			object[] array = new object[parameters.Length];
			for (int num = 0; num < parameters.Length; num++)
			{
				Type parameterType = parameters[num].ParameterType;
				if (typeof(Character).IsAssignableFrom(parameterType))
				{
					array[num] = owner;
				}
				else if (parameterType == typeof(Vector3))
				{
					array[num] = velocity;
				}
				else if (parameterType == typeof(HitData))
				{
					array[num] = hit;
				}
				else if (parameterType == typeof(float))
				{
					array[num] = (parameters[num].Name.ToLowerInvariant().Contains("noise") ? 10f : 1f);
				}
				else
				{
					array[num] = (parameterType.IsValueType ? Activator.CreateInstance(parameterType) : null);
				}
			}
			methodInfo.Invoke(component, array);
		}
	}
	public static class ClassGUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Close;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__13_0;

			public static UnityAction <>9__13_1;

			public static UnityAction <>9__13_2;

			public static UnityAction <>9__14_0;

			public static UnityAction <>9__14_1;

			public static UnityAction <>9__14_2;

			internal void <BuildClassSelection>b__13_0()
			{
				ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Mage);
				Rebuild();
			}

			internal void <BuildClassSelection>b__13_1()
			{
				ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Berserker);
				Rebuild();
			}

			internal void <BuildClassSelection>b__13_2()
			{
				ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Necromancer);
				Rebuild();
			}

			internal void <BuildClassInfo>b__14_0()
			{
				OfferTrophy(Player.m_localPlayer);
				Rebuild();
			}

			internal void <BuildClassInfo>b__14_1()
			{
				OfferCoins(Player.m_localPlayer);
				Rebuild();
			}

			internal void <BuildClassInfo>b__14_2()
			{
				ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.None);
				Rebuild();
			}
		}

		private const int TrophyXp = 50;

		private const int BossTrophyXp = 500;

		private const int CoinsPerOffer = 10;

		private const int CoinsXp = 20;

		private static readonly HashSet<string> BossTrophyTokens = new HashSet<string> { "$item_trophy_eikthyr", "$item_trophy_theelder", "$item_trophy_bonemass", "$item_trophy_dragonqueen", "$item_trophy_goblinking", "$item_trophy_seekerqueen", "$item_trophy_fader" };

		private static GameObject _panel;

		public static bool IsOpen => (Object)(object)_panel != (Object)null;

		public static void Toggle()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		public static void Open()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null))
			{
				Build(localPlayer);
				GUIManager.BlockInput(true);
			}
		}

		public static void Close()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
				_panel = null;
			}
			GUIManager.BlockInput(false);
		}

		private static void Rebuild()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
				_panel = null;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				Build(localPlayer);
			}
		}

		private static void Build(Player player)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 700f, 620f, false);
			AddLine("Temple of Classes", -45f, 28, GUIManager.Instance.ValheimOrange, 44f);
			if (ClassSystem.GetClass(player) == PlayerClass.None)
			{
				BuildClassSelection();
			}
			else
			{
				BuildClassInfo(player);
			}
			Vector2 position = new Vector2(0f, 30f);
			object obj = <>O.<0>__Close;
			if (obj == null)
			{
				UnityAction val = Close;
				<>O.<0>__Close = val;
				obj = (object)val;
			}
			AddButton("Close", position, 160f, 40f, (UnityAction)obj, anchorBottom: true);
		}

		private static void BuildClassSelection()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_01bb: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			AddLine("The gods await your decision, viking.", -85f, 15, Color.white);
			AddLine("The Way of the Mage", -125f, 19, GUIManager.Instance.ValheimOrange);
			AddLine("Master of the elements: fire, frost and lightning obey your will.", -153f, 14, Color.white);
			Vector2 position = new Vector2(0f, -193f);
			object obj = <>c.<>9__13_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Mage);
					Rebuild();
				};
				<>c.<>9__13_0 = val;
				obj = (object)val;
			}
			AddButton("Become a Mage", position, 240f, 44f, (UnityAction)obj);
			AddLine("The Way of the Berserker", -250f, 19, GUIManager.Instance.ValheimOrange);
			AddLine("Fury and steel: charges, whirlwinds and slams that shake the earth.", -278f, 14, Color.white);
			Vector2 position2 = new Vector2(0f, -318f);
			object obj2 = <>c.<>9__13_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Berserker);
					Rebuild();
				};
				<>c.<>9__13_1 = val2;
				obj2 = (object)val2;
			}
			AddButton("Become a Berserker", position2, 240f, 44f, (UnityAction)obj2);
			AddLine("The Way of the Necromancer", -375f, 19, GUIManager.Instance.ValheimOrange);
			AddLine("Lord of the dead: poisons, life drains and armies of skeletons.", -403f, 14, Color.white);
			Vector2 position3 = new Vector2(0f, -443f);
			object obj3 = <>c.<>9__13_2;
			if (obj3 == null)
			{
				UnityAction val3 = delegate
				{
					ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Necromancer);
					Rebuild();
				};
				<>c.<>9__13_2 = val3;
				obj3 = (object)val3;
			}
			AddButton("Become a Necromancer", position3, 240f, 44f, (UnityAction)obj3);
			AddLine("8 abilities to unlock, one every 10 levels, up to level 80.", -505f, 14, new Color(0.8f, 0.8f, 0.8f));
		}

		private static void BuildClassInfo(Player player)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Expected O, but got Unknown
			PlayerClass playerClass = ClassSystem.GetClass(player);
			int level = ClassSystem.GetLevel(player);
			int xp = ClassSystem.GetXp(player);
			string arg = ((level >= 80) ? "MAX LEVEL" : $"{xp} / {ClassSystem.XpThreshold(level + 1)} XP");
			AddLine($"Way of the {playerClass}  —  Level {level}  —  {arg}", -85f, 18, Color.white);
			Color val = default(Color);
			((Color)(ref val))..ctor(0.65f, 0.9f, 0.65f);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.6f, 0.6f, 0.6f);
			float num = -125f;
			SpellDef[] spells = Abilities.GetSpells(playerClass);
			foreach (SpellDef spellDef in spells)
			{
				bool flag = level >= spellDef.UnlockLevel;
				string text = (flag ? (spellDef.Name + ": " + spellDef.Describe(level)) : $"[Lv. {spellDef.UnlockLevel}] {spellDef.Name}: {spellDef.Describe(spellDef.UnlockLevel)}");
				AddLine(text, num, 14, flag ? val : val2);
				num -= 25f;
			}
			AddLine("Cast abilities with " + ClassiPlugin.GetSpellKeyLabel(0) + " ... " + ClassiPlugin.GetSpellKeyLabel(7) + " (configurable)", -345f, 14, new Color(0.8f, 0.8f, 0.8f));
			AddLine("Make an offering to the gods to gain experience:", -385f, 16, GUIManager.Instance.ValheimOrange);
			string text2 = $"Offer 1 trophy (+{50} XP)";
			Vector2 position = new Vector2(-170f, -430f);
			object obj = <>c.<>9__14_0;
			if (obj == null)
			{
				UnityAction val3 = delegate
				{
					OfferTrophy(Player.m_localPlayer);
					Rebuild();
				};
				<>c.<>9__14_0 = val3;
				obj = (object)val3;
			}
			AddButton(text2, position, 300f, 42f, (UnityAction)obj);
			string text3 = $"Offer {10} coins (+{20} XP)";
			Vector2 position2 = new Vector2(170f, -430f);
			object obj2 = <>c.<>9__14_1;
			if (obj2 == null)
			{
				UnityAction val4 = delegate
				{
					OfferCoins(Player.m_localPlayer);
					Rebuild();
				};
				<>c.<>9__14_1 = val4;
				obj2 = (object)val4;
			}
			AddButton(text3, position2, 300f, 42f, (UnityAction)obj2);
			Vector2 position3 = new Vector2(0f, -490f);
			object obj3 = <>c.<>9__14_2;
			if (obj3 == null)
			{
				UnityAction val5 = delegate
				{
					ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.None);
					Rebuild();
				};
				<>c.<>9__14_2 = val5;
				obj3 = (object)val5;
			}
			AddButton("Abandon the way (resets progress)", position3, 360f, 40f, (UnityAction)obj3);
		}

		private static void OfferTrophy(Player player)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).GetInventory();
			ItemData val = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if ((int)allItem.m_shared.m_itemType == 13)
				{
					val = allItem;
					break;
				}
			}
			if (val == null)
			{
				((Character)player).Message((MessageType)2, "You have no trophies to offer", 0, (Sprite)null);
				return;
			}
			int amount = (BossTrophyTokens.Contains(val.m_shared.m_name) ? 500 : 50);
			string text = Localization.instance.Localize(val.m_shared.m_name);
			inventory.RemoveOneItem(val);
			Effects.TryPlayAt(((Component)player).transform.position, "vfx_offering");
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_offering");
			((Character)player).Message((MessageType)2, "The gods accept " + text, 0, (Sprite)null);
			ClassSystem.AddXp(player, amount);
		}

		private static void OfferCoins(Player player)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory.CountItems("$item_coins", -1, true) < 10)
			{
				((Character)player).Message((MessageType)2, $"You need at least {10} coins", 0, (Sprite)null);
				return;
			}
			inventory.RemoveItem("$item_coins", 10, -1, true);
			Effects.TryPlayAt(((Component)player).transform.position, "vfx_offering");
			Effects.TryPlayAt(((Component)player).transform.position, "sfx_offering");
			ClassSystem.AddXp(player, 20);
		}

		private static void AddLine(string text, float y, int fontSize, Color color, float height = 30f)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GUIManager.Instance.CreateText(text, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, y), GUIManager.Instance.AveriaSerifBold, fontSize, color, true, Color.black, 640f, height, false);
			Text component = val.GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				component.alignment = (TextAnchor)4;
			}
		}

		private static void AddButton(string text, Vector2 position, float width, float height, UnityAction onClick, bool anchorBottom = false)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = (anchorBottom ? new Vector2(0.5f, 0f) : new Vector2(0.5f, 1f));
			GameObject val2 = GUIManager.Instance.CreateButton(text, _panel.transform, val, val, position, width, height);
			((UnityEvent)val2.GetComponent<Button>().onClick).AddListener(onClick);
		}
	}
	public enum PlayerClass
	{
		None,
		Mage,
		Berserker,
		Necromancer
	}
	public static class ClassSystem
	{
		private const string KeyClass = "cdv_classe";

		private const string KeyXp = "cdv_xp";

		public const int MaxLevel = 80;

		public static PlayerClass GetClass(Player player)
		{
			if ((Object)(object)player == (Object)null || player.m_customData == null || !player.m_customData.TryGetValue("cdv_classe", out var value))
			{
				return PlayerClass.None;
			}
			if (Enum.TryParse<PlayerClass>(value, out var result))
			{
				return result;
			}
			string text = value;
			string text2 = text;
			if (!(text2 == "Mago"))
			{
				if (text2 == "Necromante")
				{
					return PlayerClass.Necromancer;
				}
				return PlayerClass.None;
			}
			return PlayerClass.Mage;
		}

		public static void SetClass(Player player, PlayerClass cls)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			player.m_customData["cdv_classe"] = cls.ToString();
			player.m_customData["cdv_xp"] = "0";
			PassiveEffects.RemoveAll(player);
			PassiveEffects.EnsureApplied(player);
			if (cls != PlayerClass.None)
			{
				((Character)player).Message((MessageType)2, $"You have chosen the way of the {cls}!", 0, (Sprite)null);
				Effects.TryPlayAt(((Component)player).transform.position, "vfx_odin_despawn");
			}
		}

		public static int GetXp(Player player)
		{
			if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("cdv_xp", out var value) && int.TryParse(value, out var result))
			{
				return result;
			}
			return 0;
		}

		public static int XpThreshold(int level)
		{
			return 30 * (level - 1) + 15 * (level - 1) * level / 2;
		}

		public static int GetLevel(Player player)
		{
			int xp = GetXp(player);
			int i;
			for (i = 1; i < 80 && xp >= XpThreshold(i + 1); i++)
			{
			}
			return i;
		}

		public static void AddXp(Player player, int amount)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || amount <= 0 || GetClass(player) == PlayerClass.None)
			{
				return;
			}
			int level = GetLevel(player);
			int num = GetXp(player) + amount;
			player.m_customData["cdv_xp"] = num.ToString();
			((Character)player).Message((MessageType)1, $"+{amount} class XP", 0, (Sprite)null);
			int level2 = GetLevel(player);
			if (level2 <= level)
			{
				return;
			}
			((Character)player).Message((MessageType)2, $"Class level {level2}!", 0, (Sprite)null);
			Effects.TryPlayAt(((Component)player).transform.position, "vfx_odin_despawn");
			for (int i = level + 1; i <= level2; i++)
			{
				foreach (string item in Abilities.GetUnlockedAt(GetClass(player), i))
				{
					((Character)player).Message((MessageType)2, "New ability unlocked: " + item + "!", 0, (Sprite)null);
				}
			}
		}
	}
	public static class Effects
	{
		private static bool _triggersDumped;

		public static GameObject FindPrefab(params string[] names)
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			foreach (string text in names)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
			}
			Logger.LogWarning((object)("No prefab found among: " + string.Join(", ", names)));
			return null;
		}

		public static void TryPlayAt(Vector3 position, params string[] names)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			TryPlayAt(position, 30f, names);
		}

		public static void TryPlayAt(Vector3 position, float maxLifetime, params string[] names)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindPrefab(names);
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity);
				if (maxLifetime > 0f)
				{
					Object.Destroy((Object)(object)val2, maxLifetime);
				}
			}
		}

		public static void TryCastAnimation(Player player, params string[] triggerNames)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			Animator animator = ((Character)player).m_animator;
			ZSyncAnimation zanim = ((Character)player).m_zanim;
			if ((Object)(object)animator == (Object)null || (Object)(object)zanim == (Object)null)
			{
				return;
			}
			foreach (string text in triggerNames)
			{
				AnimatorControllerParameter[] parameters = animator.parameters;
				foreach (AnimatorControllerParameter val in parameters)
				{
					if ((int)val.type == 9 && val.name == text)
					{
						zanim.SetTrigger(text);
						return;
					}
				}
			}
			Logger.LogWarning((object)("No animation trigger found among: " + string.Join(", ", triggerNames)));
		}

		public static void DumpAnimatorTriggers(Player player)
		{
			if (!_triggersDumped && !((Object)(object)player == (Object)null) && !((Object)(object)((Character)player).m_animator == (Object)null))
			{
				_triggersDumped = true;
				IOrderedEnumerable<string> values = from p in ((Character)player).m_animator.parameters
					where (int)p.type == 9
					select p.name into n
					orderby n
					select n;
				Logger.LogInfo((object)("Player animation triggers: " + string.Join(", ", values)));
			}
		}
	}
	public static class HudOverlay
	{
		private const float SlotSize = 52f;

		private const float SlotGap = 6f;

		private const float BottomMargin = 60f;

		private static GUIStyle _slotStyle;

		private static GUIStyle _headerStyle;

		private static GUIStyle _keyStyle;

		private static GUIStyle _cooldownStyle;

		private static GUIStyle _lockedStyle;

		private static Texture2D _slotBg;

		private static Texture2D _overlayTex;

		private static readonly Dictionary<string, Sprite> IconCache = new Dictionary<string, Sprite>();

		public static void Draw()
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)Hud.instance == (Object)null || Hud.instance.m_userHidden)
			{
				return;
			}
			PlayerClass playerClass = ClassSystem.GetClass(localPlayer);
			if (playerClass == PlayerClass.None)
			{
				return;
			}
			EnsureStyles();
			SpellDef[] spells = Abilities.GetSpells(playerClass);
			if (spells.Length == 0)
			{
				return;
			}
			float num = (float)spells.Length * 52f + (float)(spells.Length - 1) * 6f;
			float num2 = ((float)Screen.width - num) / 2f;
			float num3 = (float)Screen.height - 60f - 52f;
			DrawHeader(localPlayer, num2, num3 - 44f, num);
			string text = null;
			Rect val = default(Rect);
			Rect rect = default(Rect);
			Rect val2 = default(Rect);
			for (int i = 0; i < spells.Length; i++)
			{
				SpellDef spellDef = spells[i];
				((Rect)(ref val))..ctor(num2 + (float)i * 58f, num3, 52f, 52f);
				bool flag = Abilities.IsUnlocked(localPlayer, spellDef);
				GUI.DrawTexture(val, (Texture)(object)_slotBg);
				Sprite icon = GetIcon(spellDef.IconItem);
				if ((Object)(object)icon != (Object)null)
				{
					((Rect)(ref rect))..ctor(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 4f, ((Rect)(ref val)).width - 8f, ((Rect)(ref val)).height - 8f);
					Color color = GUI.color;
					GUI.color = (Color)(flag ? Color.white : new Color(1f, 1f, 1f, 0.25f));
					DrawSprite(rect, icon);
					GUI.color = color;
				}
				if (!flag)
				{
					GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + ((Rect)(ref val)).height - 20f, ((Rect)(ref val)).width, 18f), $"lv{spellDef.UnlockLevel}", _lockedStyle);
				}
				else
				{
					float cooldownRemaining = Abilities.GetCooldownRemaining(spellDef.Name);
					if (cooldownRemaining > 0f)
					{
						float num4 = Mathf.Clamp01(cooldownRemaining / spellDef.Cooldown);
						((Rect)(ref val2))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y + ((Rect)(ref val)).height * (1f - num4), ((Rect)(ref val)).width, ((Rect)(ref val)).height * num4);
						GUI.DrawTexture(val2, (Texture)(object)_overlayTex);
						GUI.Label(val, $"{cooldownRemaining:0}", _cooldownStyle);
					}
				}
				GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y - 16f, ((Rect)(ref val)).width, 16f), ClassiPlugin.GetSpellKeyLabel(i), _keyStyle);
				if (((Rect)(ref val)).Contains(Event.current.mousePosition))
				{
					text = (flag ? (spellDef.Name + ": " + spellDef.Describe(ClassSystem.GetLevel(localPlayer))) : $"{spellDef.Name} (unlocks at level {spellDef.UnlockLevel})");
				}
			}
			if (text != null)
			{
				GUI.Label(new Rect(num2, num3 - 66f, num, 20f), text, _headerStyle);
			}
		}

		private static void DrawHeader(Player player, float x, float y, float width)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			int level = ClassSystem.GetLevel(player);
			int xp = ClassSystem.GetXp(player);
			string arg = ((level >= 80) ? "MAX" : $"{xp}/{ClassSystem.XpThreshold(level + 1)}");
			string text = $"<b>{ClassSystem.GetClass(player)}</b>  Lv. {level}   XP {arg}";
			if (Abilities.DebugUnlockAll)
			{
				text += "   <color=#ffcc00>[DEBUG]</color>";
			}
			GUI.Label(new Rect(x, y, width, 20f), text, _headerStyle);
		}

		private static Sprite GetIcon(string itemName)
		{
			if (string.IsNullOrEmpty(itemName) || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			if (IconCache.TryGetValue(itemName, out var value))
			{
				return value;
			}
			Sprite val = null;
			try
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemName);
				ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val = val2.m_itemData.GetIcon();
				}
			}
			catch
			{
			}
			IconCache[itemName] = val;
			return val;
		}

		private static void DrawSprite(Rect rect, Sprite sprite)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D texture = sprite.texture;
			try
			{
				Rect textureRect = sprite.textureRect;
				GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
			}
			catch
			{
				GUI.DrawTexture(rect, (Texture)(object)texture, (ScaleMode)2);
			}
		}

		private static void EnsureStyles()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0077: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			if (_slotStyle == null)
			{
				_slotBg = MakeTexture(new Color(0f, 0f, 0f, 0.6f));
				_overlayTex = MakeTexture(new Color(0f, 0f, 0f, 0.7f));
				_slotStyle = new GUIStyle(GUI.skin.box);
				_headerStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					richText = true,
					alignment = (TextAnchor)4
				};
				_headerStyle.normal.textColor = Color.white;
				_keyStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					alignment = (TextAnchor)4
				};
				_keyStyle.normal.textColor = new Color(0.85f, 0.85f, 0.85f);
				_cooldownStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 20,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_cooldownStyle.normal.textColor = Color.white;
				_lockedStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					alignment = (TextAnchor)4
				};
				_lockedStyle.normal.textColor = new Color(0.7f, 0.7f, 0.7f);
			}
		}

		private static Texture2D MakeTexture(Color color)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}
	}
	public static class Localizations
	{
		public static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "Italian";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "piece_cdv_tempio", "Tempio delle Classi" },
				{ "piece_cdv_tempio_desc", "Un altare sacro dove scegliere la propria via e offrire sacrifici agli dèi." },
				{ "piece_cdv_tempio_use", "Prega" }
			});
			text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "piece_cdv_tempio", "Temple of Classes" },
				{ "piece_cdv_tempio_desc", "A sacred altar where you choose your path and offer sacrifices to the gods." },
				{ "piece_cdv_tempio_use", "Pray" }
			});
		}
	}
	public static class PassiveEffects
	{
		public const string MageName = "SE_CDV_Mago";

		public const string BerserkerName = "SE_CDV_Berserker";

		public const string NecromancerName = "SE_CDV_Necromante";

		public const string RuneShieldName = "SE_CDV_Scudo";

		public const string FuryName = "SE_CDV_Furia";

		public const string IronSkinName = "SE_CDV_Ferro";

		public const string BoneArmorName = "SE_CDV_Ossa";

		private static readonly Dictionary<PlayerClass, string> PassiveByClass = new Dictionary<PlayerClass, string>
		{
			{
				PlayerClass.Mage,
				"SE_CDV_Mago"
			},
			{
				PlayerClass.Berserker,
				"SE_CDV_Berserker"
			},
			{
				PlayerClass.Necromancer,
				"SE_CDV_Necromante"
			}
		};

		private static readonly Dictionary<string, string> IconItemByEffect = new Dictionary<string, string>
		{
			{ "SE_CDV_Mago", "SurtlingCore" },
			{ "SE_CDV_Scudo", "SurtlingCore" },
			{ "SE_CDV_Berserker", "TrophyWolf" },
			{ "SE_CDV_Furia", "TrophyWolf" },
			{ "SE_CDV_Ferro", "ArmorIronChest" },
			{ "SE_CDV_Necromante", "TrophySkeleton" },
			{ "SE_CDV_Ossa", "BoneFragments" }
		};

		private static readonly Dictionary<string, StatusEffect> Registered = new Dictionary<string, StatusEffect>();

		public static void Register()
		{
			Create<SE_MagePassive>("SE_CDV_Mago", "Way of the Mage", "Elemental damage and stamina/eitr regeneration increased for every class level.");
			Create<SE_BerserkerPassive>("SE_CDV_Berserker", "Way of the Berserker", "Melee damage increased, cheaper attacks and more carry weight for every class level.");
			Create<SE_NecromancerPassive>("SE_CDV_Necromante", "Way of the Necromancer", "Poison and spirit damage increased, regeneration from beyond the grave for every class level.");
			Create<SE_RuneShield>("SE_CDV_Scudo", "Rune Shield", "A barrier of runes hardens your defense.", 20f);
			Create<SE_Fury>("SE_CDV_Furia", "Berserker Fury", "Increased damage and attacks that barely consume stamina.", 15f);
			Create<SE_IronSkin>("SE_CDV_Ferro", "Iron Skin", "Your skin is hard as iron.", 20f);
			Create<SE_BoneArmor>("SE_CDV_Ossa", "Bone Armor", "Ancient bones protect you.", 20f);
		}

		private static void Create<T>(string name, string displayName, string tooltip, float ttl = 0f) where T : StatusEffect
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			T val = ScriptableObject.CreateInstance<T>();
			((Object)(object)val).name = name;
			((StatusEffect)val).m_name = displayName;
			((StatusEffect)val).m_tooltip = tooltip;
			((StatusEffect)val).m_ttl = ttl;
			ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)val, false));
			Registered[name] = (StatusEffect)(object)val;
		}

		public static void EnsureApplied(Player player)
		{
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan == null)
			{
				return;
			}
			PlayerClass playerClass = ClassSystem.GetClass(player);
			foreach (KeyValuePair<PlayerClass, string> item in PassiveByClass)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(item.Value);
				if (item.Key == playerClass)
				{
					if (!sEMan.HaveStatusEffect(stableHashCode))
					{
						AssignIcon(item.Value);
						sEMan.AddStatusEffect(stableHashCode, false, 0, 0f);
					}
				}
				else if (sEMan.HaveStatusEffect(stableHashCode))
				{
					sEMan.RemoveStatusEffect(stableHashCode, true);
				}
			}
		}

		public static void RemoveAll(Player player)
		{
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan == null)
			{
				return;
			}
			foreach (string key in Registered.Keys)
			{
				sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode(key), true);
			}
		}

		public static void ApplyTimedEffect(Player player, string name)
		{
			AssignIcon(name);
			((Character)player).GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode(name), true, 0, 0f);
		}

		private static void AssignIcon(string effectName)
		{
			if (!Registered.TryGetValue(effectName, out var value) || (Object)(object)value.m_icon != (Object)null || (Object)(object)ObjectDB.instance == (Object)null || !IconItemByEffect.TryGetValue(effectName, out var value2))
			{
				return;
			}
			try
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(value2);
				ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val != (Object)null)
				{
					value.m_icon = val.m_itemData.GetIcon();
				}
			}
			catch
			{
			}
		}
	}
	public abstract class SE_ClassBase : StatusEffect
	{
		protected static int Lvl
		{
			get
			{
				Player localPlayer = Player.m_localPlayer;
				return (!((Object)(object)localPlayer != (Object)null)) ? 1 : ClassSystem.GetLevel(localPlayer);
			}
		}

		protected static bool IsMeleeSkill(SkillType skill)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//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_0039: Expected I4, but got Unknown
			switch (skill - 1)
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 6:
			case 10:
				return true;
			default:
				return false;
			}
		}
	}
	public class SE_MagePassive : SE_ClassBase
	{
		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			float num = 1f + 0.01f * (float)SE_ClassBase.Lvl;
			hitData.m_damage.m_fire *= num;
			hitData.m_damage.m_frost *= num;
			hitData.m_damage.m_lightning *= num;
			hitData.m_damage.m_poison *= num;
			hitData.m_damage.m_spirit *= num;
		}

		public override void ModifyStaminaRegen(ref float staminaRegen)
		{
			staminaRegen *= 1f + 0.005f * (float)SE_ClassBase.Lvl;
		}

		public override void ModifyEitrRegen(ref float eitrRegen)
		{
			eitrRegen *= 1f + 0.015f * (float)SE_ClassBase.Lvl;
		}
	}
	public class SE_BerserkerPassive : SE_ClassBase
	{
		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (SE_ClassBase.IsMeleeSkill(skill))
			{
				hitData.ApplyModifier(1f + 0.01f * (float)SE_ClassBase.Lvl);
			}
		}

		public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse)
		{
			staminaUse *= Mathf.Max(0.5f, 1f - 0.005f * (float)SE_ClassBase.Lvl);
		}

		public override void ModifyMaxCarryWeight(float baseLimit, ref float limit)
		{
			limit += 1.5f * (float)SE_ClassBase.Lvl;
		}
	}
	public class SE_NecromancerPassive : SE_ClassBase
	{
		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			float num = 1f + 0.015f * (float)SE_ClassBase.Lvl;
			hitData.m_damage.m_poison *= num;
			hitData.m_damage.m_spirit *= num;
		}

		public override void ModifyHealthRegen(ref float regenMultiplier)
		{
			regenMultiplier *= 1f + 0.005f * (float)SE_ClassBase.Lvl;
		}

		public override void ModifyEitrRegen(ref float eitrRegen)
		{
			eitrRegen *= 1f + 0.01f * (float)SE_ClassBase.Lvl;
		}
	}
	public class SE_RuneShield : SE_ClassBase
	{
		public override void ModifyArmorMods(ref float armorMods)
		{
			armorMods += 100f + 2f * (float)SE_ClassBase.Lvl;
		}
	}
	public class SE_Fury : SE_ClassBase
	{
		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			hitData.ApplyModifier(1.4f);
		}

		public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse)
		{
			staminaUse *= 0.2f;
		}
	}
	public class SE_IronSkin : SE_ClassBase
	{
		public override void ModifyArmorMods(ref float armorMods)
		{
			armorMods += 80f + 2f * (float)SE_ClassBase.Lvl;
		}
	}
	public class SE_BoneArmor : SE_ClassBase
	{
		public override void ModifyArmorMods(ref float armorMods)
		{
			armorMods += 70f + 2f * (float)SE_ClassBase.Lvl;
		}
	}
	[BepInPlugin("gianl.waysofthegods", "WaysOfTheGods", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class ClassiPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "gianl.waysofthegods";

		public const string PluginName = "WaysOfTheGods";

		public const string PluginVersion = "1.0.1";

		public static ClassiPlugin Instance;

		public static ConfigEntry<KeyboardShortcut>[] SpellKeys;

		public static ConfigEntry<KeyCode> KeyDebugUnlock;

		public static ConfigEntry<float> XpMultiplier;

		private Harmony _harmony;

		private float _nextPassiveCheck;

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			Instance = this;
			SpellKeys = new ConfigEntry<KeyboardShortcut>[8];
			for (int i = 0; i < SpellKeys.Length; i++)
			{
				SpellKeys[i] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", $"Ability{i + 1}", new KeyboardShortcut((KeyCode)(49 + i), (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), $"Cast class ability {i + 1}");
			}
			KeyDebugUnlock = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "UnlockAllAbilities", (KeyCode)290, "Test key: toggles temporary unlock of all abilities (does not touch XP)");
			XpMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Experience", "XpMultiplier", 1f, "Multiplier for XP gained from kills");
			Localizations.Register();
			PassiveEffects.Register();
			Temple.Register();
			_harmony = new Harmony("gianl.waysofthegods");
			XpPatches.Apply(_harmony);
			Logger.LogInfo((object)"WaysOfTheGods loaded: build the Temple of Classes to get started!");
		}

		private void Update()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (ClassGUI.IsOpen && Input.GetKeyDown((KeyCode)27))
			{
				ClassGUI.Close();
				return;
			}
			if (Time.time > _nextPassiveCheck)
			{
				_nextPassiveCheck = Time.time + 1f;
				PassiveEffects.EnsureApplied(localPlayer);
				Effects.DumpAnimatorTriggers(localPlayer);
				Abilities.UpdateMinions(localPlayer);
			}
			if (ClassSystem.GetClass(localPlayer) == PlayerClass.None || IsAnyUiOpen())
			{
				return;
			}
			if (Input.GetKeyDown(KeyDebugUnlock.Value))
			{
				Abilities.DebugUnlockAll = !Abilities.DebugUnlockAll;
				((Character)localPlayer).Message((MessageType)2, Abilities.DebugUnlockAll ? "DEBUG: all abilities unlocked" : "DEBUG: ability unlock disabled", 0, (Sprite)null);
			}
			for (int i = 0; i < SpellKeys.Length; i++)
			{
				KeyboardShortcut value = SpellKeys[i].Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Abilities.CastSpell(localPlayer, i);
					break;
				}
			}
		}

		public static string GetSpellKeyLabel(int index)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0054: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			if (SpellKeys == null || index < 0 || index >= SpellKeys.Length)
			{
				return string.Empty;
			}
			KeyboardShortcut value = SpellKeys[index].Value;
			List<string> list = new List<string>();
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				list.Add(ShortKeyName(modifier));
			}
			list.Add(ShortKeyName(((KeyboardShortcut)(ref value)).MainKey));
			return string.Join("+", list);
		}

		private unsafe static string ShortKeyName(KeyCode key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected I4, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected I4, but got Unknown
			if ((int)key >= 48 && (int)key <= 57)
			{
				return (key - 48).ToString();
			}
			KeyCode val = key;
			KeyCode val2 = val;
			switch (val2 - 303)
			{
			case 0:
			case 1:
				return "Shift";
			case 2:
			case 3:
				return "Ctrl";
			case 4:
			case 5:
				return "Alt";
			default:
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
		}

		private static bool IsAnyUiOpen()
		{
			try
			{
				return ClassGUI.IsOpen || Console.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Menu.IsVisible() || InventoryGui.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen();
			}
			catch
			{
				return false;
			}
		}

		private void OnGUI()
		{
			HudOverlay.Draw();
		}
	}
	public class RuneDome : MonoBehaviour
	{
		public Player Owner;

		public float Radius = 8f;

		public float EndTime;

		private float _nextTick;

		private bool _armorApplied;

		private void Update()
		{
			if (Time.time > EndTime)
			{
				RemoveArmor();
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else if (!(Time.time < _nextTick))
			{
				_nextTick = Time.time + 0.25f;
				UpdateArmor();
				DissolveEnemyProjectiles();
				RepelEnemies();
			}
		}

		private void UpdateArmor()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				SEMan sEMan = ((Character)localPlayer).GetSEMan();
				int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_CDV_Scudo");
				if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) <= Radius)
				{
					sEMan.AddStatusEffect(stableHashCode, true, 0, 0f);
					_armorApplied = true;
				}
				else if (_armorApplied && sEMan.HaveStatusEffect(stableHashCode))
				{
					sEMan.RemoveStatusEffect(stableHashCode, true);
					_armorApplied = false;
				}
			}
		}

		private void DissolveEnemyProjectiles()
		{
			//IL_0024: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			Projectile[] array = Object.FindObjectsByType<Projectile>((FindObjectsSortMode)0);
			foreach (Projectile val in array)
			{
				if (!((Object)(object)val == (Object)null) && !(Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > Radius))
				{
					Character owner = val.m_owner;
					if (!((Object)(object)owner != (Object)null) || !owner.IsPlayer())
					{
						Effects.TryPlayAt(((Component)val).transform.position, 2f, "fx_StaffShield_Hit");
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
		}

		private void RepelEnemies()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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)
			//IL_00c9: Expected O, but got Unknown
			//IL_00d5: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && !allCharacter.IsDead() && !(Vector3.Distance(((Component)allCharacter).transform.position, ((Component)this).transform.position) > Radius))
				{
					Vector3 dir = ((Component)allCharacter).transform.position - ((Component)this).transform.position;
					dir.y = 0f;
					dir = ((((Vector3)(ref dir)).sqrMagnitude > 0.01f) ? ((Vector3)(ref dir)).normalized : ((Component)this).transform.forward);
					HitData val = new HitData();
					val.m_pushForce = 80f;
					val.m_dir = dir;
					val.m_point = ((Component)allCharacter).transform.position;
					val.SetAttacker((Character)(object)Owner);
					allCharacter.Damage(val);
				}
			}
		}

		private void RemoveArmor()
		{
			if (_armorApplied)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null)
				{
					((Character)localPlayer).GetSEMan().RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_CDV_Scudo"), true);
				}
				_armorApplied = false;
			}
		}

		private void OnDestroy()
		{
			RemoveArmor();
		}
	}
	public static class Temple
	{
		public const string PieceName = "piece_cdv_tempio";

		public static void Register()
		{
			PrefabManager.OnVanillaPrefabsAvailable += CreatePiece;
		}

		private static void CreatePiece()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Name = "$piece_cdv_tempio";
			val.Description = "$piece_cdv_tempio_desc";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Misc;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("Stone", 20, 0, true),
				new RequirementConfig("FineWood", 10, 0, true),
				new RequirementConfig("SurtlingCore", 3, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("piece_cdv_tempio", "guard_stone", val2);
			GameObject piecePrefab = val3.PiecePrefab;
			PrivateArea component = piecePrefab.GetComponent<PrivateArea>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			piecePrefab.AddComponent<TempleInteract>();
			BuildTempleVisual(piecePrefab);
			PieceManager.Instance.AddPiece(val3);
			PrefabManager.OnVanillaPrefabsAvailable -= CreatePiece;
		}

		private static void BuildTempleVisual(GameObject prefab)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or