Decompiled source of Norns v2.0.0

plugins/Norns/Norns.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[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("Norns")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+22c6aac6b0f3f6f1500297b9af449f8e05818f33")]
[assembly: AssemblyProduct("Norns")]
[assembly: AssemblyTitle("Norns")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.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 Norns
{
	public sealed class ArcLightningVfxController : MonoBehaviour
	{
		private const int PointCount = 19;

		private const float RevealDuration = 0.065f;

		private const float HoldDuration = 0.145f;

		private const float FadeDuration = 0.16f;

		private const float RepathInterval = 0.032f;

		public LineRenderer OuterGlow;

		public LineRenderer MainChannel;

		public LineRenderer WhiteCore;

		public LineRenderer[] Branches;

		public Transform SourceGroup;

		public Transform TargetGroup;

		public Transform ResidualGroup;

		public Light ImpactLight;

		private readonly Vector3[] _points = (Vector3[])(object)new Vector3[19];

		private Vector3[][] _branchPoints;

		private ParticleSystem[] _sourceParticles;

		private ParticleSystem[] _targetParticles;

		private ParticleSystem[] _residualParticles;

		private Vector3 _from;

		private Vector3 _to;

		private Vector3 _direction;

		private Vector3 _side;

		private Vector3 _up;

		private float _length;

		private float _delay;

		private float _startedAt;

		private float _nextRepathAt;

		private int _seed;

		private int _repath;

		private bool _initialized;

		private bool _sourcePlayed;

		private bool _impactPlayed;

		private void OnEnable()
		{
			_sourceParticles = ParticlesUnder(SourceGroup);
			_targetParticles = ParticlesUnder(TargetGroup);
			_residualParticles = ParticlesUnder(ResidualGroup);
			StopAndClear(_sourceParticles);
			StopAndClear(_targetParticles);
			StopAndClear(_residualParticles);
			SetLineVisible(OuterGlow, visible: false);
			SetLineVisible(MainChannel, visible: false);
			SetLineVisible(WhiteCore, visible: false);
			if (Branches != null)
			{
				LineRenderer[] branches = Branches;
				for (int i = 0; i < branches.Length; i++)
				{
					SetLineVisible(branches[i], visible: false);
				}
			}
			if ((Object)(object)ImpactLight != (Object)null)
			{
				ImpactLight.intensity = 0f;
			}
			_startedAt = Time.time;
			_initialized = false;
			_sourcePlayed = false;
			_impactPlayed = false;
		}

		public unsafe void Initialize(Vector3 from, Vector3 to, float delay, int chainIndex)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_005e: 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_0066: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			_from = from;
			_to = to;
			Vector3 val = to - from;
			_length = ((Vector3)(ref val)).magnitude;
			if (_length < 0.05f)
			{
				val = Vector3.forward * 0.05f;
			}
			_direction = ((Vector3)(ref val)).normalized;
			Vector3 val2 = Vector3.Cross(_direction, Vector3.up);
			_side = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref _side)).sqrMagnitude < 0.01f)
			{
				val2 = Vector3.Cross(_direction, Vector3.right);
				_side = ((Vector3)(ref val2)).normalized;
			}
			val2 = Vector3.Cross(_side, _direction);
			_up = ((Vector3)(ref val2)).normalized;
			_delay = Mathf.Max(0f, delay);
			_seed = ((object)(*(Vector3*)(&from))/*cast due to .constrained prefix*/).GetHashCode() ^ (((object)(*(Vector3*)(&to))/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ (chainIndex * 7919);
			_repath = 0;
			_nextRepathAt = 0f;
			_startedAt = Time.time;
			_initialized = true;
			_sourcePlayed = false;
			_impactPlayed = false;
			if ((Object)(object)SourceGroup != (Object)null)
			{
				SourceGroup.position = from;
			}
			if ((Object)(object)TargetGroup != (Object)null)
			{
				TargetGroup.position = to;
			}
			if ((Object)(object)ResidualGroup != (Object)null)
			{
				ResidualGroup.position = to;
			}
			if ((Object)(object)ImpactLight != (Object)null)
			{
				((Component)ImpactLight).transform.position = to;
			}
			int num = ((Branches != null) ? Branches.Length : 0);
			_branchPoints = new Vector3[num][];
			for (int i = 0; i < num; i++)
			{
				_branchPoints[i] = (Vector3[])(object)new Vector3[4];
			}
		}

		private void Update()
		{
			if (!_initialized)
			{
				if (Time.time - _startedAt > 0.25f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				return;
			}
			float num = Time.time - _startedAt - _delay;
			if (!(num < 0f))
			{
				float num2 = 0.21f;
				float num3 = num2 + 0.16f;
				if (!_sourcePlayed)
				{
					_sourcePlayed = true;
					Play(_sourceParticles);
				}
				if (num <= num2 && num >= _nextRepathAt)
				{
					RebuildPath(num);
					_nextRepathAt = num + 0.032f;
				}
				float reveal = Smooth01(num / 0.065f);
				float num4 = ((num <= num2) ? 1f : (1f - Smooth01((num - num2) / 0.16f)));
				float strobe = 0.88f + Mathf.Sin(num * 91f + (float)_seed * 0.001f) * 0.08f + Mathf.Sin(num * 143f + 1.7f) * 0.04f;
				DrawMainLines(reveal, num4, strobe);
				DrawBranches(reveal, num4);
				if (!_impactPlayed && num >= 0.053299997f)
				{
					PlayImpact();
				}
				if ((Object)(object)ImpactLight != (Object)null)
				{
					float num5 = Mathf.Max(0f, num - 0.053299997f);
					float num6 = Mathf.Exp((0f - num5) * 18f) * 4.6f;
					float num7 = Mathf.Clamp01(1f - num5 / 0.24f) * 0.65f;
					ImpactLight.intensity = (_impactPlayed ? ((num6 + num7) * num4) : 0f);
				}
				if (num >= num3 + 0.34f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}

		private void RebuildPath(float localTime)
		{
			//IL_00dc: 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_00e8: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: 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_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: 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_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			_repath++;
			float num = Mathf.Clamp(_length * 0.075f, 0.18f, 0.86f);
			for (int i = 0; i < 19; i++)
			{
				float num2 = (float)i / 18f;
				float num3 = Mathf.Sin(num2 * (float)Math.PI);
				float num4 = Mathf.Sin(num2 * 16.2f + (float)_seed * 0.00031f + (float)_repath * 1.73f);
				float num5 = Mathf.Sin(num2 * 39.7f - (float)_seed * 0.00019f - (float)_repath * 2.31f);
				float num6 = Mathf.Sin(num2 * 27.1f + (float)_seed * 0.00047f + (float)_repath * 1.19f);
				float num7 = num4 * 0.68f + num5 * 0.32f;
				_points[i] = Vector3.Lerp(_from, _to, num2) + _side * num7 * num * num3 + _up * num6 * num * 0.58f * num3;
			}
			_points[0] = _from;
			_points[18] = _to;
			if (Branches != null)
			{
				for (int j = 0; j < Branches.Length; j++)
				{
					int num8 = Mathf.Clamp(3 + j * 2, 2, 16);
					Vector3 val = _points[num8];
					float num9 = (((j & 1) == 0) ? 1f : (-1f));
					float num10 = (float)_seed * 0.00023f + (float)j * 1.91f + (float)_repath * 0.74f;
					Vector3 val2 = _side * num9 * (0.72f + Mathf.Abs(Mathf.Sin(num10)) * 0.34f) + _up * Mathf.Sin(num10 * 1.37f) * 0.54f + _direction * (0.12f + (float)j * 0.025f);
					Vector3 normalized = ((Vector3)(ref val2)).normalized;
					float num11 = Mathf.Clamp(_length * (0.1f + (float)j * 0.008f), 0.62f, 1.65f);
					Vector3[] obj = _branchPoints[j];
					obj[0] = val;
					obj[1] = val + normalized * num11 * 0.34f + _up * Mathf.Sin(num10 + 0.8f) * 0.13f;
					obj[2] = val + normalized * num11 * 0.69f - _side * num9 * 0.12f;
					obj[3] = val + normalized * num11;
				}
			}
		}

		private void DrawMainLines(float reveal, float fade, float strobe)
		{
			//IL_0037: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			int visible = Mathf.Clamp(Mathf.CeilToInt(reveal * 18f) + 1, 2, 19);
			DrawLine(OuterGlow, visible, new Color(0.16f, 0.42f, 1f, 0.24f * fade * strobe));
			DrawLine(MainChannel, visible, new Color(0.28f, 0.76f, 1f, 0.82f * fade * strobe));
			DrawLine(WhiteCore, visible, new Color(0.93f, 0.99f, 1f, fade));
		}

		private void DrawLine(LineRenderer line, int visible, Color color)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)line == (Object)null))
			{
				((Renderer)line).enabled = true;
				line.positionCount = visible;
				line.startColor = color;
				line.endColor = color;
				for (int i = 0; i < visible; i++)
				{
					line.SetPosition(i, _points[i]);
				}
			}
		}

		private void DrawBranches(float reveal, float fade)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (Branches == null)
			{
				return;
			}
			float num = fade * Smooth01((reveal - 0.26f) / 0.42f);
			Color val2 = default(Color);
			for (int i = 0; i < Branches.Length; i++)
			{
				LineRenderer val = Branches[i];
				if (!((Object)(object)val == (Object)null))
				{
					float num2 = 0.62f + Mathf.Sin((Time.time - _startedAt) * 107f + (float)i * 2.1f) * 0.24f;
					((Color)(ref val2))..ctor(0.38f, 0.79f, 1f, Mathf.Clamp01(num * num2 * (1f - (float)i * 0.055f)));
					((Renderer)val).enabled = val2.a > 0.015f;
					if (((Renderer)val).enabled)
					{
						val.positionCount = 4;
						val.startColor = val2;
						val.endColor = new Color(val2.r, val2.g, val2.b, 0f);
						val.SetPositions(_branchPoints[i]);
					}
				}
			}
		}

		private void PlayImpact()
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			_impactPlayed = true;
			Play(_targetParticles);
			Play(_residualParticles);
			Effects.InstantiateLocal("fx_chainlightning_hit", _to, Quaternion.identity, 4f);
			SpellAudio.PlayArcLightningHop(_to);
		}

		private static ParticleSystem[] ParticlesUnder(Transform root)
		{
			if (!((Object)(object)root == (Object)null))
			{
				return ((Component)root).GetComponentsInChildren<ParticleSystem>(true);
			}
			return (ParticleSystem[])(object)new ParticleSystem[0];
		}

		private static void Play(ParticleSystem[] systems)
		{
			foreach (ParticleSystem val in systems)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Play(true);
				}
			}
		}

		private static void StopAndClear(ParticleSystem[] systems)
		{
			foreach (ParticleSystem val in systems)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
		}

		private static void SetLineVisible(LineRenderer line, bool visible)
		{
			if ((Object)(object)line != (Object)null)
			{
				((Renderer)line).enabled = visible;
			}
		}

		private static float Smooth01(float value)
		{
			value = Mathf.Clamp01(value);
			return value * value * (3f - 2f * value);
		}
	}
	public sealed class ArcLightningChargeVfxController : MonoBehaviour
	{
		private static readonly List<ArcLightningChargeVfxController> Active = new List<ArcLightningChargeVfxController>();

		public Light EffectLight;

		public float Lifetime = 0.88f;

		private ParticleSystem[] _particles;

		private Transform _handAnchor;

		private float _startedAt;

		private float _cancelAt = -1f;

		private void OnEnable()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			_particles = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			_startedAt = Time.time;
			_cancelAt = -1f;
			_handAnchor = FindNearestRightHand(((Component)this).transform.position);
			Active.Add(this);
			ParticleSystem[] particles = _particles;
			foreach (ParticleSystem obj in particles)
			{
				obj.Stop(true, (ParticleSystemStopBehavior)0);
				obj.Play(true);
			}
			if ((Object)(object)EffectLight != (Object)null)
			{
				EffectLight.intensity = 0f;
			}
		}

		private void OnDisable()
		{
			Active.Remove(this);
		}

		private void Update()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_006a: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.time - _startedAt;
			if ((Object)(object)_handAnchor != (Object)null)
			{
				Vector3 val = _handAnchor.position + _handAnchor.forward * 0.14f;
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val, 1f - Mathf.Exp((0f - Time.deltaTime) * 28f));
			}
			float num2 = ((_cancelAt < 0f) ? 1f : Mathf.Clamp01(1f - (Time.time - _cancelAt) / 0.12f));
			if ((Object)(object)EffectLight != (Object)null)
			{
				float num3 = Smooth01(num / 0.55f);
				float num4 = 0.88f + Mathf.Sin(num * 49f) * 0.12f;
				EffectLight.intensity = num3 * num4 * 1.25f * num2;
			}
			if (_cancelAt >= 0f)
			{
				if (Time.time - _cancelAt >= 0.14f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			else if (num >= Lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public void Cancel()
		{
			if (!(_cancelAt >= 0f))
			{
				_cancelAt = Time.time;
				ParticleSystem[] particles = _particles;
				for (int i = 0; i < particles.Length; i++)
				{
					particles[i].Stop(true, (ParticleSystemStopBehavior)1);
				}
			}
		}

		public static void CancelNearest(Vector3 position, float maximumDistance = 3.5f)
		{
			//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)
			ArcLightningChargeVfxController arcLightningChargeVfxController = null;
			float num = maximumDistance;
			for (int num2 = Active.Count - 1; num2 >= 0; num2--)
			{
				ArcLightningChargeVfxController arcLightningChargeVfxController2 = Active[num2];
				if ((Object)(object)arcLightningChargeVfxController2 == (Object)null)
				{
					Active.RemoveAt(num2);
				}
				else
				{
					float num3 = Vector3.Distance(((Component)arcLightningChargeVfxController2).transform.position, position);
					if (!(num3 >= num))
					{
						num = num3;
						arcLightningChargeVfxController = arcLightningChargeVfxController2;
					}
				}
			}
			arcLightningChargeVfxController?.Cancel();
		}

		private static Transform FindNearestRightHand(Vector3 position)
		{
			//IL_0028: 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)
			Player val = null;
			float num = 3.5f;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (!((Object)(object)allPlayer == (Object)null))
				{
					float num2 = Vector3.Distance(position, ((Component)allPlayer).transform.position);
					if (!(num2 >= num))
					{
						num = num2;
						val = allPlayer;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>();
			if (!((Object)(object)componentInChildren != (Object)null) || !componentInChildren.isHuman)
			{
				return null;
			}
			return componentInChildren.GetBoneTransform((HumanBodyBones)18);
		}

		private static float Smooth01(float value)
		{
			value = Mathf.Clamp01(value);
			return value * value * (3f - 2f * value);
		}
	}
	public sealed class BerserkerAuraVfxController : MonoBehaviour
	{
		public Transform FormationGroup;

		public Transform BodyGroup;

		public Transform GroundGroup;

		public Transform DissipationGroup;

		public ParticleSystem HeartbeatPulse;

		public Light AuraLight;

		public float Lifetime = 12f;

		public float HeartbeatInterval;

		public float BaseIntensity = 0.55f;

		private Player _player;

		private Transform _chest;

		private float _startedAt;

		private int _heartbeats;

		private bool _ending;

		private float _endStartedAt;

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_player = BerserkerVfxSupport.FindNearestPlayer(((Component)this).transform.position);
			_chest = BerserkerVfxSupport.ChestAnchor(_player);
			_startedAt = Time.time;
			_heartbeats = 0;
			_ending = false;
			BerserkerVfxSupport.Play(FormationGroup);
			BerserkerVfxSupport.Play(BodyGroup);
			BerserkerVfxSupport.Play(GroundGroup);
			BerserkerVfxSupport.StopAndClear(DissipationGroup);
			if ((Object)(object)AuraLight != (Object)null)
			{
				AuraLight.intensity = 0f;
			}
		}

		private void LateUpdate()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00cf: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_01f5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null)
			{
				_player = BerserkerVfxSupport.FindNearestPlayer(((Component)this).transform.position);
				_chest = BerserkerVfxSupport.ChestAnchor(_player);
			}
			float num = Time.time - _startedAt;
			Vector3 val = (((Object)(object)_player != (Object)null) ? ((Component)_player).transform.position : ((Component)this).transform.position);
			Quaternion rotation = (((Object)(object)_player != (Object)null) ? ((Component)_player).transform.rotation : ((Component)this).transform.rotation);
			Vector3 position = (((Object)(object)_chest != (Object)null) ? _chest.position : (val + Vector3.up * 1.32f));
			((Component)this).transform.position = val;
			if ((Object)(object)FormationGroup != (Object)null)
			{
				FormationGroup.position = position;
				FormationGroup.rotation = rotation;
			}
			if ((Object)(object)BodyGroup != (Object)null)
			{
				BodyGroup.position = position;
				BodyGroup.rotation = rotation;
			}
			if ((Object)(object)GroundGroup != (Object)null)
			{
				GroundGroup.position = val + Vector3.up * 0.05f;
				GroundGroup.rotation = rotation;
			}
			if ((Object)(object)DissipationGroup != (Object)null)
			{
				DissipationGroup.position = position;
				DissipationGroup.rotation = rotation;
			}
			if (HeartbeatInterval > 0.05f && !_ending)
			{
				int num2 = Mathf.FloorToInt(num / HeartbeatInterval);
				while (_heartbeats < num2)
				{
					_heartbeats++;
					ParticleSystem heartbeatPulse = HeartbeatPulse;
					if (heartbeatPulse != null)
					{
						heartbeatPulse.Emit(18);
					}
				}
			}
			if ((Object)(object)AuraLight != (Object)null)
			{
				((Component)AuraLight).transform.position = position;
				float num3 = BerserkerVfxSupport.Smooth01(num / 0.32f);
				float num4 = 1f - BerserkerVfxSupport.Smooth01((num - Lifetime) / 0.55f);
				float num5 = ((HeartbeatInterval > 0.05f) ? (1f + Mathf.Pow(1f - Mathf.Repeat(num / HeartbeatInterval, 1f), 4f) * 0.55f) : (1f + Mathf.Sin(num * 1.9f) * 0.1f));
				AuraLight.intensity = num3 * num4 * BaseIntensity * num5;
			}
			if (!_ending && num >= Lifetime)
			{
				_ending = true;
				_endStartedAt = Time.time;
				BerserkerVfxSupport.StopEmitting(FormationGroup);
				BerserkerVfxSupport.StopEmitting(BodyGroup);
				BerserkerVfxSupport.StopEmitting(GroundGroup);
				BerserkerVfxSupport.Play(DissipationGroup);
			}
			if (_ending && Time.time - _endStartedAt >= 1.45f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public static class BerserkerClass
	{
		public const string PassiveId = "wrathbound";

		public const float RendingWindow = 8f;

		public const float RendingDamage = 34f;

		public const float WarCryRadius = 8f;

		public const float WarCryFuryGain = 50f;

		private const float WarCryStagger = 10f;

		public const float BloodstormRadius = 5f;

		public const float BloodstormDamage = 28f;

		public const int BloodstormPulses = 3;

		public const float BloodstormDuration = 2.55f;

		public const float BloodstormInterval = 0.84999996f;

		public const int BloodstormSpins = 4;

		private const float SwingChainSettle = 0.15f;

		public const float BearskinDuration = 12f;

		public const float BearskinDamageReduction = 0.4f;

		public const float BearskinTauntRadius = 12f;

		public const float BearskinRegenPerSecond = 4f;

		private const float BearskinTauntInterval = 1.5f;

		public const float RageDuration = 12f;

		public const float RageLifeSteal = 0.15f;

		public const float RageBurstRadius = 6f;

		public const float RageBurstDamage = 40f;

		private static Player _statePlayer;

		private static float _rendingUntil;

		private static float _rendingExtraDamage;

		private static float _bearskinUntil;

		private static float _rageUntil;

		private static bool _rageWasActive;

		private static Player _animationAttackPlayer;

		private static float _suppressAnimationAttackUntil;

		public static readonly Spell[] Spells = new Spell[5]
		{
			new Spell
			{
				Id = "rending_blow",
				UnlockLevel = 10,
				Cooldown = 5f,
				Resource = AbilityResource.Fury,
				ResourceCost = 20f,
				CastTime = 0f,
				BaseDamage = 34f,
				CastTrigger = null,
				Describe = (int lvl) => Loc.F("spell_rending_blow_desc", 8f, Progression.Dmg(34f, lvl)),
				Cast = ArmRendingBlow
			},
			new Spell
			{
				Id = "war_cry",
				UnlockLevel = 20,
				Cooldown = 30f,
				Resource = AbilityResource.Fury,
				ResourceCost = 0f,
				CastTime = 0f,
				BaseDamage = 0f,
				CastEmote = "roar",
				CastTrigger = "gpower",
				Describe = (int _) => Loc.F("spell_war_cry_desc", 8f, 50f),
				Cast = CastWarCry
			},
			new Spell
			{
				Id = "bloodstorm",
				UnlockLevel = 30,
				Cooldown = 18f,
				Resource = AbilityResource.Fury,
				ResourceCost = 45f,
				CastTime = 0f,
				BaseDamage = 28f,
				CastTrigger = null,
				Describe = (int lvl) => Loc.F("spell_bloodstorm_desc", Progression.Dmg(28f, lvl), 5f),
				Cast = CastBloodstorm
			},
			new Spell
			{
				Id = "bearskin",
				IconStem = "deathless",
				UnlockLevel = 40,
				Cooldown = 60f,
				Resource = AbilityResource.Fury,
				ResourceCost = 55f,
				CastTime = 0f,
				BaseDamage = 0f,
				CastEmote = "flex",
				CastTrigger = "gpower",
				Describe = (int _) => Loc.F("spell_bearskin_desc", 12f, 40f, 4f, 12f),
				Cast = CastBearskin
			},
			new Spell
			{
				Id = "rage_unbound",
				UnlockLevel = 50,
				Cooldown = 120f,
				Resource = AbilityResource.Fury,
				ResourceCost = 100f,
				CastTime = 0f,
				BaseDamage = 40f,
				CastEmote = "challenge",
				CastTrigger = "gpower",
				Describe = (int lvl) => Loc.F("spell_rage_unbound_desc", Progression.Dmg(40f, lvl), 6f, 12f, 15.000001f),
				Cast = CastRageUnbound
			}
		};

		public const float EmptyFuryPenalty = 0.1f;

		public const float FullFurySpeedBonus = 0.15f;

		public const float RegenFuryThreshold = 50f;

		public const float RegenFuryHysteresis = 10f;

		public const float WrathboundRegenPerTick = 2f;

		public static string PassiveName => Loc.T("passive_wrathbound_name");

		public static string PassiveDescription(int level)
		{
			return Loc.F("passive_wrathbound_desc", 10f, MaximumMeleeBonus(level) * 100f, 15.000001f, 50f, 5f);
		}

		public static float MaximumMeleeBonus(int level)
		{
			return 0.1f + 0.002f * (float)Mathf.Clamp(level, 1, 50);
		}

		public static float FuryDamageModifier(Player player, int level)
		{
			float num = Mathf.Lerp(-0.1f, MaximumMeleeBonus(level), BerserkerFury.Normalized);
			if (IsRageUnbound(player))
			{
				num = Mathf.Max(num, 0f) * 2f;
			}
			return 1f + num;
		}

		public static float FurySpeedMultiplier(Player player)
		{
			if ((Object)(object)player == (Object)null || ClassSystem.GetClass(player) != PlayerClass.Berserker)
			{
				return 1f;
			}
			return 1f + 0.15f * BerserkerFury.Normalized;
		}

		public static void Update(Player player)
		{
			EnsureState(player);
			if (!((Object)(object)player == (Object)null))
			{
				bool flag = IsRageUnbound(player);
				if (_rageWasActive && !flag)
				{
					BerserkerFury.EmptyAfterRageUnbound();
				}
				_rageWasActive = flag;
				if (((Character)player).IsDead())
				{
					_rendingUntil = 0f;
					_bearskinUntil = 0f;
					_rageUntil = 0f;
				}
			}
		}

		public static bool IsRageUnbound(Player player)
		{
			if ((Object)(object)player != (Object)null && player == _statePlayer)
			{
				return Time.time < _rageUntil;
			}
			return false;
		}

		private static void EnsureState(Player player)
		{
			if (player != _statePlayer)
			{
				_statePlayer = player;
				_rendingUntil = 0f;
				_rendingExtraDamage = 0f;
				_bearskinUntil = 0f;
				_rageUntil = 0f;
				_rageWasActive = false;
				_animationAttackPlayer = null;
				_suppressAnimationAttackUntil = 0f;
			}
		}

		public static void ResetState(Player player)
		{
			_statePlayer = player;
			_rendingUntil = 0f;
			_rendingExtraDamage = 0f;
			_bearskinUntil = 0f;
			_rageUntil = 0f;
			_rageWasActive = false;
			_animationAttackPlayer = null;
			_suppressAnimationAttackUntil = 0f;
		}

		public static void ModifyOutgoingMelee(Character target, Player attacker, HitData hit)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			EnsureState(attacker);
			int level = ClassSystem.GetLevel(attacker);
			float num = FuryDamageModifier(attacker, level);
			num *= BerserkerSpecializationEffects.RendMultiplier(attacker, target);
			num *= BerserkerSpecializationEffects.CommandMultiplier(attacker);
			num *= RuneEffects.MeleeDamageMultiplier(attacker);
			hit.m_damage.m_blunt *= num;
			hit.m_damage.m_slash *= num;
			hit.m_damage.m_pierce *= num;
			hit.m_staggerMultiplier *= BerserkerSpecializationEffects.OutgoingStaggerMultiplier(attacker);
			if (BerserkerSpecializationEffects.IsJotunnForm(attacker))
			{
				Vector3 point = ((hit.m_point != Vector3.zero) ? hit.m_point : (((Object)(object)target != (Object)null) ? target.GetCenterPoint() : ((Component)attacker).transform.position));
				JotunnClass.ReleaseFormShockwave(attacker, target, point);
			}
			RuneEffects.ApplyMeleeRiders(attacker, hit);
			RuneEffects.OnMeleeHit(attacker, target, hit);
			if (!(Time.time >= _rendingUntil) && !(_rendingExtraDamage <= 0f))
			{
				hit.m_damage.m_slash += _rendingExtraDamage;
				hit.m_staggerMultiplier = Mathf.Max(hit.m_staggerMultiplier, 2.2f);
				_rendingUntil = 0f;
				_rendingExtraDamage = 0f;
				PassiveEffects.RemoveRending(attacker);
				Vector3 b = ((hit.m_point != Vector3.zero) ? hit.m_point : (((Object)(object)target != (Object)null) ? target.GetCenterPoint() : ((Component)attacker).transform.position));
				SpellFx.PlayShared(FxKind.RendingBlow, ((Component)attacker).transform.position, b);
			}
		}

		public static void ReduceIncomingDamage(Player player, float previousHealth, ref float health)
		{
			if (!((Object)(object)player == (Object)null) && ClassSystem.GetClass(player) == PlayerClass.Berserker)
			{
				EnsureState(player);
				if (!(health >= previousHealth) && !(Time.time >= _bearskinUntil))
				{
					float num = previousHealth - health;
					health = previousHealth - num * 0.6f;
				}
			}
		}

		private static void ArmRendingBlow(Player player, int level)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			EnsureState(player);
			_rendingUntil = Time.time + 8f;
			_rendingExtraDamage = Progression.Dmg(34f, level);
			PassiveEffects.ApplyRending(player);
			SpellFx.PlayShared(FxKind.RendingEmpower, ((Component)player).transform.position, ((Component)player).transform.position);
		}

		private static void CastWarCry(Player player, int level)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0015: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			SpellFx.PlayShared(FxKind.WarCry, position, position);
			foreach (Character item in Effects.EnemiesInRange(position, 8f, (Character)(object)player))
			{
				Effects.DealDamage(player, item, new DamageTypes
				{
					m_blunt = 1f
				}, null, 40f, 10f);
			}
			BerserkerFury.AddFromWarCry(50f);
		}

		private static void CastBloodstorm(Player player, int level)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			SpellFx.PlayShared(FxKind.Bloodstorm, ((Component)player).transform.position, ((Component)player).transform.position);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(BloodstormRoutine(player, level));
		}

		private static IEnumerator BloodstormRoutine(Player player, int level)
		{
			Quaternion startRotation = ((Component)player).transform.rotation;
			float damage = Progression.Dmg(28f, level);
			SuppressAnimationAttacks(player, 3.75f);
			float elapsed = 0f;
			float nextSwingAt = 0f;
			int pulsesDealt = 0;
			while (elapsed < 2.55f)
			{
				if ((Object)(object)player == (Object)null)
				{
					yield break;
				}
				if (((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker)
				{
					RestoreFacing(player, startRotation);
					yield break;
				}
				if (elapsed >= nextSwingAt && !((Character)player).InAttack())
				{
					TriggerWeaponSwing(player);
					nextSwingAt = elapsed + 0.15f;
				}
				float num = 4f * (elapsed / 2.55f);
				((Component)player).transform.rotation = startRotation * Quaternion.Euler(0f, num * 360f, 0f);
				int num2 = Mathf.Clamp(Mathf.FloorToInt((elapsed + 0.40799996f) / 0.84999996f), 0, 3);
				while (pulsesDealt < num2)
				{
					pulsesDealt++;
					DealBloodstormPulse(player, damage);
				}
				elapsed += Time.deltaTime;
				yield return null;
			}
			while (pulsesDealt < 3)
			{
				pulsesDealt++;
				DealBloodstormPulse(player, damage);
			}
			RestoreFacing(player, startRotation);
		}

		internal static void RestoreFacing(Player player, Quaternion fallback)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_003e: 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)
			if (!((Object)(object)player == (Object)null))
			{
				Quaternion lookYaw = ((Character)player).GetLookYaw();
				((Component)player).transform.rotation = ((lookYaw.x == 0f && lookYaw.y == 0f && lookYaw.z == 0f && lookYaw.w == 0f) ? fallback : lookYaw);
			}
		}

		private static void DealBloodstormPulse(Player player, float damage)
		{
			//IL_0006: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character item in Effects.EnemiesInRange(((Component)player).transform.position, 5f, (Character)(object)player))
			{
				Effects.DealDamage(player, item, new DamageTypes
				{
					m_slash = damage
				}, null, 12f);
			}
		}

		internal static void SuppressAnimationAttacks(Player player, float duration)
		{
			if (!((Object)(object)player == (Object)null))
			{
				_animationAttackPlayer = player;
				_suppressAnimationAttackUntil = Mathf.Max(_suppressAnimationAttackUntil, Time.time + duration);
			}
		}

		internal static void TriggerWeaponSwing(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			float stamina = player.GetStamina();
			if (((Character)player).StartAttack((Character)null, false))
			{
				SuppressAnimationAttacks(player, 0.9f);
				float num = stamina - player.GetStamina();
				if (num > 0f)
				{
					((Character)player).AddStamina(num);
				}
			}
			else
			{
				ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
				string text = ((currentWeapon != null && currentWeapon.m_shared != null && currentWeapon.m_shared.m_attack != null) ? currentWeapon.m_shared.m_attack.m_attackAnimation : null);
				if (!string.IsNullOrEmpty(text) && (Object)(object)((Character)player).m_zanim != (Object)null)
				{
					((Character)player).m_zanim.SetTrigger(text);
				}
			}
		}

		internal static bool SuppressAnimationAttack(Attack attack)
		{
			if (attack != null && Time.time < _suppressAnimationAttackUntil)
			{
				return (object)attack.m_character == _animationAttackPlayer;
			}
			return false;
		}

		private static void CastBearskin(Player player, int level)
		{
			//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)
			EnsureState(player);
			_bearskinUntil = Time.time + 12f;
			PassiveEffects.ApplyBearskin(player);
			SpellFx.PlayShared(FxKind.Bearskin, ((Component)player).transform.position, ((Component)player).transform.position);
			XpSystem.Message(player, Loc.T("msg_bearskin_taunt"));
			((MonoBehaviour)Plugin.Instance).StartCoroutine(BearskinRoutine(player));
		}

		private static IEnumerator BearskinRoutine(Player player)
		{
			for (float elapsed = 0f; elapsed < 12f; elapsed += 1.5f)
			{
				if ((Object)(object)player == (Object)null)
				{
					break;
				}
				if (((Character)player).IsDead())
				{
					break;
				}
				if (player != _statePlayer)
				{
					break;
				}
				Vector3 position = ((Component)player).transform.position;
				ZDOID zDOID = ((Character)player).GetZDOID();
				Effects.TauntOwned(position, 12f, zDOID);
				Network.BroadcastTaunt(position, 12f, zDOID);
				float num = Mathf.Max(0f, ((Character)player).GetMaxHealth() - ((Character)player).GetHealth());
				if (num > 0.01f)
				{
					((Character)player).Heal(Mathf.Min(num, 6f), true);
				}
				yield return (object)new WaitForSeconds(1.5f);
			}
		}

		private static void CastRageUnbound(Player player, int level)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			EnsureState(player);
			_rageUntil = Time.time + 12f;
			_rageWasActive = true;
			PassiveEffects.ApplyRageUnbound(player);
			BerserkerFury.FillForRageUnbound();
			SpellFx.PlayShared(FxKind.RageUnbound, ((Component)player).transform.position, ((Component)player).transform.position);
		}
	}
	[HarmonyPatch(typeof(SEMan), "ApplyStatusEffectSpeedMods")]
	internal static class BerserkerFurySpeedPatch
	{
		private static void Postfix(SEMan __instance, ref float speed)
		{
			Character obj = __instance?.m_character;
			Player val = (Player)(object)((obj is Player) ? obj : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				speed *= BerserkerClass.FurySpeedMultiplier(val);
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
	internal static class BerserkerAnimationMeleePatch
	{
		private static bool Prefix(Attack __instance)
		{
			return !BerserkerClass.SuppressAnimationAttack(__instance);
		}
	}
	[HarmonyPatch(typeof(Attack), "DoAreaAttack")]
	internal static class BerserkerAnimationAreaPatch
	{
		private static bool Prefix(Attack __instance)
		{
			return !BerserkerClass.SuppressAnimationAttack(__instance);
		}
	}
	public static class BerserkerFury
	{
		public const float Maximum = 100f;

		public const float GraceDuration = 5f;

		public const float DecayPerSecond = 3.75f;

		private const float TwoHandedFuryScale = 1.35f;

		private const float OneHandedFuryScale = 0.78f;

		private static Player _trackedPlayer;

		private static float _value;

		private static float _lastCombatAt = -999f;

		private static bool _wasDead;

		public static float Value => _value;

		public static float Normalized => Mathf.Clamp01(_value / 100f);

		public static void Update(Player player)
		{
			if (player != _trackedPlayer)
			{
				_trackedPlayer = player;
				_value = 0f;
				_lastCombatAt = -999f;
				_wasDead = false;
			}
			if ((Object)(object)player == (Object)null || ClassSystem.GetClass(player) != PlayerClass.Berserker)
			{
				_value = 0f;
				return;
			}
			if (((Character)player).IsDead())
			{
				if (!_wasDead)
				{
					_value = 0f;
				}
				_wasDead = true;
				return;
			}
			_wasDead = false;
			if (MaximumIsLocked(player))
			{
				_value = 100f;
			}
			else if (Time.time - _lastCombatAt > 5f)
			{
				float num = RuneEffects.FuryDecay(player, 3.75f);
				_value = Mathf.MoveTowards(_value, 0f, num * Time.deltaTime);
			}
			PassiveEffects.RefreshWrathbound(player);
		}

		public static bool Has(float amount)
		{
			if (!MaximumIsLocked(Player.m_localPlayer))
			{
				return _value + 0.001f >= Mathf.Max(0f, amount);
			}
			return true;
		}

		public static bool Spend(float amount)
		{
			if (!Has(amount))
			{
				return false;
			}
			TouchCombat();
			if (!MaximumIsLocked(Player.m_localPlayer))
			{
				_value = Mathf.Max(0f, _value - Mathf.Max(0f, amount));
			}
			return true;
		}

		public static void AddFromWarCry(float amount)
		{
			Add(amount);
		}

		public static void FillForRageUnbound()
		{
			_value = 100f;
			TouchCombat();
		}

		public static void EmptyAfterRageUnbound()
		{
			_value = 0f;
			_lastCombatAt = Time.time;
		}

		public static void Reset(Player player)
		{
			_trackedPlayer = player;
			_value = 0f;
			_lastCombatAt = -999f;
			_wasDead = (Object)(object)player != (Object)null && ((Character)player).IsDead();
		}

		public static void AddFromDamageDealt(float effectiveDamage)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ClassSystem.GetClass(localPlayer) != PlayerClass.Berserker || effectiveDamage <= 0.01f)
			{
				return;
			}
			float num = Mathf.Clamp(2f + Mathf.Sqrt(effectiveDamage) * 0.75f, 2f, 14f);
			Add(RuneEffects.FuryGain(localPlayer, num * WeaponFuryScale(localPlayer)));
			float num2 = 0f;
			if (BerserkerClass.IsRageUnbound(localPlayer))
			{
				num2 = 0.15f;
			}
			if (BerserkerSpecializationEffects.IsBloodlust(localPlayer))
			{
				num2 = Mathf.Max(num2, 0.25f);
			}
			if (num2 > 0f)
			{
				float num3 = Mathf.Max(0f, ((Character)localPlayer).GetMaxHealth() - ((Character)localPlayer).GetHealth());
				if (num3 > 0.01f)
				{
					((Character)localPlayer).Heal(Mathf.Min(num3, effectiveDamage * num2), true);
				}
			}
		}

		public static void AddFromDamageTaken(float effectiveDamage)
		{
			if (!(effectiveDamage <= 0.01f))
			{
				Add(Mathf.Clamp(10f + effectiveDamage * 0.16f, 10f, 26f));
			}
		}

		private static float WeaponFuryScale(Player player)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			ItemData val = ((player != null) ? ((Humanoid)player).GetCurrentWeapon() : null);
			if (val == null || val.m_shared == null)
			{
				return 1f;
			}
			ItemType itemType = val.m_shared.m_itemType;
			if ((int)itemType == 14 || (int)itemType == 22)
			{
				return 1.35f;
			}
			return 0.78f;
		}

		private static void Add(float amount)
		{
			if (MaximumIsLocked(Player.m_localPlayer))
			{
				_value = 100f;
			}
			else
			{
				_value = Mathf.Clamp(_value + Mathf.Max(0f, amount), 0f, 100f);
			}
			TouchCombat();
		}

		private static void TouchCombat()
		{
			_lastCombatAt = Time.time;
		}

		private static bool MaximumIsLocked(Player player)
		{
			return BerserkerClass.IsRageUnbound(player);
		}

		internal static bool IsMeleeSkill(SkillType skill)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			if ((int)skill != 1 && (int)skill != 2 && (int)skill != 3 && (int)skill != 4 && (int)skill != 5 && (int)skill != 7)
			{
				return (int)skill == 11;
			}
			return true;
		}

		internal static bool IsValidCombatTarget(Character target, Player attacker)
		{
			if ((Object)(object)target == (Object)null || (Object)(object)attacker == (Object)null || target.IsPlayer() || target.IsTamed())
			{
				return false;
			}
			string text = (((Object)(object)target.m_nview != (Object)null) ? target.m_nview.GetPrefabName() : ((Object)((Component)target).gameObject).name);
			if (!string.IsNullOrEmpty(text) && text.IndexOf("TrainingDummy", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			return BaseAI.IsEnemy(target, (Character)(object)attacker);
		}

		internal static void AwardDealtDamageFromWitness(long playerId, float effectiveDamage, SkillType skill)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (playerId != 0L && !(effectiveDamage <= 0.01f) && IsMeleeSkill(skill))
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && localPlayer.GetPlayerID() == playerId)
				{
					AddFromDamageDealt(effectiveDamage);
				}
				Network.BroadcastFuryHit(playerId, effectiveDamage);
			}
		}

		internal static void ReceiveRemoteHit(long playerId, float effectiveDamage)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && localPlayer.GetPlayerID() == playerId)
			{
				AddFromDamageDealt(effectiveDamage);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	public static class BerserkerOutgoingDamagePatch
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (hit != null && BerserkerFury.IsMeleeSkill(hit.m_skill))
			{
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && ClassSystem.GetClass(val) == PlayerClass.Berserker)
				{
					BerserkerClass.ModifyOutgoingMelee(__instance, val, hit);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "SetHealth")]
	public static class BerserkerIncomingDamagePatch
	{
		private static void Prefix(Character __instance, ref float health)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				float health2 = ((Character)val).GetHealth();
				if (!(health >= health2 - 0.01f))
				{
					BerserkerSpecializationEffects.ReduceIncomingDamage(val, health2, ref health);
					BerserkerClass.ReduceIncomingDamage(val, health2, ref health);
					RuneEffects.ReduceIncomingDamage(val, health2, ref health);
					BloodMageClass.AbsorbIncomingDamage(val, health2, ref health);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "AddStaggerDamage")]
	public static class JotunnStaggerResistancePatch
	{
		private static void Prefix(Character __instance, ref float damage)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				damage *= BerserkerSpecializationEffects.IncomingStaggerMultiplier(val);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyPushback", new Type[]
	{
		typeof(Vector3),
		typeof(float)
	})]
	public static class JotunnPushResistancePatch
	{
		private static void Prefix(Character __instance, ref float pushForce)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				pushForce *= BerserkerSpecializationEffects.IncomingPushMultiplier(val);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	public static class BerserkerIncomingDamageWitnessPatch
	{
		private struct DamageState
		{
			public Player Player;

			public float HealthBefore;

			public bool Hostile;
		}

		private static void Prefix(Character __instance, HitData hit, out DamageState __state)
		{
			__state = default(DamageState);
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && hit != null && ClassSystem.GetClass(val) == PlayerClass.Berserker && !((Object)(object)((Character)val).m_nview == (Object)null) && ((Character)val).m_nview.IsOwner())
			{
				Character attacker = hit.GetAttacker();
				__state.Player = val;
				__state.HealthBefore = ((Character)val).GetHealth();
				__state.Hostile = (Object)(object)attacker != (Object)null && (Object)(object)attacker != (Object)(object)val && BaseAI.IsEnemy(attacker, (Character)(object)val);
			}
		}

		private static void Postfix(DamageState __state)
		{
			if (__state.Hostile && !((Object)(object)__state.Player == (Object)null))
			{
				float effectiveDamage = Mathf.Max(0f, __state.HealthBefore - ((Character)__state.Player).GetHealth());
				BerserkerFury.AddFromDamageTaken(effectiveDamage);
				RuneEffects.OnDamageTaken(__state.Player, effectiveDamage);
			}
		}
	}
	public sealed class BerserkerImpactVfxController : MonoBehaviour
	{
		public Light ImpactLight;

		public float LightIntensity = 2.2f;

		public float Lifetime = 3.2f;

		private float _startedAt;

		private void OnEnable()
		{
			_startedAt = Time.time;
			BerserkerVfxSupport.Play(((Component)this).transform);
			if ((Object)(object)ImpactLight != (Object)null)
			{
				ImpactLight.intensity = 0f;
				((Behaviour)ImpactLight).enabled = true;
			}
		}

		private void LateUpdate()
		{
			float num = Time.time - _startedAt;
			if ((Object)(object)ImpactLight != (Object)null && ((Behaviour)ImpactLight).enabled)
			{
				float num2 = BerserkerVfxSupport.Flash(num, 0.025f, 0.28f) * LightIntensity;
				ImpactLight.intensity = num2;
				if (num2 <= 0.001f && num > 0.5f)
				{
					((Behaviour)ImpactLight).enabled = false;
				}
			}
			if (num >= Lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public static class BerserkerSpecializationEffects
	{
		public const string RendName = "SE_Norns_Rend";

		public const string MaimName = "SE_Norns_Maim";

		public const string MountainSlowName = "SE_Norns_Mountainform";

		public const float RendVulnerability = 0.3f;

		public const float MaimSlow = 0.4f;

		public const float BloodlustDuration = 12f;

		public const float BloodlustLifeSteal = 0.25f;

		public const float SlaughterDuration = 12f;

		public const float SlaughterSpreadRadius = 6f;

		public const string GraspName = "SE_Norns_TitansGrasp";

		public const float GraspSlow = 0.35f;

		public const float BedrockDamageReduction = 0.12f;

		public const float BedrockStaggerResistance = 0.4f;

		public const float BedrockPushResistance = 0.4f;

		public const string RallyName = "SE_Norns_RallyStandard";

		public const string WardingName = "SE_Norns_WardingStandard";

		public const string WarbandStandsName = "SE_Norns_WarbandStands";

		public const string SunderedName = "SE_Norns_Sundered";

		public const float RallyDamageBonus = 1.15f;

		public const float WardingArmor = 30f;

		public const float WarbandStandsArmor = 18f;

		public const float WarbandStandsRegenPerTick = 3f;

		public const float SunderedSlow = 0.3f;

		public const float CommandDamageBonus = 0.12f;

		public const float CommandDamageReduction = 0.12f;

		public const string WarlordAuraName = "SE_Norns_WarlordAura";

		public const float WarlordAuraRadius = 15f;

		public const float WarlordAuraMaxBonus = 0.1f;

		public const int WarlordAuraTiers = 4;

		private static Player _statePlayer;

		private static float _bloodlustUntil;

		private static float _slaughterUntil;

		private static float _mountainUntil;

		private static float _jotunnFormUntil;

		public static void ResetState(Player player)
		{
			_statePlayer = player;
			_bloodlustUntil = 0f;
			_slaughterUntil = 0f;
			_mountainUntil = 0f;
			_jotunnFormUntil = 0f;
		}

		public static void Update(Player player)
		{
			EnsureState(player);
			if (!((Object)(object)player == (Object)null))
			{
				if (((Character)player).IsDead())
				{
					_bloodlustUntil = 0f;
					_slaughterUntil = 0f;
					_mountainUntil = 0f;
					_jotunnFormUntil = 0f;
				}
				RavagerClass.UpdateWounds(player);
				ApplyMountainSlow(player);
				WarlordClass.UpdateLocalStandards(player);
				WarlordClass.UpdateLocalAura(player);
				WarlordClass.UpdateAura(player);
			}
		}

		private static void EnsureState(Player player)
		{
			if (player != _statePlayer)
			{
				_statePlayer = player;
				_bloodlustUntil = 0f;
				_slaughterUntil = 0f;
				_mountainUntil = 0f;
				_jotunnFormUntil = 0f;
				RavagerClass.ClearWounds();
			}
		}

		public static bool IsSpecialized(Player player, BerserkerSpecialization thread)
		{
			if ((Object)(object)player != (Object)null && ClassSystem.GetClass(player) == PlayerClass.Berserker && ClassSystem.GetLevel(player) >= 50)
			{
				return ClassSystem.GetBerserkerSpecialization(player) == thread;
			}
			return false;
		}

		public static bool IsBloodlust(Player player)
		{
			if ((Object)(object)player != (Object)null && player == _statePlayer)
			{
				return Time.time < _bloodlustUntil;
			}
			return false;
		}

		public static bool IsSlaughter(Player player)
		{
			if ((Object)(object)player != (Object)null && player == _statePlayer)
			{
				return Time.time < _slaughterUntil;
			}
			return false;
		}

		public static void BeginBloodlust(Player player)
		{
			EnsureState(player);
			_bloodlustUntil = Time.time + 12f;
		}

		public static void BeginSlaughter(Player player)
		{
			EnsureState(player);
			_slaughterUntil = Time.time + 12f;
		}

		public static bool IsMountainform(Player player)
		{
			if ((Object)(object)player != (Object)null && player == _statePlayer)
			{
				return Time.time < _mountainUntil;
			}
			return false;
		}

		public static bool IsJotunnForm(Player player)
		{
			if ((Object)(object)player != (Object)null && player == _statePlayer)
			{
				return Time.time < _jotunnFormUntil;
			}
			return false;
		}

		public static void BeginMountainform(Player player)
		{
			EnsureState(player);
			_mountainUntil = Time.time + 12f;
		}

		public static void BeginJotunnForm(Player player)
		{
			EnsureState(player);
			_jotunnFormUntil = Time.time + 15f;
		}

		private static void ApplyMountainSlow(Player player)
		{
			if (((Character)player).m_seman == null)
			{
				return;
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_Norns_Mountainform");
			if (IsMountainform(player))
			{
				if (!((Character)player).m_seman.HaveStatusEffect(stableHashCode))
				{
					((Character)player).m_seman.AddStatusEffect(stableHashCode, true, 0, 0f);
				}
			}
			else if (((Character)player).m_seman.HaveStatusEffect(stableHashCode))
			{
				((Character)player).m_seman.RemoveStatusEffect(stableHashCode, true);
			}
		}

		public static void ReduceIncomingDamage(Player player, float previousHealth, ref float health)
		{
			if (health >= previousHealth)
			{
				return;
			}
			float num = 1f;
			if (IsSpecialized(player, BerserkerSpecialization.Jotunn))
			{
				num *= 0.88f;
				if (IsMountainform(player))
				{
					num *= 0.5f;
				}
			}
			else if (IsUnderCommand(player))
			{
				num *= 0.88f;
			}
			if (!(num >= 1f))
			{
				float num2 = previousHealth - health;
				health = previousHealth - num2 * num;
			}
		}

		public static float IncomingStaggerMultiplier(Player player)
		{
			if (!IsSpecialized(player, BerserkerSpecialization.Jotunn))
			{
				return 1f;
			}
			if (IsMountainform(player))
			{
				return 0f;
			}
			return 0.6f;
		}

		public static float IncomingPushMultiplier(Player player)
		{
			if (!IsSpecialized(player, BerserkerSpecialization.Jotunn))
			{
				return 1f;
			}
			if (IsMountainform(player) || IsJotunnForm(player))
			{
				return 0f;
			}
			return 0.6f;
		}

		public static float OutgoingStaggerMultiplier(Player player)
		{
			if (!IsJotunnForm(player))
			{
				return 1f;
			}
			return 2f;
		}

		public static int WarlordAuraTierFor(float furyNormalized)
		{
			return Mathf.Clamp(Mathf.CeilToInt(furyNormalized * 4f), 0, 4);
		}

		public static string WarlordAuraStatus(int tier)
		{
			if (tier > 0)
			{
				return "SE_Norns_WarlordAura" + tier;
			}
			return null;
		}

		public static string StandardStatusFor(WarlordClass.StandardKind kind)
		{
			return kind switch
			{
				WarlordClass.StandardKind.Rally => "SE_Norns_RallyStandard", 
				WarlordClass.StandardKind.Warding => "SE_Norns_WardingStandard", 
				WarlordClass.StandardKind.WarbandStands => "SE_Norns_WarbandStands", 
				_ => null, 
			};
		}

		public static bool IsUnderCommand(Player player)
		{
			if (!IsSpecialized(player, BerserkerSpecialization.Warlord))
			{
				return false;
			}
			if (((Character)player).m_seman == null)
			{
				return false;
			}
			if (!((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_RallyStandard")) && !((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_WardingStandard")))
			{
				return ((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_WarbandStands"));
			}
			return true;
		}

		public static float CommandMultiplier(Player caster)
		{
			if (!IsUnderCommand(caster))
			{
				return 1f;
			}
			return 1.12f;
		}

		public static float RendMultiplier(Player caster, Character target)
		{
			if ((Object)(object)caster == (Object)null || (Object)(object)target == (Object)null || target.m_seman == null)
			{
				return 1f;
			}
			if (RavagerClass.IsResolvingWound)
			{
				return 1f;
			}
			if (!IsSpecialized(caster, BerserkerSpecialization.Ravager))
			{
				return 1f;
			}
			if (!target.m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_Rend")))
			{
				return 1f;
			}
			return 1.3f;
		}

		public static void RegisterStatusEffects(Action<StatusEffect> register)
		{
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			if (register != null)
			{
				RendStatusEffect rendStatusEffect = ScriptableObject.CreateInstance<RendStatusEffect>();
				((Object)rendStatusEffect).name = "SE_Norns_Rend";
				((StatusEffect)rendStatusEffect).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Rend");
				((StatusEffect)rendStatusEffect).m_name = Loc.Token("status_rend_name");
				((StatusEffect)rendStatusEffect).m_tooltip = Loc.Token("status_rend_tooltip");
				((StatusEffect)rendStatusEffect).m_ttl = 10f;
				register((StatusEffect)(object)rendStatusEffect);
				SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val).name = "SE_Norns_Maim";
				((StatusEffect)val).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Maim");
				((StatusEffect)val).m_name = Loc.Token("status_maimed_name");
				((StatusEffect)val).m_tooltip = Loc.Token("status_maimed_tooltip");
				((StatusEffect)val).m_ttl = 5f;
				val.m_speedModifier = -0.4f;
				register((StatusEffect)(object)val);
				SE_Stats val2 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val2).name = "SE_Norns_TitansGrasp";
				((StatusEffect)val2).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_TitansGrasp");
				((StatusEffect)val2).m_name = Loc.Token("status_titans_grasp_name");
				((StatusEffect)val2).m_tooltip = Loc.Token("status_titans_grasp_tooltip");
				((StatusEffect)val2).m_ttl = 4f;
				val2.m_speedModifier = -0.35f;
				register((StatusEffect)(object)val2);
				SE_Stats val3 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val3).name = "SE_Norns_Mountainform";
				((StatusEffect)val3).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Mountainform");
				((StatusEffect)val3).m_name = Loc.Token("status_mountainform_name");
				((StatusEffect)val3).m_tooltip = Loc.Token("status_mountainform_tooltip");
				((StatusEffect)val3).m_ttl = 0f;
				((StatusEffect)val3).m_icon = SpellIcons.StatusFor(JotunnClass.Mountainform);
				val3.m_speedModifier = -0.25f;
				register((StatusEffect)(object)val3);
				SE_Stats val4 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val4).name = "SE_Norns_RallyStandard";
				((StatusEffect)val4).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_RallyStandard");
				((StatusEffect)val4).m_name = Loc.Token("status_rally_standard_name");
				((StatusEffect)val4).m_tooltip = Loc.Formatted("status_rally_standard_tooltip", 14.999998f);
				((StatusEffect)val4).m_ttl = 0f;
				((StatusEffect)val4).m_icon = SpellIcons.StatusFor(WarlordClass.RallyStandard);
				val4.m_modifyAttackSkill = (SkillType)999;
				val4.m_damageModifier = 1.15f;
				register((StatusEffect)(object)val4);
				SE_Stats val5 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val5).name = "SE_Norns_WardingStandard";
				((StatusEffect)val5).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_WardingStandard");
				((StatusEffect)val5).m_name = Loc.Token("status_warding_standard_name");
				((StatusEffect)val5).m_tooltip = Loc.Formatted("status_warding_standard_tooltip", 30f);
				((StatusEffect)val5).m_ttl = 0f;
				((StatusEffect)val5).m_icon = SpellIcons.StatusFor(WarlordClass.WardingStandard);
				val5.m_addArmor = 30f;
				register((StatusEffect)(object)val5);
				SE_Stats val6 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val6).name = "SE_Norns_WarbandStands";
				((StatusEffect)val6).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_WarbandStands");
				((StatusEffect)val6).m_name = Loc.Token("status_warband_stands_name");
				((StatusEffect)val6).m_tooltip = Loc.Formatted("status_warband_stands_tooltip", 18f);
				((StatusEffect)val6).m_ttl = 0f;
				((StatusEffect)val6).m_icon = SpellIcons.StatusFor(WarlordClass.TheWarbandStands);
				val6.m_addArmor = 18f;
				val6.m_tickInterval = 1f;
				val6.m_healthPerTick = 3f;
				register((StatusEffect)(object)val6);
				for (int i = 1; i <= 4; i++)
				{
					float num = (float)i / 4f;
					string text = "SE_Norns_WarlordAura" + i;
					SE_Stats val7 = ScriptableObject.CreateInstance<SE_Stats>();
					((Object)val7).name = text;
					((StatusEffect)val7).m_nameHash = StringExtensionMethods.GetStableHashCode(text);
					((StatusEffect)val7).m_name = Loc.Token("status_warlord_aura_name");
					((StatusEffect)val7).m_tooltip = Loc.Formatted("status_warlord_aura_tooltip", 0.1f * num * 100f);
					((StatusEffect)val7).m_ttl = 0f;
					((StatusEffect)val7).m_icon = SpellIcons.StatusFor(WarlordClass.RallyStandard);
					val7.m_modifyAttackSkill = (SkillType)999;
					val7.m_damageModifier = 1f + 0.1f * num;
					val7.m_speedModifier = 0.1f * num;
					register((StatusEffect)(object)val7);
				}
				SE_Stats val8 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val8).name = "SE_Norns_Sundered";
				((StatusEffect)val8).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Sundered");
				((StatusEffect)val8).m_name = Loc.Token("status_sundered_name");
				((StatusEffect)val8).m_tooltip = Loc.Token("status_sundered_tooltip");
				((StatusEffect)val8).m_ttl = 2.2f;
				val8.m_speedModifier = -0.3f;
				register((StatusEffect)(object)val8);
			}
		}
	}
	public sealed class RendStatusEffect : StatusEffect
	{
		public override void SetLevel(int itemLevel, float skillLevel)
		{
			((StatusEffect)this).SetLevel(itemLevel, skillLevel);
			if (skillLevel > 0.01f)
			{
				base.m_ttl = skillLevel;
			}
		}
	}
	public static class BerserkerSpecializations
	{
		public const float ExecutionRange = 7f;

		public const float ExecutionDamage = 70f;

		public const float ExecutionLowHealthMultiplier = 2.2f;

		public const float ExecutionThreshold = 0.5f;

		public const float EarthshatterRadius = 10f;

		public const float EarthshatterDamage = 75f;

		public const float EarthshatterRange = 16f;

		public const float EarthshatterMinRange = 6f;

		public const float EarthshatterApexHeight = 15f;

		public const float EarthshatterDiveVelocity = 28f;

		public const float WarbandRadius = 15f;

		public const float WarbandDuration = 12f;

		public const int WarbandSpiritCount = 3;

		public const float WarbandSpiritDamage = 6f;

		public static readonly BerserkerSpecialization[] All = new BerserkerSpecialization[3]
		{
			BerserkerSpecialization.Ravager,
			BerserkerSpecialization.Jotunn,
			BerserkerSpecialization.Warlord
		};

		public static readonly BerserkerSpecialization[] Choices = new BerserkerSpecialization[4]
		{
			BerserkerSpecialization.None,
			BerserkerSpecialization.Ravager,
			BerserkerSpecialization.Jotunn,
			BerserkerSpecialization.Warlord
		};

		private static readonly Spell RavagerSpell = new Spell
		{
			Id = "executioners_wake",
			UnlockLevel = 50,
			Cooldown = 60f,
			Resource = AbilityResource.Fury,
			ResourceCost = 70f,
			CastTime = 0f,
			BaseDamage = 70f,
			CastTrigger = null,
			Describe = (int lvl) => Loc.F("spell_executioners_wake_desc", Progression.Dmg(70f, lvl), 50f, 2.2f),
			Cast = CastExecutionersWake
		};

		private static readonly Spell JotunnSpell = new Spell
		{
			Id = "earthshatter",
			UnlockLevel = 50,
			Cooldown = 70f,
			Resource = AbilityResource.Fury,
			ResourceCost = 80f,
			CastTime = 0f,
			BaseDamage = 75f,
			CastTrigger = null,
			Describe = (int lvl) => Loc.F("spell_earthshatter_desc", 16f, Progression.Dmg(75f, lvl), 10f),
			Cast = CastEarthshatter
		};

		private static readonly Spell WarlordSpell = new Spell
		{
			Id = "warbands_oath",
			UnlockLevel = 50,
			Cooldown = 120f,
			Resource = AbilityResource.Fury,
			ResourceCost = 60f,
			CastTime = 0f,
			BaseDamage = 6f,
			CastEmote = "roar",
			CastTrigger = "gpower",
			Describe = (int lvl) => Loc.F("spell_warbands_oath_desc", 3, 12f),
			Cast = CastWarbandsOath
		};

		public static void ResetState(Player player)
		{
			WarbandSpirit.DismissOwned(player);
			WarlordClass.ResetState(player);
		}

		public static Spell SpellFor(BerserkerSpecialization specialization)
		{
			return specialization switch
			{
				BerserkerSpecialization.Ravager => RavagerSpell, 
				BerserkerSpecialization.Jotunn => JotunnSpell, 
				BerserkerSpecialization.Warlord => WarlordSpell, 
				_ => null, 
			};
		}

		public static Spell CoreSpellFor(Player player, int index, Spell core)
		{
			if (core == null || (Object)(object)player == (Object)null || ClassSystem.GetLevel(player) < 50)
			{
				return core;
			}
			switch (ClassSystem.GetBerserkerSpecialization(player))
			{
			case BerserkerSpecialization.Ravager:
				if (index < 0 || index >= RavagerClass.Spells.Length)
				{
					return core;
				}
				return RavagerClass.Spells[index];
			case BerserkerSpecialization.Jotunn:
				if (index < 0 || index >= JotunnClass.Spells.Length)
				{
					return core;
				}
				return JotunnClass.Spells[index];
			case BerserkerSpecialization.Warlord:
				if (index < 0 || index >= WarlordClass.Spells.Length)
				{
					return core;
				}
				return WarlordClass.Spells[index];
			default:
				return core;
			}
		}

		public static string NameOf(BerserkerSpecialization specialization)
		{
			return Loc.T("spec_berserker_" + KeyOf(specialization) + "_name");
		}

		private static string KeyOf(BerserkerSpecialization specialization)
		{
			return specialization switch
			{
				BerserkerSpecialization.Ravager => "ravager", 
				BerserkerSpecialization.Jotunn => "jotunn", 
				BerserkerSpecialization.Warlord => "warlord", 
				_ => "none", 
			};
		}

		public static string DescriptionOf(BerserkerSpecialization specialization)
		{
			return Loc.T("spec_berserker_" + KeyOf(specialization) + "_desc");
		}

		public static Color AccentOf(BerserkerSpecialization specialization)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(specialization switch
			{
				BerserkerSpecialization.Ravager => new Color(0.96f, 0.18f, 0.12f), 
				BerserkerSpecialization.Jotunn => new Color(0.66f, 0.63f, 0.58f), 
				BerserkerSpecialization.Warlord => new Color(0.94f, 0.68f, 0.24f), 
				_ => ClassArt.AccentOf(PlayerClass.Berserker), 
			});
		}

		public static string ShortNameOf(BerserkerSpecialization specialization)
		{
			return Loc.T("spec_berserker_" + KeyOf(specialization) + "_short");
		}

		private static void CastExecutionersWake(Player player, int level)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_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)
			Vector3 position = ((Component)player).transform.position;
			Vector3 val = Effects.AimDirection(player);
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				val = ((Component)player).transform.forward;
			}
			((Vector3)(ref val)).Normalize();
			Vector3 b = position + val * 7f;
			((Component)player).transform.rotation = Quaternion.LookRotation(val, Vector3.up);
			BerserkerClass.TriggerWeaponSwing(player);
			SpellFx.PlayShared(FxKind.ExecutionersWake, position, b);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(ExecutionersWakeDamage(player, level, val));
		}

		private static IEnumerator ExecutionersWakeDamage(Player player, int level, Vector3 forward)
		{
			//IL_0015: 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)
			yield return (object)new WaitForSeconds(0.2f);
			if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker)
			{
				yield break;
			}
			Vector3 position = ((Component)player).transform.position;
			float num = Progression.Dmg(70f, level);
			foreach (Character item in Effects.EnemiesInRange(position, 7f, (Character)(object)player))
			{
				Vector3 val = ((Component)item).transform.position - position;
				val.y = 0f;
				if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f) || !(Vector3.Dot(forward, ((Vector3)(ref val)).normalized) < 0.57f))
				{
					float slash = ((((item.GetMaxHealth() > 0f) ? (item.GetHealth() / item.GetMaxHealth()) : 1f) <= 0.5f) ? (num * 2.2f) : num);
					Effects.DealDamage(player, item, new DamageTypes
					{
						m_slash = slash
					}, null, 30f);
				}
			}
		}

		private static void CastEarthshatter(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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = EarthshatterTarget(player);
			Vector3 val2 = val - ((Component)player).transform.position;
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = ((Component)player).transform.forward;
			}
			((Vector3)(ref val2)).Normalize();
			((Component)player).transform.rotation = Quaternion.LookRotation(val2, Vector3.up);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(EarthshatterLeap(player, level, val));
		}

		private static Vector3 EarthshatterTarget(Player player)
		{
			//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			Vector3 val = Effects.AimDirection(player);
			Vector3 val2 = val;
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				val2 = ((Component)player).transform.forward;
			}
			((Vector3)(ref val2)).Normalize();
			float num = Mathf.Lerp(6f, 16f, Mathf.Clamp01(((Vector3)(ref val2)).magnitude * (1f - Mathf.Clamp01(0f - val.y))));
			num = Mathf.Clamp(num, 6f, 16f);
			return Effects.SurfacePoint(position + val2 * num);
		}

		private static IEnumerator EarthshatterLeap(Player player, int level, Vector3 targetSurface)
		{
			//IL_0015: 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)
			if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker || (Object)(object)((Character)player).m_body == (Object)null)
			{
				yield break;
			}
			if ((Object)(object)((Character)player).m_zanim != (Object)null)
			{
				((Character)player).m_zanim.SetTrigger("jump");
			}
			Vector3 start = ((Character)player).m_body.position;
			float num = Mathf.Clamp(start.y - Effects.SurfacePoint(start).y, 0.05f, 0.8f);
			Vector3 target = targetSurface + Vector3.up * num;
			Vector3 apex = Vector3.Lerp(start, target, 0.44f);
			apex.y = Mathf.Max(start.y, target.y) + 15f;
			float elapsed = 0f;
			while (elapsed < 0.9f)
			{
				yield return (object)new WaitForFixedUpdate();
				if (!CanContinueEarthshatter(player))
				{
					yield break;
				}
				elapsed += Time.fixedDeltaTime;
				float num2 = Mathf.Clamp01(elapsed / 0.9f);
				float num3 = num2 * num2 * (3f - 2f * num2);
				MoveEarthshatterBody(player, Vector3.Lerp(start, apex, num3));
			}
			float holdUntil = Time.time + 0.1f;
			while (Time.time < holdUntil)
			{
				yield return (object)new WaitForFixedUpdate();
				if (!CanContinueEarthshatter(player))
				{
					yield break;
				}
				MoveEarthshatterBody(player, apex);
			}
			SpellFx.PlayShared(FxKind.EarthshatterDive, ((Component)player).transform.position, targetSurface);
			BerserkerClass.SuppressAnimationAttacks(player, 1.6f);
			BerserkerClass.TriggerWeaponSwing(player);
			Vector3 diveStart = ((Character)player).m_body.position;
			float diveDuration = Mathf.Clamp(Vector3.Distance(diveStart, target) / 28f, 0.46f, 0.82f);
			elapsed = 0f;
			while (elapsed < diveDuration)
			{
				yield return (object)new WaitForFixedUpdate();
				if (!CanContinueEarthshatter(player))
				{
					yield break;
				}
				elapsed += Time.fixedDeltaTime;
				float num4 = Mathf.Clamp01(elapsed / diveDuration);
				float num5 = num4 * num4;
				MoveEarthshatterBody(player, Vector3.Lerp(diveStart, target, num5));
			}
			if (!CanContinueEarthshatter(player))
			{
				yield break;
			}
			MoveEarthshatterBody(player, target);
			yield return (object)new WaitForFixedUpdate();
			if (!CanContinueEarthshatter(player))
			{
				yield break;
			}
			((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
			((Character)player).m_body.linearVelocity = Vector3.zero;
			Vector3 val = Effects.SurfacePoint(targetSurface);
			SpellFx.PlayShared(FxKind.Earthshatter, val, val);
			float blunt = Progression.Dmg(75f, level);
			foreach (Character item in Effects.EnemiesInRange(val, 10f, (Character)(object)player))
			{
				Effects.DealDamage(player, item, new DamageTypes
				{
					m_blunt = blunt
				}, null, 75f);
			}
		}

		private static void MoveEarthshatterBody(Player player, Vector3 position)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0038: 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)
			float num = Mathf.Max(0.001f, Time.fixedDeltaTime);
			((Character)player).m_body.linearVelocity = (position - ((Character)player).m_body.position) / num;
			((Character)player).m_body.MovePosition(position);
			((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y;
		}

		private static bool CanContinueEarthshatter(Player player)
		{
			if ((Object)(object)player != (Object)null && !((Character)player).IsDead() && (Object)(object)((Character)player).m_body != (Object)null)
			{
				return ClassSystem.GetClass(player) == PlayerClass.Berserker;
			}
			return false;
		}

		private static void CastWarbandsOath(Player player, int level)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Vector3 position = ((Component)player).transform.position;
			SpellFx.PlayShared(FxKind.WarbandsOath, position, position);
			if (!WarbandSpirit.Ready)
			{
				XpSystem.Message(player, Loc.T("msg_warband_no_answer"));
				return;
			}
			WarbandSpirit.DismissOwned(player);
			WarbandSpirit.Summon(player, 3, Progression.Dmg(6f, level), 12f);
			XpSystem.Message(player, "Warband's Oath — the fallen answer");
		}
	}
	internal static class BerserkerVfxSupport
	{
		public static Player FindNearestPlayer(Vector3 position, float maximumDistance = 4.5f)
		{
			//IL_0022: 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)
			Player result = null;
			float num = maximumDistance;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (!((Object)(object)allPlayer == (Object)null))
				{
					float num2 = Vector3.Distance(position, ((Component)allPlayer).transform.position);
					if (!(num2 >= num))
					{
						num = num2;
						result = allPlayer;
					}
				}
			}
			return result;
		}

		public static Transform ChestAnchor(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			Animator componentInChildren = ((Component)player).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren == (Object)null || !componentInChildren.isHuman)
			{
				return null;
			}
			return componentInChildren.GetBoneTransform((HumanBodyBones)54) ?? componentInChildren.GetBoneTransform((HumanBodyBones)8) ?? componentInChildren.GetBoneTransform((HumanBodyBones)7);
		}

		public static void Play(Transform group)
		{
			if ((Object)(object)group == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Play(true);
				}
			}
		}

		public static void StopEmitting(Transform group)
		{
			if ((Object)(object)group == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Stop(true, (ParticleSystemStopBehavior)1);
				}
			}
		}

		public static void StopAndClear(Transform group)
		{
			if ((Object)(object)group == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
		}

		public static float Smooth01(float value)
		{
			value = Mathf.Clamp01(value);
			return value * value * (3f - 2f * value);
		}

		public static float Flash(float elapsed, float attack, float decay)
		{
			if (elapsed < 0f)
			{
				return 0f;
			}
			if (elapsed < attack)
			{
				return Smooth01(elapsed / Mathf.Max(0.0001f, attack));
			}
			return 1f - Smooth01((elapsed - attack) / Mathf.Max(0.0001f, decay));
		}
	}
	public static class BerserkerWeapons
	{
		public const string UruzCleaverPrefab = "NornsUruzCleaver";

		private static bool _hooked;

		private static bool _created;

		public static void Register()
		{
			if (!_hooked)
			{
				_hooked = true;
				PrefabManager.OnVanillaPrefabsAvailable += Create;
			}
		}

		public static void Shutdown()
		{
			if (_hooked)
			{
				PrefabManager.OnVanillaPrefabsAvailable -= Create;
			}
			_hooked = false;
		}

		private static void Create()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			PrefabManager.OnVanillaPrefabsAvailable -= Create;
			_hooked = false;
			if (_created)
			{
				return;
			}
			try
			{
				ItemConfig val = new ItemConfig();
				val.Name = Loc.Token("item_uruz_cleaver_name");
				val.Description = Loc.Token("item_uruz_cleaver_desc");
				val.CraftingStation = CraftingStations.Workbench;
				val.RepairStation = CraftingStations.Workbench;
				val.MinStationLevel = 1;
				val.Weight = 4.5f;
				val.Icon = LoadIcon("uruz_cleaver.jpg");
				val.Requirements = (RequirementConfig[])(object)new RequirementConfig[4]
				{
					new RequirementConfig("Wood", 12, 4, true),
					new RequirementConfig("Flint", 8, 4, true),
					new RequirementConfig("LeatherScraps", 4, 2, true),
					new RequirementConfig("DeerHide", 2, 1, true)
				};
				ItemConfig val2 = val;
				CustomItem val3 = new CustomItem("NornsUruzCleaver", "Battleaxe", val2);
				if ((Object)(object)val3.ItemPrefab == (Object)null || (Object)(object)val3.ItemDrop == (Object)null)
				{
					Plugin.Log.LogError((object)"Impossibile clonare Battleaxe per Uruz Cleaver.");
					return;
				}
				SharedData shared = val3.ItemDrop.m_itemData.m_shared;
				shared.m_itemType = (ItemType)14;
				shared.m_skillType = (SkillType)7;
				shared.m_damages = new DamageTypes
				{
					m_slash = 24f,
					m_blunt = 4f
				};
				shared.m_damagesPerLevel = new DamageTypes
				{
					m_slash = 3f,
					m_blunt = 1f
				};
				shared.m_attackForce = 55f;
				shared.m_backstabBonus = 3f;
				shared.m_blockPower = 12f;
				shared.m_blockPowerPerLevel = 3f;
				shared.m_deflectionForce = 20f;
				shared.m_deflectionForcePerLevel = 5f;
				shared.m_timedBlockBonus = 2f;
				shared.m_maxQuality = 4;
				shared.m_useDurability = true;
				shared.m_maxDurability = 140f;
				shared.m_durabilityPerLevel = 45f;
				shared.m_movementModifier = -0.08f;
				if (shared.m_attack != null)
				{
					shared.m_attack = shared.m_attack.Clone();
					shared.m_attack.m_attackStamina = 12f;
				}
				if (shared.m_secondaryAttack != null)
				{
					shared.m_secondaryAttack = shared.m_secondaryAttack.Clone();
					shared.m_secondaryAttack.m_attackStamina = 18f;
				}
				NornsStaffModels.ReplaceVanillaVisual(val3.ItemPrefab, NornsStaffModels.Style.UruzCleaver);
				if (!ItemManager.Instance.AddItem(val3))
				{
					Plugin.Log.LogError((object)"Jotunn ha rifiutato Uruz Cleaver.");
					return;
				}
				_created = true;
				Plugin.Log.LogInfo((object)"Uruz Cleaver iniziale registrata.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Registrazione di Uruz Cleaver fallita: {arg}");
			}
		}

		private static Sprite LoadIcon(string fileName)
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (string.IsNullOrEmpty(directoryName))
			{
				return null;
			}
			string text = Path.Combine(directoryName, "art", "items", fileName);
			if (!File.Exists(text))
			{
				Plugin.Log.LogWarning((object)("Icona arma Berserker non trovata: " + text));
				return null;
			}
			return AssetUtils.LoadSpriteFromFile(text);
		}
	}
	public sealed class BlackHoleVfxController : MonoBehaviour
	{
		public const float DefaultActiveDuration = 6f;

		public const float DefaultResidualDuration = 1.2f;

		public Transform GroundFieldGroup;

		public Transform GroundVortexGroup;

		public Transform GroundVortexCounterGroup;

		public Transform SingularityGroup;

		public Transform AccretionGroup;

		public Transform AccretionCounterGroup;

		public Transform GravityFlowGroup;

		public Light EffectLight;

		public float ActiveDuration = 6f;

		public float ResidualDuration = 1.2f;

		private Vector3 _groundFieldScale;

		private Quaternion _groundVortexRotation;

		private Quaternion _groundVortexCounterRotation;

		private Vector3 _singularityScale;

		private Vector3 _singularityPosition;

		private Vector3 _accretionScale;

		private Vector3 _counterScale;

		private Vector3 _gravityFlowScale;

		private Camera _camera;

		private float _startedAt;

		private bool _implosionPlayed;

		private void OnEnable()
		{
			//IL_001c: 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_0021: 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_0035: 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_0068: 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_006d: 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_0081: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unkn