Decompiled source of Norns v1.0.0

plugins/Norns/Norns.dll

Decompiled 15 hours 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 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("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c72d205cdc20a34c85d34434e7954e2625ec15d2")]
[assembly: AssemblyProduct("Norns")]
[assembly: AssemblyTitle("Norns")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 PassiveName = "Wrathbound";

		public const float RendingWindow = 8f;

		public const float RendingDamage = 34f;

		public const float WarCryRadius = 8f;

		public const float WarCryDamage = 35f;

		public const float BloodstormRadius = 5f;

		public const float BloodstormDamage = 28f;

		public const int BloodstormPulses = 3;

		public const float BloodstormDuration = 1.2f;

		public const float BloodstormInterval = 0.4f;

		public const float BearskinDuration = 12f;

		public const float BearskinDamageReduction = 0.4f;

		public const float RageDuration = 12f;

		public const float RageLifeSteal = 0.15f;

		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
			{
				Name = "Rending Blow",
				Flavor = "the next edge bites deeper",
				UnlockLevel = 10,
				Cooldown = 5f,
				Resource = AbilityResource.Fury,
				ResourceCost = 20f,
				CastTime = 0f,
				BaseDamage = 34f,
				CastTrigger = null,
				Describe = (int lvl) => $"Your next melee hit within {8f:0} s tears for " + $"{Progression.Dmg(34f, lvl):0} additional slash damage and heavy stagger.",
				Cast = ArmRendingBlow
			},
			new Spell
			{
				Name = "War Cry",
				Flavor = "your voice breaks the enemy line",
				UnlockLevel = 20,
				Cooldown = 14f,
				Resource = AbilityResource.Fury,
				ResourceCost = 30f,
				CastTime = 0f,
				BaseDamage = 35f,
				CastTrigger = "gpower",
				Describe = (int lvl) => $"A violent cry deals {Progression.Dmg(35f, lvl):0} blunt damage " + $"and drives enemies back within {8f:0} m.",
				Cast = CastWarCry
			},
			new Spell
			{
				Name = "Bloodstorm",
				Flavor = "steel turns three times around you",
				UnlockLevel = 30,
				Cooldown = 18f,
				Resource = AbilityResource.Fury,
				ResourceCost = 45f,
				CastTime = 0f,
				BaseDamage = 28f,
				CastTrigger = null,
				Describe = (int lvl) => "Three sweeping strikes each deal " + $"{Progression.Dmg(28f, lvl):0} slash damage within {5f:0} m " + "as you spin with the blood-wind.",
				Cast = CastBloodstorm
			},
			new Spell
			{
				Name = "Bearskin",
				Flavor = "hide and fury turn the enemy edge",
				UnlockLevel = 40,
				Cooldown = 60f,
				Resource = AbilityResource.Fury,
				ResourceCost = 55f,
				CastTime = 0f,
				BaseDamage = 0f,
				CastTrigger = "gpower",
				Describe = (int lvl) => $"Reduce incoming damage by {40f:0}% " + $"for {12f:0} s.",
				Cast = CastBearskin
			},
			new Spell
			{
				Name = "Rage Unbound",
				Flavor = "there is no wound, only wrath",
				UnlockLevel = 50,
				Cooldown = 100f,
				Resource = AbilityResource.Fury,
				ResourceCost = 100f,
				CastTime = 1.5f,
				BaseDamage = 0f,
				CastTrigger = "gpower",
				Describe = (int lvl) => $"For {12f:0} s Fury stays full, Wrathbound is doubled, " + $"and melee damage heals {15.000001f:0}% of the health actually lost.",
				Cast = CastRageUnbound
			}
		};

		public static string PassiveDescription(int level)
		{
			return "Wrathbound — melee hits and hostile wounds build Fury. Fury grants up to " + $"{MaximumMeleeBonus(level) * 100f:0}% physical melee damage and fades after " + $"{5f:0} s out of combat.";
		}

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

		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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_00fc: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			EnsureState(attacker);
			float num = MaximumMeleeBonus(ClassSystem.GetLevel(attacker)) * BerserkerFury.Normalized;
			if (IsRageUnbound(attacker))
			{
				num *= 2f;
			}
			float num2 = 1f + num;
			hit.m_damage.m_blunt *= num2;
			hit.m_damage.m_slash *= num2;
			hit.m_damage.m_pierce *= num2;
			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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			float blunt = Progression.Dmg(35f, level);
			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 = blunt
				}, null, 45f);
			}
		}

		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);
			for (int pulse = 0; pulse < 3; pulse++)
			{
				if ((Object)(object)player == (Object)null)
				{
					yield break;
				}
				if (((Character)player).IsDead())
				{
					((Component)player).transform.rotation = startRotation;
					yield break;
				}
				TriggerWeaponSwing(player);
				float elapsed = 0f;
				bool dealtDamage = false;
				while (elapsed < 0.4f)
				{
					if ((Object)(object)player == (Object)null)
					{
						yield break;
					}
					if (((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker)
					{
						((Component)player).transform.rotation = startRotation;
						yield break;
					}
					float num = (float)pulse + Mathf.Clamp01(elapsed / 0.4f);
					((Component)player).transform.rotation = startRotation * Quaternion.Euler(0f, num * 360f, 0f);
					if (!dealtDamage && elapsed >= 0.20799999f)
					{
						DealBloodstormPulse(player, damage);
						dealtDamage = true;
					}
					elapsed += Time.deltaTime;
					yield return null;
				}
				if (!dealtDamage)
				{
					DealBloodstormPulse(player, damage);
				}
			}
			((Component)player).transform.rotation = startRotation;
		}

		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 TriggerWeaponSwing(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			float stamina = player.GetStamina();
			if (((Character)player).StartAttack((Character)null, false))
			{
				_animationAttackPlayer = player;
				_suppressAnimationAttackUntil = Time.time + 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, "Bearskin — damage reduced");
		}

		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(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 = 7.5f;

		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)
			{
				_value = Mathf.MoveTowards(_value, 0f, 7.5f * Time.deltaTime);
			}
		}

		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 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;
			}
			Add(Mathf.Clamp(2f + Mathf.Sqrt(effectiveDamage) * 0.75f, 2f, 14f));
			if (BerserkerClass.IsRageUnbound(localPlayer))
			{
				float num = Mathf.Max(0f, ((Character)localPlayer).GetMaxHealth() - ((Character)localPlayer).GetHealth());
				if (num > 0.01f)
				{
					((Character)localPlayer).Heal(Mathf.Min(num, effectiveDamage * 0.15f), true);
				}
			}
		}

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

		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))
				{
					BerserkerSpecializations.ReduceIncomingDamage(val, health2, ref health);
					BerserkerClass.ReduceIncomingDamage(val, health2, ref health);
				}
			}
		}
	}
	[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))
			{
				BerserkerFury.AddFromDamageTaken(Mathf.Max(0f, __state.HealthBefore - ((Character)__state.Player).GetHealth()));
			}
		}
	}
	public static class BerserkerSpecializations
	{
		public const float ExecutionRange = 7f;

		public const float ExecutionDamage = 95f;

		public const float ExecutionLowHealthMultiplier = 1.5f;

		public const float EarthshatterRadius = 10f;

		public const float EarthshatterDamage = 75f;

		public const float EarthshatterRange = 24f;

		public const float EarthshatterApexHeight = 15f;

		public const float EarthshatterDiveVelocity = 28f;

		public const float WarbandRadius = 15f;

		public const float WarbandDuration = 18f;

		public const float WarbandDamageReduction = 0.25f;

		private static Player _warbandPlayer;

		private static float _warbandUntil;

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

		private static readonly Spell RavagerSpell = new Spell
		{
			Name = "Executioner's Wake",
			Flavor = "the wounded fall where your edge passes",
			UnlockLevel = 50,
			Cooldown = 60f,
			Resource = AbilityResource.Fury,
			ResourceCost = 70f,
			CastTime = 0f,
			BaseDamage = 95f,
			CastTrigger = null,
			Describe = (int lvl) => $"Cleave a wide path for {Progression.Dmg(95f, lvl):0} slash damage; " + $"foes below 35% health suffer {1.5f:0.0}x damage.",
			Cast = CastExecutionersWake
		};

		private static readonly Spell JotunnSpell = new Spell
		{
			Name = "Earthshatter",
			Flavor = "the ground remembers the feet of giants",
			UnlockLevel = 50,
			Cooldown = 70f,
			Resource = AbilityResource.Fury,
			ResourceCost = 80f,
			CastTime = 0f,
			BaseDamage = 75f,
			CastTrigger = null,
			Describe = (int lvl) => $"Leap up to {24f:0} m toward the aim, then plunge down like " + "Yagluth's meteor. The impact deals " + $"{Progression.Dmg(75f, lvl):0} blunt damage within {10f:0} m " + "and immense knockback.",
			Cast = CastEarthshatter
		};

		private static readonly Spell WarlordSpell = new Spell
		{
			Name = "Warband's Oath",
			Flavor = "all who stand with you become one shield",
			UnlockLevel = 50,
			Cooldown = 90f,
			Resource = AbilityResource.Fury,
			ResourceCost = 60f,
			CastTime = 0f,
			BaseDamage = 0f,
			CastTrigger = "gpower",
			Describe = (int lvl) => $"You and nearby players within {15f:0} m take " + $"{25f:0}% less damage for {18f:0} s.",
			Cast = CastWarbandsOath
		};

		public static void ResetState(Player player)
		{
			_warbandPlayer = player;
			_warbandUntil = 0f;
		}

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

		public static string NameOf(BerserkerSpecialization specialization)
		{
			return specialization switch
			{
				BerserkerSpecialization.Ravager => "Ravager", 
				BerserkerSpecialization.Jotunn => "Jötunn", 
				BerserkerSpecialization.Warlord => "Warlord", 
				_ => "Unwoven", 
			};
		}

		public static string DescriptionOf(BerserkerSpecialization specialization)
		{
			return specialization switch
			{
				BerserkerSpecialization.Ravager => "Finish wounded enemies with merciless sweeping blows.", 
				BerserkerSpecialization.Jotunn => "Carry the weight of giants and break the battlefield.", 
				BerserkerSpecialization.Warlord => "Turn your fury into an oath that protects the warband.", 
				_ => "Choose whether your fury destroys, endures, or commands.", 
			};
		}

		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.52f, 0.76f, 0.92f), 
				BerserkerSpecialization.Warlord => new Color(0.94f, 0.68f, 0.24f), 
				_ => ClassArt.AccentOf(PlayerClass.Berserker), 
			});
		}

		public static string ShortNameOf(BerserkerSpecialization specialization)
		{
			return specialization switch
			{
				BerserkerSpecialization.Ravager => "RAVAGE", 
				BerserkerSpecialization.Jotunn => "JÖTUNN", 
				BerserkerSpecialization.Warlord => "WARLORD", 
				_ => "—", 
			};
		}

		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(95f, 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.35f) ? (num * 1.5f) : 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_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_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_0056: 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)
			Vector3 position = ((Component)player).transform.position;
			Vector3 val = Effects.SurfacePoint(Effects.AimPoint(player, 24f));
			Vector3 val2 = val - position;
			val2.y = 0f;
			if (((Vector3)(ref val2)).magnitude > 24f)
			{
				val = Effects.SurfacePoint(position + ((Vector3)(ref val2)).normalized * 24f);
			}
			return val;
		}

		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);
			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_000c: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			ApplyWarbandLocal(position);
			Network.BroadcastWarband(position);
			SpellFx.PlayShared(FxKind.WarbandsOath, position, position);
		}

		public static void ApplyWarbandLocal(Vector3 center)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && !(Vector3.Distance(((Component)localPlayer).transform.position, center) > 15f))
			{
				_warbandPlayer = localPlayer;
				_warbandUntil = Mathf.Max(_warbandUntil, Time.time + 18f);
				PassiveEffects.ApplyWarband(localPlayer);
				XpSystem.Message(localPlayer, "Warband's Oath — damage reduced");
			}
		}

		public static void ReduceIncomingDamage(Player player, float previousHealth, ref float health)
		{
			if (!((Object)(object)player == (Object)null) && player == _warbandPlayer && !(Time.time >= _warbandUntil) && !(health >= previousHealth))
			{
				float num = previousHealth - health;
				health = previousHealth - num * 0.75f;
			}
		}
	}
	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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0127: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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 = "Uruz Cleaver";
				val.Description = "A brutal two-handed cleaver of flint, bone and bound wood. Its first rune teaches young Berserkers to put both hands behind every blow.";
				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: Unknown result type (might be due to invalid IL or missing references)
			_groundFieldScale = (((Object)(object)GroundFieldGroup != (Object)null) ? GroundFieldGroup.localScale : Vector3.one);
			_groundVortexRotation = (((Object)(object)GroundVortexGroup != (Object)null) ? GroundVortexGroup.localRotation : Quaternion.identity);
			_groundVortexCounterRotation = (((Object)(object)GroundVortexCounterGroup != (Object)null) ? GroundVortexCounterGroup.localRotation : Quaternion.identity);
			_singularityScale = (((Object)(object)SingularityGroup != (Object)null) ? SingularityGroup.localScale : Vector3.one);
			_singularityPosition = (((Object)(object)SingularityGroup != (Object)null) ? SingularityGroup.localPosition : Vector3.zero);
			_accretionScale = (((Object)(object)AccretionGroup != (Object)null) ? AccretionGroup.localScale : Vector3.one);
			_counterScale = (((Object)(object)AccretionCounterGroup != (Object)null) ? AccretionCounterGroup.localScale : Vector3.one);
			_gravityFlowScale = (((Object)(object)GravityFlowGroup != (Object)null) ? GravityFlowGroup.localScale : Vector3.one);
			_camera = Camera.main;
			_startedAt = Time.time;
			_implosionPlayed = false;
			Apply(0f);
		}

		private void Update()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.time - _startedAt;
			Apply(num);
			if (!_implosionPlayed && num >= ActiveDuration)
			{
				_implosionPlayed = true;
				SpellAudio.PlayBlackHoleImplosion(((Component)this).transform.position);
			}
			if (num >= ActiveDuration + ResidualDuration + 0.15f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void Apply(float elapsed)
		{
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: 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_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			float num = Smooth01(elapsed / 0.46f);
			float num2 = Smooth01((elapsed - (ActiveDuration - 1.2f)) / 0.75f);
			float num3 = Smooth01((elapsed - (ActiveDuration - 0.45f)) / 0.45f);
			float num4 = Mathf.Clamp01((elapsed - ActiveDuration) / Mathf.Max(0.01f, ResidualDuration));
			float num5 = Mathf.Sin(elapsed * 2.35f) * 0.012f + Mathf.Sin(elapsed * 4.77f + 0.8f) * 0.007f;
			float num6 = Mathf.Repeat(elapsed, 0.5f) / 0.5f;
			float num7 = Mathf.Pow(1f - num6, 5f) * num * (1f - num2) * 0.014f;
			float num8 = Smooth01(elapsed / 0.42f);
			float num9 = Mathf.Max(0.001f, Mathf.Lerp(0.1f, 1f, num8) * (1f - num3));
			float num10 = Mathf.Max(0.001f, Mathf.Lerp(0.05f, 1f + num5 + num2 * 0.035f, num) * (1f - num7) * (1f - num3));
			float num11 = Mathf.Max(0.001f, Mathf.Lerp(0.04f, 1f, Smooth01((elapsed - 0.08f) / 0.42f)) * (1f + num7 * 1.8f) * (1f - num3));
			float num12 = Mathf.Max(0.001f, Mathf.Lerp(0.18f, 1f, Smooth01((elapsed - 0.12f) / 0.48f)) * (1f - num3));
			if ((Object)(object)GroundFieldGroup != (Object)null)
			{
				GroundFieldGroup.localScale = _groundFieldScale * num9;
			}
			if ((Object)(object)GroundVortexGroup != (Object)null)
			{
				float num13 = elapsed * 10.5f + Mathf.Sin(elapsed * 1.28f) * 3.8f + Mathf.Sin(elapsed * 2.73f + 0.6f) * 1.6f + num2 * num2 * 34f;
				GroundVortexGroup.localRotation = _groundVortexRotation * Quaternion.Euler(0f, num13, 0f);
			}
			if ((Object)(object)GroundVortexCounterGroup != (Object)null)
			{
				float num14 = (0f - elapsed) * 16.5f + Mathf.Sin(elapsed * 1.91f + 1.4f) * 2.2f - num2 * num2 * 50f;
				GroundVortexCounterGroup.localRotation = _groundVortexCounterRotation * Quaternion.Euler(0f, num14, 0f);
			}
			if ((Object)(object)SingularityGroup != (Object)null)
			{
				float num15 = Mathf.Lerp(-1.72f, 0f, num);
				float num16 = Mathf.Sin(elapsed * 1.83f) * 0.025f * num * (1f - num2);
				SingularityGroup.localPosition = _singularityPosition + Vector3.up * (num15 + num16 - num3 * 0.18f);
				SingularityGroup.localScale = _singularityScale * num10;
			}
			if ((Object)(object)GravityFlowGroup != (Object)null)
			{
				GravityFlowGroup.localScale = _gravityFlowScale * num12;
			}
			if ((Object)(object)AccretionGroup != (Object)null)
			{
				AccretionGroup.localScale = _accretionScale * num11;
				float roll = elapsed * 18f + Mathf.Sin(elapsed * 1.71f) * 4.2f + num2 * num2 * 42f;
				AccretionGroup.rotation = FacingRotation(roll);
			}
			if ((Object)(object)AccretionCounterGroup != (Object)null)
			{
				AccretionCounterGroup.localScale = _counterScale * num11;
				float roll2 = (0f - elapsed) * 7.5f + Mathf.Sin(elapsed * 2.29f + 1.1f) * 2.6f - num2 * num2 * 18f;
				AccretionCounterGroup.rotation = FacingRotation(roll2);
			}
			if ((Object)(object)EffectLight != (Object)null)
			{
				float num17 = Mathf.Sin(Mathf.Clamp01(elapsed / 0.2f) * (float)Math.PI);
				float num18 = num2 * (0.1f + Mathf.Abs(Mathf.Sin(elapsed * 7.1f)) * 0.08f);
				float num19 = Mathf.Sin(Mathf.Clamp01((elapsed - ActiveDuration) / 0.1f) * (float)Math.PI) * 0.72f;
				float num20 = ((elapsed < ActiveDuration) ? (0.1f + num5 * 2f + num7 * 1.4f) : 0f);
				EffectLight.intensity = Mathf.Max(0f, (num17 * 0.42f + num20 + num18 + num19) * (1f - num4));
			}
		}

		private Quaternion FacingRotation(float roll)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_camera == (Object)null)
			{
				_camera = Camera.main;
			}
			if ((Object)(object)_camera == (Object)null)
			{
				return Quaternion.AngleAxis(roll, Vector3.forward);
			}
			Vector3 val = ((Component)_camera).transform.position - ((Component)this).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = Vector3.forward;
			}
			return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up) * Quaternion.AngleAxis(roll, Vector3.forward);
		}

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

		public float Lifetime = 1.65f;

		private ParticleSystem[] _particles;

		private float _startedAt;

		private float _cancelAt = -1f;

		private void OnEnable()
		{
			_particles = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			_startedAt = Time.time;
			Active.Add(this);
		}

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

		private void Update()
		{
			if (_cancelAt >= 0f)
			{
				if (Time.time - _cancelAt >= 0.24f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			else if (Time.time - _startedAt >= Lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public void Cancel()
		{
			//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)
			if (_cancelAt >= 0f)
			{
				return;
			}
			_cancelAt = Time.time;
			if (_particles == null)
			{
				return;
			}
			ParticleSystem[] particles = _particles;
			foreach (ParticleSystem val in particles)
			{
				if (!((Object)(object)val == (Object)null))
				{
					EmissionModule emission = val.emission;
					((EmissionModule)(ref emission)).enabled = false;
					val.Stop(true, (ParticleSystemStopBehavior)1);
				}
			}
		}

		public static void CancelNearest(Vector3 position, float maximumDistance = 3f)
		{
			//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)
			BlackHoleChargeVfxController blackHoleChargeVfxController = null;
			float num = maximumDistance;
			for (int num2 = Active.Count - 1; num2 >= 0; num2--)
			{
				BlackHoleChargeVfxController blackHoleChargeVfxController2 = Active[num2];
				if ((Object)(object)blackHoleChargeVfxController2 == (Object)null)
				{
					Active.RemoveAt(num2);
				}
				else
				{
					float num3 = Vector3.Distance(((Component)blackHoleChargeVfxController2).transform.position, position);
					if (!(num3 >= num))
					{
						num = num3;
						blackHoleChargeVfxController = blackHoleChargeVfxController2;
					}
				}
			}
			blackHoleChargeVfxController?.Cancel();
		}
	}
	public sealed class BloodHarvestVfxController : MonoBehaviour
	{
		public Transform FormationGroup;

		public Transform GroundRiteGroup;

		public Transform PulseGroup;

		public Transform SustainGroup;

		public Transform ResidualGroup;

		public Transform[] GroundAnchors;

		public LineRenderer[] HarvestTethers;

		public Light RitualLight;

		public float Radius = 8f;

		public int PulseCount = 5;

		public float PulseInterval = 0.68f;

		public float Lifetime = 3.48f;

		private readonly List<Character> _targets = new List<Character>();

		private float _startedAt;

		private bool _residualStarted;

		private void OnEnable()
		{
			_startedAt = Time.time;
			_residualStarted = false;
			CacheTargets();
			ProjectGroundAnchors();
			SetTethers(enabled: false, 0f);
			Play(FormationGroup);
			Play(GroundRiteGroup);
			Play(PulseGroup);
			Play(SustainGroup);
			StopAndClear(ResidualGroup);
			if ((Object)(object)RitualLight != (Object)null)
			{
				((Behaviour)RitualLight).enabled = true;
				RitualLight.intensity = 0f;
			}
		}

		private void Update()
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.time - _startedAt;
			float num2 = Mathf.Max(0f, (float)(PulseCount - 1) * PulseInterval + 0.18f);
			float num3 = Smooth01(num / 0.28f);
			float num4 = Smooth01(Mathf.Clamp01((Lifetime - num) / 0.58f));
			float num5 = Mathf.Repeat(num, PulseInterval);
			int num6 = Mathf.FloorToInt(num / PulseInterval);
			float num7 = ((num6 < PulseCount && num5 < 0.24f) ? Mathf.Sin(Mathf.Clamp01(num5 / 0.24f) * (float)Math.PI) : 0f);
			num7 = Mathf.Pow(Mathf.Max(0f, num7), 1.45f);
			if ((Object)(object)GroundRiteGroup != (Object)null)
			{
				GroundRiteGroup.localScale = Vector3.one * num3 * num4;
				GroundRiteGroup.localRotation = Quaternion.identity;
			}
			if ((Object)(object)PulseGroup != (Object)null)
			{
				PulseGroup.localScale = Vector3.one * (0.96f + num7 * 0.08f);
			}
			UpdateTethers(num, num6, num5, num7, num4);
			if ((Object)(object)RitualLight != (Object)null)
			{
				RitualLight.color = Color.Lerp(new Color(0.31f, 0.006f, 0.012f), new Color(0.78f, 0.035f, 0.025f), num7);
				RitualLight.intensity = num3 * num4 * (0.08f + num7 * 0.48f);
			}
			if (!_residualStarted && num >= num2)
			{
				_residualStarted = true;
				StopEmitting(SustainGroup);
				Play(ResidualGroup);
			}
			if (num >= Lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void CacheTargets()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_targets.Clear();
			List<Character> list = Effects.EnemiesInRange(((Component)this).transform.position, Radius);
			for (int i = 0; i < list.Count; i++)
			{
				if (_targets.Count >= 8)
				{
					break;
				}
				if ((Object)(object)list[i] != (Object)null)
				{
					_targets.Add(list[i]);
				}
			}
		}

		private void ProjectGroundAnchors()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_0098: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (GroundAnchors == null)
			{
				return;
			}
			for (int i = 0; i < GroundAnchors.Length; i++)
			{
				Transform val = GroundAnchors[i];
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 val2 = val.position - ((Component)this).transform.position;
					Vector3 forward = val.forward;
					Effects.TrySurfaceFrame(((Component)this).transform.position + val2, out var surface, out var normal);
					Vector3 val3 = Vector3.ProjectOnPlane(forward, normal);
					if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
					{
						val3 = Vector3.ProjectOnPlane(((Component)this).transform.forward, normal);
					}
					if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
					{
						val3 = Vector3.Cross(normal, Vector3.right);
					}
					val.SetPositionAndRotation(surface + normal * (0.052f + (float)(i % 4) * 0.009f), Quaternion.LookRotation(((Vector3)(ref val3)).normalized, normal));
				}
			}
		}

		private void UpdateTethers(float elapsed, int pulseIndex, float pulseTime, float beat, float fade)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b4: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)