Decompiled source of Golden Spin v1.4.0

plugins/GoldenSpin.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GoldenSpin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("GoldenSpin")]
[assembly: AssemblyTitle("GoldenSpin")]
[assembly: AssemblyVersion("1.4.0.0")]
[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 TuskAct4Mod
{
	internal class BeatdownTarget : MonoBehaviour
	{
		public static readonly List<BeatdownTarget> Active = new List<BeatdownTarget>();

		private static readonly int ColorId = Shader.PropertyToID("_Color");

		private static readonly Color Magenta = new Color(1f, 0.1f, 0.85f);

		private readonly List<(Renderer renderer, Color original)> tinted = new List<(Renderer, Color)>();

		private MaterialPropertyBlock block;

		public EnemyIdentifier Enemy { get; private set; }

		public bool Ready { get; private set; }

		public float Age { get; private set; }

		public bool HoldingAtBrink
		{
			get
			{
				if (Ready)
				{
					return Age < TuskPlugin.BeatdownWindow.Value;
				}
				return false;
			}
		}

		public static bool CheckThreshold(EnemyIdentifier eid, float fallbackMaxHealth)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			BeatdownTarget beatdownTarget = default(BeatdownTarget);
			if ((Object)(object)eid == (Object)null || eid.dead || ((Component)eid).TryGetComponent<BeatdownTarget>(ref beatdownTarget))
			{
				return false;
			}
			float health = eid.health;
			float num = fallbackMaxHealth;
			Enemy val = default(Enemy);
			if (((Component)eid).TryGetComponent<Enemy>(ref val) && val.originalHealth > 0f)
			{
				health = val.health;
				num = val.originalHealth;
			}
			if (num <= 0f)
			{
				return false;
			}
			if ((!eid.isBoss && !eid.bigEnemy && !(num >= TuskPlugin.BeatdownMinMaxHealth.Value)) || health / num >= TuskPlugin.BeatdownThreshold.Value)
			{
				return false;
			}
			BeatdownTarget beatdownTarget2 = ((Component)eid).gameObject.AddComponent<BeatdownTarget>();
			beatdownTarget2.Enemy = eid;
			beatdownTarget2.Ready = true;
			beatdownTarget2.CollectRenderers();
			Active.Add(beatdownTarget2);
			TuskAudio.PlayCoinPing(TuskUtil.GetCenter(eid), 0.6f);
			TuskPlugin.Log.LogInfo((object)$"Beatdown ready: {eid.enemyType} at {health:0.0}/{num:0.0} HP.");
			return true;
		}

		private void CollectRenderers()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			block = new MaterialPropertyBlock();
			Renderer[] componentsInChildren = ((Component)Enemy).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (val is MeshRenderer || val is SkinnedMeshRenderer)
				{
					Material sharedMaterial = val.sharedMaterial;
					if (!((Object)(object)sharedMaterial == (Object)null) && sharedMaterial.HasProperty(ColorId))
					{
						tinted.Add((val, sharedMaterial.GetColor(ColorId)));
					}
				}
			}
		}

		private void Update()
		{
			Age += Time.deltaTime;
			if ((Object)(object)Enemy == (Object)null || Enemy.dead)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				ApplyTint(0.5f + 0.5f * Mathf.Sin(Age * 14f));
			}
		}

		private void ApplyTint(float amount)
		{
			//IL_001c: 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_0043: 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)
			foreach (var (val, val2) in tinted)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.GetPropertyBlock(block);
					block.SetColor(ColorId, Color.Lerp(val2, Magenta, amount));
					val.SetPropertyBlock(block);
				}
			}
		}

		public void Execute(Vector3 point, Punch punch)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (Ready && !((Object)(object)Enemy == (Object)null))
			{
				Ready = false;
				if ((Object)(object)OraCinematic.Instance != (Object)null)
				{
					OraCinematic.Instance.Play(Enemy, point, punch);
				}
				Object.Destroy((Object)(object)this);
			}
		}

		internal static void PunchGore(EnemyIdentifier eid, Vector3 position, int index)
		{
			//IL_002a: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			BloodsplatterManager val = TuskUtil.Get<BloodsplatterManager>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Bloodsplatter val4 = default(Bloodsplatter);
			for (int i = 0; i < 3; i++)
			{
				GoreType val2 = (GoreType)(((index + i) % 3 != 0) ? (((index + i) % 3 == 1) ? 2 : 3) : 0);
				GameObject val3 = (((Object)(object)eid != (Object)null) ? val.GetGore(val2, eid, false) : val.GetGore(val2, false, false, false, (EnemyIdentifier)null, false));
				if (!((Object)(object)val3 == (Object)null))
				{
					val3.transform.position = position + Random.insideUnitSphere * 0.3f;
					if (val3.TryGetComponent<Bloodsplatter>(ref val4))
					{
						val4.GetReady();
					}
				}
			}
		}

		private void OnDestroy()
		{
			Active.Remove(this);
			if (block != null)
			{
				ApplyTint(0f);
			}
		}
	}
	[HarmonyPatch(typeof(Punch), "PunchSuccess")]
	internal static class BeatdownPunchPatch
	{
		private static void Prefix(Punch __instance, Transform target, out BeatdownTarget __state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			__state = null;
			try
			{
				if (!((Object)(object)__instance == (Object)null) && (int)__instance.type == 0 && !((Object)(object)target == (Object)null))
				{
					Transform val = target;
					ParryHelper val2 = default(ParryHelper);
					if (((Component)val).TryGetComponent<ParryHelper>(ref val2) && (Object)(object)val2.target != (Object)null)
					{
						val = val2.target;
					}
					EnemyIdentifierIdentifier val4 = default(EnemyIdentifierIdentifier);
					EnemyIdentifier val3 = ((((Component)val).TryGetComponent<EnemyIdentifierIdentifier>(ref val4) && (Object)(object)val4.eid != (Object)null) ? val4.eid : ((Component)val).GetComponentInParent<EnemyIdentifier>());
					BeatdownTarget beatdownTarget = default(BeatdownTarget);
					if ((Object)(object)val3 != (Object)null && ((Component)val3).TryGetComponent<BeatdownTarget>(ref beatdownTarget) && beatdownTarget.Ready)
					{
						__state = beatdownTarget;
					}
				}
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogWarning((object)("Beatdown prefix failed: " + ex.Message));
			}
		}

		private static void Postfix(Punch __instance, Vector3 point, BeatdownTarget __state)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__state == (Object)null)
			{
				return;
			}
			try
			{
				__state.Execute(point, __instance);
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogWarning((object)("Beatdown failed: " + ex.Message));
			}
		}
	}
	internal class GoldenSpinCoin : MonoBehaviour
	{
		private Coin coin;

		private float age;

		private float nextVolley;

		private float spinAngle;

		private readonly HashSet<EnemyIdentifier> victims = new HashSet<EnemyIdentifier>();

		private Transform figureRoot;

		private GoldenFigure figure;

		private Light glow;

		public static bool TryApply(Coin coin)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_0051: 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)
			GoldenSpinCoin goldenSpinCoin = default(GoldenSpinCoin);
			if ((Object)(object)coin == (Object)null || ((Component)coin).TryGetComponent<GoldenSpinCoin>(ref goldenSpinCoin))
			{
				return false;
			}
			((MonoBehaviour)coin).CancelInvoke();
			coin.shot = true;
			Rigidbody val = (((Object)(object)coin.rb != (Object)null) ? coin.rb : ((Component)coin).GetComponent<Rigidbody>());
			if ((Object)(object)val != (Object)null)
			{
				if (!val.isKinematic)
				{
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
				val.isKinematic = true;
				val.useGravity = false;
			}
			GoldenSpinCoin goldenSpinCoin2 = ((Component)coin).gameObject.AddComponent<GoldenSpinCoin>();
			goldenSpinCoin2.coin = coin;
			goldenSpinCoin2.nextVolley = 0.15f;
			goldenSpinCoin2.BuildVisuals();
			TuskVfx.NailImpact(((Component)coin).transform.position, Vector3.up);
			TuskAudio.PlayCoinPing(((Component)coin).transform.position, 1f);
			TuskOverlay.Flash(TuskAssets.Gold, 0.15f, 0.15f);
			return true;
		}

		private void BuildVisuals()
		{
			//IL_0006: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			figureRoot = new GameObject("GoldenCoinSpiral").transform;
			figureRoot.position = ((Component)this).transform.position;
			figure = new GoldenFigure(figureRoot, 1.4f);
			TuskVfx.Swirl(((Component)figureRoot).gameObject, 1.2f, 1.4f, 50f, TuskAssets.PaleGold, TuskAssets.Amber);
			glow = ((Component)figureRoot).gameObject.AddComponent<Light>();
			glow.type = (LightType)2;
			glow.color = TuskAssets.Gold;
			glow.range = 8f;
			glow.intensity = 3f;
			glow.shadows = (LightShadows)0;
		}

		private void Update()
		{
			//IL_00a1: 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_00d1: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			float num = Mathf.Max(0.2f, TuskPlugin.CoinDuration.Value);
			float num2 = Mathf.Clamp01(age / num);
			((Component)this).transform.Rotate(0f, Mathf.Lerp(900f, 3000f, num2) * Time.deltaTime, 0f, (Space)0);
			spinAngle -= Mathf.Lerp(300f, 1500f, num2) * Time.deltaTime;
			if ((Object)(object)figureRoot != (Object)null)
			{
				figureRoot.position = ((Component)this).transform.position;
				figureRoot.rotation = TuskUtil.FaceCamera(((Component)this).transform.position) * Quaternion.Euler(0f, 0f, spinAngle);
				figureRoot.localScale = Vector3.one * (Mathf.Clamp01(age / 0.2f) * (1f + 0.3f * num2));
				figure.SetDrawProgress(age / 0.25f);
				float num3 = 0.8f + 0.2f * Mathf.Sin(age * 40f);
				figure.SetColors(new Color(1f, 0.95f, 0.6f, num3), new Color(1f, 0.6f, 0.1f, num3), new Color(1f, 0.82f, 0.25f, 0.4f));
				glow.intensity = 3f + 4f * num2 + Mathf.Sin(age * 30f);
			}
			float num4 = Mathf.Max(0.05f, TuskPlugin.CoinInterval.Value);
			while (age >= nextVolley && nextVolley < num)
			{
				nextVolley += num4;
				FireVolley();
			}
			if (age >= num)
			{
				Explode();
			}
		}

		private void FireVolley()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: 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_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			EnemyTracker val = TuskUtil.Get<EnemyTracker>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			float value = TuskPlugin.CoinRange.Value;
			LayerMask val2 = LayerMaskDefaults.Get((LMD)1);
			int value2 = ((LayerMask)(ref val2)).value;
			List<(EnemyIdentifier, Vector3, float)> list = new List<(EnemyIdentifier, Vector3, float)>();
			foreach (EnemyIdentifier currentEnemy in val.GetCurrentEnemies())
			{
				if ((Object)(object)currentEnemy == (Object)null || currentEnemy.dead)
				{
					continue;
				}
				Vector3 center = TuskUtil.GetCenter(currentEnemy);
				Vector3? val3 = null;
				if ((Object)(object)currentEnemy.weakPoint != (Object)null && currentEnemy.weakPoint.activeInHierarchy && !Physics.Linecast(position, currentEnemy.weakPoint.transform.position, value2, (QueryTriggerInteraction)1))
				{
					val3 = currentEnemy.weakPoint.transform.position;
				}
				else if (!Physics.Linecast(position, center, value2, (QueryTriggerInteraction)1))
				{
					val3 = center;
				}
				if (val3.HasValue)
				{
					float num = Vector3.Distance(position, val3.Value);
					if (num <= value)
					{
						list.Add((currentEnemy, val3.Value, num));
					}
				}
			}
			if (list.Count != 0)
			{
				list.Sort(((EnemyIdentifier eid, Vector3 aim, float dist) a, (EnemyIdentifier eid, Vector3 aim, float dist) b) => a.dist.CompareTo(b.dist));
				int num2 = Mathf.Min(list.Count, Mathf.Max(1, TuskPlugin.CoinMaxTargets.Value));
				for (int num3 = 0; num3 < num2; num3++)
				{
					EnemyIdentifier item = list[num3].Item1;
					Vector3 item2 = list[num3].Item2;
					HelixTracer.Spawn(position, item2, 0.35f);
					TuskVfx.SparkBurst(item2, 8, 3f, 9f, 0.05f, TuskAssets.PaleGold, TuskAssets.Amber);
					item.hitter = "tusk_act2";
					GameObject gameObject = ((Component)item).gameObject;
					Vector3 val4 = item2 - position;
					item.DeliverDamage(gameObject, ((Vector3)(ref val4)).normalized * 1000f, item2, TuskPlugin.CoinNailDamage.Value, false, 0f, (GameObject)null, false, false);
					victims.Add(item);
				}
				TuskAudio.PlayCoinPing(position, 1.4f + Random.Range(0f, 0.3f));
			}
		}

		private void Explode()
		{
			//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_0068: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			DefaultReferenceManager val = TuskUtil.Get<DefaultReferenceManager>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.explosion != (Object)null)
			{
				Explosion[] componentsInChildren = Object.Instantiate<GameObject>(val.explosion, position, Quaternion.identity).GetComponentsInChildren<Explosion>(true);
				foreach (Explosion obj in componentsInChildren)
				{
					obj.canHit = (AffectedSubjects)2;
					obj.hitterWeapon = "tusk_coin";
				}
			}
			TuskVfx.SparkBurst(position, 60, 8f, 22f, 0.15f, TuskAssets.PaleGold, TuskAssets.Amber);
			FadingRing.Spawn(position, Random.onUnitSphere, 0.3f, 5f, 0.4f, TuskAssets.Gold, 0.2f);
			int num = 0;
			foreach (EnemyIdentifier victim in victims)
			{
				if ((Object)(object)victim != (Object)null)
				{
					num++;
				}
			}
			TuskStyle.Add("tusk.richrotation", TuskPlugin.RichRotationPoints.Value, null, (num > 1) ? num : (-1));
			TuskUtil.Shake(1f);
			TuskPlugin.Log.LogInfo((object)$"Golden coin exploded after hitting {victims.Count} enemies.");
			if ((Object)(object)coin != (Object)null)
			{
				coin.GetDeleted();
			}
			Object.Destroy((Object)(object)this);
		}

		private void OnDestroy()
		{
			if ((Object)(object)figureRoot != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)figureRoot).gameObject);
			}
		}
	}
	public class InfiniteSpinDebuff : MonoBehaviour
	{
		private const string Hitter = "tusk_act4";

		private EnemyIdentifier eid;

		private SpinVisual visual;

		private float tickTimer;

		private float currentDamage;

		private int ticks;

		private float healthAtHit;

		public static bool Apply(EnemyIdentifier eid, Collider hitCollider, Vector3 hitPoint)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)eid == (Object)null || eid.dead)
			{
				return false;
			}
			InfiniteSpinDebuff infiniteSpinDebuff = default(InfiniteSpinDebuff);
			if (((Component)eid).TryGetComponent<InfiniteSpinDebuff>(ref infiniteSpinDebuff))
			{
				return false;
			}
			InfiniteSpinDebuff infiniteSpinDebuff2 = ((Component)eid).gameObject.AddComponent<InfiniteSpinDebuff>();
			infiniteSpinDebuff2.eid = eid;
			infiniteSpinDebuff2.currentDamage = TuskPlugin.TickDamage.Value;
			infiniteSpinDebuff2.healthAtHit = eid.health;
			infiniteSpinDebuff2.visual = SpinVisual.Create(eid, hitCollider, hitPoint);
			return true;
		}

		private void Update()
		{
			if ((Object)(object)eid == (Object)null || eid.dead)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			tickTimer += Time.deltaTime;
			float num = Mathf.Max(0.05f, TuskPlugin.TickInterval.Value);
			while (tickTimer >= num)
			{
				tickTimer -= num;
				if (!Tick())
				{
					break;
				}
			}
		}

		private bool Tick()
		{
			//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_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_00a9: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			Vector3 center = TuskUtil.GetCenter(eid);
			BeatdownTarget beatdownTarget = default(BeatdownTarget);
			if (((Component)eid).TryGetComponent<BeatdownTarget>(ref beatdownTarget) && beatdownTarget.HoldingAtBrink)
			{
				if ((Object)(object)visual != (Object)null)
				{
					visual.OnTick();
				}
				return true;
			}
			eid.hitter = "tusk_act4";
			eid.DeliverDamage(((Component)eid).gameObject, Vector3.zero, center, currentDamage, false, 0f, (GameObject)null, true, false);
			ticks++;
			currentDamage *= Mathf.Max(1f, TuskPlugin.TickDamageGrowth.Value);
			BloodBurst(center);
			if ((Object)(object)eid == (Object)null || eid.dead)
			{
				Chumimin(center);
				Object.Destroy((Object)(object)this);
				return false;
			}
			if ((Object)(object)visual != (Object)null)
			{
				visual.OnTick();
				TuskAudio.PlayTick(((Component)visual).transform.position, ticks);
			}
			if (BeatdownTarget.CheckThreshold(eid, healthAtHit) && (Object)(object)visual != (Object)null)
			{
				visual.SetBeatdown();
			}
			return true;
		}

		private void Chumimin(Vector3 center)
		{
			//IL_004f: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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)
			TuskStyle.Add("tusk.chumimin", TuskPlugin.ChumiminPoints.Value, ((Object)(object)eid != (Object)null) ? eid : null);
			if ((Object)(object)visual != (Object)null)
			{
				visual.Finale(center);
				visual = null;
			}
			else
			{
				TuskVfx.Finale(center, 1.5f);
			}
			TuskAudio.PlayChumimin(center);
			TuskOverlay.Popup(center, "チュミミ〜ン", "CHUMIMIN", new Color(1f, 0.86f, 0.3f), new Color(0.45f, 0f, 0.05f), new Color(1f, 0.15f, 0.15f));
			TuskOverlay.Flash(new Color(1f, 0.85f, 0.4f), 0.45f, 0.45f);
			TuskUtil.Shake(2f);
			TuskPlugin.Log.LogInfo((object)$"Infinite spin finished an enemy after {ticks} ticks.");
			if (TuskPlugin.BlackHoleEnabled.Value)
			{
				if ((Object)(object)eid != (Object)null)
				{
					SingularityCorpse.Swallow(eid, center);
				}
				TuskBlackHole.Spawn(center);
			}
		}

		private void BloodBurst(Vector3 position)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//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)
			BloodsplatterManager val = TuskUtil.Get<BloodsplatterManager>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject gore = val.GetGore((GoreType)3, eid, false);
			if (!((Object)(object)gore == (Object)null))
			{
				gore.transform.position = position + Random.insideUnitSphere * 0.4f;
				Bloodsplatter val2 = default(Bloodsplatter);
				if (gore.TryGetComponent<Bloodsplatter>(ref val2))
				{
					val2.GetReady();
				}
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)visual != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)visual).gameObject);
			}
		}
	}
	internal class OraCinematic : MonoBehaviour
	{
		private AudioClip voice;

		private readonly List<float> onsets = new List<float>();

		private float finalOnset = -1f;

		private AudioSource voiceSource;

		private float fovKick;

		private bool fovRestored = true;

		public static OraCinematic Instance { get; private set; }

		public bool Running { get; private set; }

		public float BarWeight { get; private set; }

		public float CameraWeight { get; private set; }

		public Vector3 Focus { get; private set; }

		public float StartTime { get; private set; } = -999f;

		public float FinalTime { get; private set; } = -999f;

		public float Progress { get; private set; }

		public int HitCount { get; private set; }

		private void Awake()
		{
			Instance = this;
			((MonoBehaviour)this).StartCoroutine(LoadVoice());
		}

		private IEnumerator LoadVoice()
		{
			string value = TuskPlugin.OraSoundFile.Value;
			string text = (Path.IsPathRooted(value) ? value : Path.Combine(TuskPlugin.PluginFolder, value));
			if (!File.Exists(text))
			{
				TuskPlugin.Log.LogWarning((object)("ORA sound not found at " + text + ", the beatdown uses synthesised punches."));
				yield break;
			}
			AudioType val = (AudioType)(Path.GetExtension(text).ToLowerInvariant() switch
			{
				".mp3" => 13, 
				".ogg" => 14, 
				".wav" => 20, 
				_ => 0, 
			});
			UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(new Uri(text).AbsoluteUri, val);
			try
			{
				DownloadHandler downloadHandler = req.downloadHandler;
				DownloadHandlerAudioClip val2 = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null);
				if (val2 != null)
				{
					val2.streamAudio = false;
					val2.compressed = false;
				}
				yield return req.SendWebRequest();
				if ((int)req.result != 1)
				{
					TuskPlugin.Log.LogWarning((object)("ORA sound could not be loaded (" + req.error + "). If it is an mp3, converting it to .ogg or .wav and setting OraSoundFile usually fixes this."));
					yield break;
				}
				voice = DownloadHandlerAudioClip.GetContent(req);
			}
			finally
			{
				((IDisposable)req)?.Dispose();
			}
			if ((Object)(object)voice == (Object)null || voice.length <= 0f)
			{
				TuskPlugin.Log.LogWarning((object)"ORA sound decoded to an empty clip.");
				voice = null;
			}
			else
			{
				((Object)voice).hideFlags = (HideFlags)32;
				DetectOras();
				TuskPlugin.Log.LogInfo((object)($"ORA sound loaded: {voice.length:0.00}s, {onsets.Count} ORAs detected, " + $"final blow at {finalOnset:0.00}s."));
			}
		}

		private void DetectOras()
		{
			onsets.Clear();
			finalOnset = -1f;
			float[] array = new float[voice.samples * voice.channels];
			if (!voice.GetData(array, 0))
			{
				TuskPlugin.Log.LogWarning((object)"Could not read the ORA clip samples, using evenly spaced punches.");
				return;
			}
			int num = Mathf.Max(1, voice.frequency / 100);
			int num2 = voice.samples / num;
			float[] array2 = new float[num2];
			for (int i = 0; i < num2; i++)
			{
				double num3 = 0.0;
				for (int j = 0; j < num; j++)
				{
					int num4 = (i * num + j) * voice.channels;
					for (int k = 0; k < voice.channels; k++)
					{
						num3 += (double)(array[num4 + k] * array[num4 + k]);
					}
				}
				array2[i] = (float)Math.Sqrt(num3 / (double)(num * voice.channels));
			}
			float num5 = 0f;
			float[] array3 = array2;
			foreach (float num6 in array3)
			{
				num5 = Mathf.Max(num5, num6);
			}
			if (num5 <= 0.0001f)
			{
				return;
			}
			int num7 = -1;
			int num8 = -1;
			for (int m = 0; m < num2; m++)
			{
				if (array2[m] > num5 * 0.3f)
				{
					if (num7 < 0)
					{
						num7 = m;
					}
					num8 = m;
				}
			}
			if (num7 < 0 || num8 - num7 < 50)
			{
				return;
			}
			float[] array4 = new float[num2];
			for (int n = 1; n < num2; n++)
			{
				array4[n] = Mathf.Max(0f, array2[n] - array2[n - 1]);
			}
			int num9 = 17;
			double num10 = -1.0;
			for (int num11 = 12; num11 <= 25; num11++)
			{
				double num12 = 0.0;
				for (int num13 = num7; num13 + num11 <= num8; num13++)
				{
					num12 += (double)(array4[num13] * array4[num13 + num11]);
				}
				if (num12 > num10)
				{
					num10 = num12;
					num9 = num11;
				}
			}
			int num14 = num8;
			float num15 = -1f;
			for (int num16 = Mathf.Max(num7, num8 - 50); num16 <= num8; num16++)
			{
				if (array4[num16] > num15)
				{
					num15 = array4[num16];
					num14 = num16;
				}
			}
			int num17 = Mathf.Max(2, num9 / 3);
			int num18 = -num9;
			int num19 = num7;
			while (num19 < num14 - num9 / 2)
			{
				int num20 = num19;
				float num21 = -1f;
				for (int num22 = Mathf.Max(num7, num19 - num17); num22 <= Mathf.Min(num14 - 1, num19 + num17); num22++)
				{
					if (array4[num22] > num21)
					{
						num21 = array4[num22];
						num20 = num22;
					}
				}
				if (num20 - num18 < num9 / 2)
				{
					num20 = num19;
				}
				onsets.Add((float)num20 / 100f);
				num18 = num20;
				num19 = num20 + num9;
			}
			finalOnset = (float)num14 / 100f;
		}

		public void Play(EnemyIdentifier eid, Vector3 point, Punch punch)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!Running)
			{
				((MonoBehaviour)this).StartCoroutine(Sequence(eid, point, punch));
			}
		}

		private IEnumerator Sequence(EnemyIdentifier eid, Vector3 point, Punch punch)
		{
			//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)
			Running = true;
			HitCount = 0;
			FinalTime = -999f;
			StartTime = Time.unscaledTime;
			List<float> hits = new List<float>();
			float final;
			if ((Object)(object)voice != (Object)null && finalOnset > 0f && onsets.Count >= 3)
			{
				final = Mathf.Min(finalOnset, TuskPlugin.CinematicMaxLength.Value);
				foreach (float onset in onsets)
				{
					if (onset < final)
					{
						hits.Add(onset);
					}
				}
			}
			else
			{
				final = Mathf.Max(0.5f, TuskPlugin.BeatdownFreeze.Value * 2f);
				for (int i = 0; i < 16; i++)
				{
					hits.Add(0.2f + (float)i * (final - 0.3f) / 16f);
				}
			}
			float size = (((Object)(object)eid != (Object)null) ? TuskUtil.GetSize(eid) : 1.5f);
			Focus = (((Object)(object)eid != (Object)null) ? TuskUtil.GetCenter(eid) : point);
			TimeController time = TuskUtil.Get<TimeController>();
			if (time != null)
			{
				time.HitStop(final + 0.15f);
			}
			try
			{
				if (time != null)
				{
					time.ParryFlash();
				}
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogWarning((object)("Parry flash failed: " + ex.Message));
			}
			if ((Object)(object)voice != (Object)null)
			{
				if ((Object)(object)voiceSource == (Object)null)
				{
					voiceSource = TuskAudio.CreateVoiceSource(((Component)this).gameObject);
				}
				voiceSource.clip = voice;
				voiceSource.volume = Mathf.Clamp01(TuskPlugin.OraVolume.Value) * Mathf.Clamp01(TuskPlugin.SoundVolume.Value);
				voiceSource.Play();
			}
			Animator anim = (((Object)(object)punch != (Object)null) ? punch.anim : null);
			AnimatorUpdateMode previousMode = (AnimatorUpdateMode)(((Object)(object)anim != (Object)null) ? ((int)anim.updateMode) : 0);
			if ((Object)(object)anim != (Object)null)
			{
				anim.updateMode = (AnimatorUpdateMode)2;
				anim.Play("Hook", 0, 0.065f);
			}
			TuskOverlay.Flash(Color.white, 0.25f, 0.8f);
			TuskUtil.Shake(1.5f);
			fovRestored = false;
			int next = 0;
			while (true)
			{
				float num = Time.unscaledTime - StartTime;
				if ((Object)(object)eid != (Object)null)
				{
					Focus = TuskUtil.GetCenter(eid);
				}
				BarWeight = Mathf.Clamp01(num / 0.25f);
				CameraWeight = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(num / 0.4f));
				Progress = Mathf.Clamp01(num / final);
				for (; next < hits.Count && hits[next] <= num; next++)
				{
					RushHit(eid, anim, size, next);
				}
				if (num >= final)
				{
					break;
				}
				if (TuskUtil.IsPaused())
				{
					StartTime += Time.unscaledDeltaTime;
				}
				yield return null;
			}
			FinalBlow(eid, anim, size);
			if (time != null)
			{
				time.RestoreTime();
			}
			float outStart = Time.unscaledTime;
			while (Time.unscaledTime - outStart < 0.6f)
			{
				float num2 = (Time.unscaledTime - outStart) / 0.6f;
				BarWeight = 1f - num2;
				CameraWeight = 1f - Mathf.SmoothStep(0f, 1f, num2);
				if ((Object)(object)eid != (Object)null)
				{
					Focus = TuskUtil.GetCenter(eid);
				}
				yield return null;
			}
			BarWeight = 0f;
			CameraWeight = 0f;
			if ((Object)(object)anim != (Object)null)
			{
				anim.updateMode = previousMode;
			}
			Running = false;
		}

		private void RushHit(EnemyIdentifier eid, Animator anim, float size, int index)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0067: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: 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)
			HitCount++;
			Vector3 val = Focus + Random.insideUnitSphere * size * 0.6f;
			if ((Object)(object)anim != (Object)null)
			{
				anim.Play((index % 5 == 4) ? "Hook" : ((index % 2 == 0) ? "Jab" : "Jab2"), 0, 0.075f);
			}
			BeatdownTarget.PunchGore(eid, val, index);
			TuskVfx.SparkBurst(val, 14, 6f, 16f, 0.08f, new Color(1f, 0.75f, 0.9f), new Color(1f, 0.2f, 0.7f), null, unscaled: true);
			Camera camera = TuskUtil.GetCamera();
			Vector3 normal = (((Object)(object)camera != (Object)null) ? (((Component)camera).transform.position - val) : Vector3.up);
			FadingRing.Spawn(val, normal, 0.1f, size * 0.9f, 0.2f, new Color(1f, 0.3f, 0.8f), 0.08f, unscaled: true);
			LightFlash.Spawn(val, new Color(1f, 0.6f, 0.85f), 3f, 4f, 0.08f);
			TuskOverlay.Splash(val, (index % 2 == 0) ? "オラ" : "ORA", new Color(1f, 0.2f, 0.75f));
			TuskOverlay.Impact(val);
			if (index % 4 == 3)
			{
				TuskOverlay.Flash(Color.white, 0.06f, 0.35f);
			}
			if ((Object)(object)voice == (Object)null)
			{
				TuskAudio.PlayPunch(val, 0.85f + Random.Range(0f, 0.4f));
			}
			else
			{
				TuskAudio.PlayPunch(val, 1f + Random.Range(0f, 0.3f), 0.35f);
			}
			fovKick = 1f;
			TuskUtil.Shake(0.6f + Progress * 0.8f);
		}

		private void FinalBlow(EnemyIdentifier eid, Animator anim, float size)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			FinalTime = Time.unscaledTime;
			if ((Object)(object)anim != (Object)null)
			{
				anim.Play("Hook", 0, 0.065f);
			}
			Vector3 focus = Focus;
			Transform cameraTransform = TuskUtil.GetCameraTransform();
			Vector3 val = (((Object)(object)cameraTransform != (Object)null) ? cameraTransform.forward : Vector3.forward);
			if ((Object)(object)eid != (Object)null && !eid.dead)
			{
				eid.hitter = "tusk_beatdown";
				eid.DeliverDamage(((Component)eid).gameObject, (val + Vector3.up * 0.35f) * 40000f, focus, TuskPlugin.BeatdownDamage.Value, true, 0f, (GameObject)null, true, false);
			}
			TuskVfx.GoreStorm(focus, size, 50);
			TuskVfx.SparkBurst(focus, 120, 12f, 35f, 0.2f, new Color(1f, 0.7f, 0.9f), new Color(1f, 0.15f, 0.5f), null, unscaled: true);
			for (int i = 0; i < 3; i++)
			{
				FadingRing.Spawn(focus, val, 0.3f, size * (3f + (float)i * 1.5f), 0.4f + (float)i * 0.12f, (Color)((i == 1) ? Color.white : new Color(1f, 0.2f, 0.75f)), 0.3f, unscaled: true);
			}
			LightFlash.Spawn(focus, Color.white, 16f, 20f, 0.5f);
			TuskStyle.Add("tusk.oraoraora", TuskPlugin.OraPoints.Value, ((Object)(object)eid != (Object)null) ? eid : null, (HitCount > 1) ? HitCount : (-1));
			TuskOverlay.Popup(focus, "オラオラオラ", "ORA ORA ORA", new Color(1f, 0.25f, 0.7f), new Color(0.2f, 0f, 0.1f), new Color(1f, 0.15f, 0.15f));
			TuskOverlay.Flash(Color.white, 0.5f, 0.9f);
			TuskUtil.Shake(3f);
			fovKick = 2.5f;
			TuskPlugin.Log.LogInfo((object)$"ORA ORA ORA cinematic: {HitCount} punches + final blow.");
		}

		public void ApplyCamera(CameraController cc)
		{
			//IL_007b: 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_008b: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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)
			if ((Object)(object)cc == (Object)null || (Object)(object)cc.cam == (Object)null)
			{
				return;
			}
			fovKick = Mathf.MoveTowards(fovKick, 0f, Time.unscaledDeltaTime * 8f);
			if (CameraWeight <= 0f || !TuskPlugin.CinematicCamera.Value)
			{
				if (!fovRestored)
				{
					cc.cam.fieldOfView = cc.defaultFov;
					fovRestored = true;
				}
				return;
			}
			Transform transform = ((Component)cc).transform;
			Vector3 val = Focus - transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
			{
				float num = Mathf.Lerp(0f, 9f, Progress) + Mathf.Sin(Time.unscaledTime * 3f) * 1.5f;
				Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up) * Quaternion.Euler(0f, 0f, num);
				transform.rotation = Quaternion.Slerp(transform.rotation, val2, CameraWeight);
			}
			float num2 = Mathf.Lerp(1f, 0.62f, Progress) * (1f + 0.05f * fovKick);
			cc.cam.fieldOfView = Mathf.Lerp(cc.defaultFov, cc.defaultFov * num2, CameraWeight);
		}
	}
	[HarmonyPatch(typeof(CameraController), "LateUpdate")]
	internal static class OraCinematicCameraPatch
	{
		private static void Postfix(CameraController __instance)
		{
			try
			{
				OraCinematic.Instance?.ApplyCamera(__instance);
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogWarning((object)("Cinematic camera failed: " + ex.Message));
			}
		}
	}
	[BepInPlugin("com.zylow7000.tuskact4", "Golden Spin", "1.4.0")]
	public class TuskPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.zylow7000.tuskact4";

		public const string PluginName = "Golden Spin";

		public const string PluginVersion = "1.4.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> FireKey;

		internal static ConfigEntry<float> Cooldown;

		internal static ConfigEntry<float> MaxRange;

		internal static ConfigEntry<float> TickInterval;

		internal static ConfigEntry<float> TickDamage;

		internal static ConfigEntry<float> TickDamageGrowth;

		internal static ConfigEntry<int> GoldenNailPoints;

		internal static ConfigEntry<int> ChumiminPoints;

		internal static ConfigEntry<float> GoldenMinSpeed;

		internal static ConfigEntry<float> ImperfectDamage;

		internal static ConfigEntry<int> ImperfectPoints;

		internal static ConfigEntry<bool> WallPiercing;

		internal static ConfigEntry<int> BreachPoints;

		internal static ConfigEntry<bool> BlackHoleEnabled;

		internal static ConfigEntry<float> BlackHoleDuration;

		internal static ConfigEntry<float> BlackHoleRadius;

		internal static ConfigEntry<float> BlackHolePull;

		internal static ConfigEntry<float> BlackHoleDamage;

		internal static ConfigEntry<int> BlackHoleGore;

		internal static ConfigEntry<int> BlackHoleHeal;

		internal static ConfigEntry<int> ArigatoPoints;

		internal static ConfigEntry<float> CoinDuration;

		internal static ConfigEntry<float> CoinInterval;

		internal static ConfigEntry<float> CoinRange;

		internal static ConfigEntry<int> CoinMaxTargets;

		internal static ConfigEntry<float> CoinNailDamage;

		internal static ConfigEntry<int> RichRotationPoints;

		internal static ConfigEntry<float> WormholeDuration;

		internal static ConfigEntry<float> WormholeMaxDistance;

		internal static ConfigEntry<float> WormholeHeight;

		internal static ConfigEntry<float> WormholeLaunchSpeed;

		internal static ConfigEntry<int> WormholePoints;

		internal static ConfigEntry<float> BeatdownThreshold;

		internal static ConfigEntry<float> BeatdownMinMaxHealth;

		internal static ConfigEntry<float> BeatdownWindow;

		internal static ConfigEntry<float> BeatdownDamage;

		internal static ConfigEntry<float> BeatdownFreeze;

		internal static ConfigEntry<int> OraPoints;

		internal static ConfigEntry<string> OraSoundFile;

		internal static ConfigEntry<float> OraVolume;

		internal static ConfigEntry<float> CinematicMaxLength;

		internal static ConfigEntry<bool> CinematicCamera;

		internal static string PluginFolder;

		internal static ConfigEntry<bool> CutIn;

		internal static ConfigEntry<bool> Menacing;

		internal static ConfigEntry<bool> ScreenFlash;

		internal static ConfigEntry<bool> HitStop;

		internal static ConfigEntry<float> CameraShake;

		internal static ConfigEntry<float> SoundVolume;

		private Harmony harmony;

		private void Awake()
		{
			//IL_06b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Expected O, but got Unknown
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Expected O, but got Unknown
			//IL_0714: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			FireKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "FireKey", (KeyCode)118, "Key that fires the Tusk Act 4 nail.");
			Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Shot", "Cooldown", 1f, "Seconds between two nail shots.");
			MaxRange = ((BaseUnityPlugin)this).Config.Bind<float>("Shot", "MaxRange", 500f, "Hitscan range in metres.");
			TickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("InfiniteSpin", "TickInterval", 0.5f, "Seconds between two spin damage ticks.");
			TickDamage = ((BaseUnityPlugin)this).Config.Bind<float>("InfiniteSpin", "TickDamage", 1f, "Damage per tick (1.0 = one revolver shot). Armor and resistance multipliers are ignored.");
			TickDamageGrowth = ((BaseUnityPlugin)this).Config.Bind<float>("InfiniteSpin", "TickDamageGrowth", 1f, "Each tick multiplies the tick damage by this factor. 1.0 = constant, >1 = the spin keeps accelerating.");
			GoldenNailPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "GoldenNailPoints", 150, "Style points for landing the nail.");
			ChumiminPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "ChumiminPoints", 300, "Style points when the spin finishes an enemy.");
			GoldenMinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenRectangle", "MinSpeed", 22f, "V1 speed (units/s) that counts as a golden rotation even without sliding or dashing. Every hit logs V1's current speed to BepInEx/LogOutput.log, use that to tune this.");
			ImperfectDamage = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenRectangle", "ImperfectDamage", 3f, "One-time burst damage (Act 3) when V1 fires standing or too slow. No infinite spin.");
			ImperfectPoints = ((BaseUnityPlugin)this).Config.Bind<int>("GoldenRectangle", "ImperfectPoints", 60, "Style points for IMPERFECT ROTATION.");
			WallPiercing = ((BaseUnityPlugin)this).Config.Bind<bool>("DimensionalBreach", "WallPiercing", true, "The nail passes through walls and floors.");
			BreachPoints = ((BaseUnityPlugin)this).Config.Bind<int>("DimensionalBreach", "BreachPoints", 200, "Style points for DIMENSIONAL BREACH.");
			BlackHoleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Singularity", "Enabled", true, "A spin kill opens a black hole.");
			BlackHoleDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Singularity", "Duration", 3f, "Seconds until the black hole explodes.");
			BlackHoleRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Singularity", "Radius", 20f, "Pull and blast radius.");
			BlackHolePull = ((BaseUnityPlugin)this).Config.Bind<float>("Singularity", "PullStrength", 90f, "Pull acceleration towards the centre (units/s²).");
			BlackHoleDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Singularity", "BlastDamage", 25f, "Damage the blast deals to every enemy in the radius.");
			BlackHoleGore = ((BaseUnityPlugin)this).Config.Bind<int>("Singularity", "GoreAmount", 80, "Number of blood splatters spawned by the blast.");
			BlackHoleHeal = ((BaseUnityPlugin)this).Config.Bind<int>("Singularity", "Heal", 50, "HP restored to V1 by the blast.");
			ArigatoPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "ArigatoGyroPoints", 500, "Style points for ARIGATO GYRO.");
			CoinDuration = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenCoin", "Duration", 2f, "Seconds a nailed coin spins and fires before it explodes.");
			CoinInterval = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenCoin", "Interval", 0.2f, "Seconds between two volleys of homing Act 2 nails.");
			CoinRange = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenCoin", "Range", 60f, "How far the coin looks for enemies (line of sight required).");
			CoinMaxTargets = ((BaseUnityPlugin)this).Config.Bind<int>("GoldenCoin", "MaxTargets", 3, "Enemies targeted per volley (nearest first).");
			CoinNailDamage = ((BaseUnityPlugin)this).Config.Bind<float>("GoldenCoin", "NailDamage", 0.5f, "Damage of one homing nail.");
			RichRotationPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "RichRotationPoints", 250, "Style points for RICH ROTATION.");
			WormholeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Wormhole", "Duration", 4f, "Seconds the wormhole stays open.");
			WormholeMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Wormhole", "MaxDistance", 10f, "The floor hit must be within this horizontal distance of V1 to count as 'below V1'.");
			WormholeHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Wormhole", "TeleportHeight", 30f, "How far up V1 is teleported (less if a ceiling is in the way).");
			WormholeLaunchSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Wormhole", "LaunchSpeed", 70f, "Upward speed V1 gets after the teleport.");
			WormholePoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "WormholeSlamPoints", 300, "Style points for WORMHOLE SLAM.");
			BeatdownThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "HealthThreshold", 0.1f, "Fraction of max HP below which a big spinning enemy glows.");
			BeatdownMinMaxHealth = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "MinMaxHealth", 10f, "Enemies with at least this much max HP count as 'big' (bosses and the game's big enemies always do).");
			BeatdownWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "Window", 3f, "Seconds the infinite spin holds a glowing enemy at the brink, so there is time to punch it.");
			BeatdownDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "Damage", 50f, "Burst damage of the ORA ORA ORA finisher (ignores armor).");
			BeatdownFreeze = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "FreezeTime", 0.6f, "Only used without a voice clip: the rush then lasts twice this long (real-time seconds).");
			OraPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Style", "OraOraOraPoints", 600, "Style points for ORA ORA ORA.");
			OraSoundFile = ((BaseUnityPlugin)this).Config.Bind<string>("Beatdown", "OraSoundFile", "johnny-ora-ora-ora.mp3", "Voice clip for the ORA rush (mp3, ogg or wav). Relative paths are next to the mod's DLL. The punches are synced to the ORAs detected in the clip; the last loud one is the final blow.");
			OraVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "OraVolume", 1f, "Volume of the ORA voice clip (0-1).");
			CinematicMaxLength = ((BaseUnityPlugin)this).Config.Bind<float>("Beatdown", "CinematicMaxLength", 9f, "Longest the frozen ORA rush may last (seconds).");
			CinematicCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Beatdown", "CinematicCamera", true, "Lock the camera onto the enemy with zoom and tilt during the ORA rush.");
			PluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			CutIn = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "CutIn", true, "Show the 'TUSK ACT 4' cut-in banner when the nail hits.");
			Menacing = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Menacing", true, "Float JoJo-style menacing symbols next to spinning enemies.");
			ScreenFlash = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "ScreenFlash", true, "Golden screen flash on hit and kill.");
			HitStop = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "HitStop", true, "Short freeze frame when the nail hits.");
			CameraShake = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "CameraShake", 1f, "Camera shake strength (0 = off). Also scaled by the game's screenshake setting.");
			SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "SoundVolume", 0.8f, "Volume of the mod's sounds (0-1).");
			GameObject val = new GameObject("TuskAct4_Host")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<TuskController>();
			val.AddComponent<TuskOverlay>();
			val.AddComponent<OraCinematic>();
			harmony = new Harmony("com.zylow7000.tuskact4");
			harmony.PatchAll();
			Log.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to fire the golden nail.", "Golden Spin", "1.4.0", FireKey.Value));
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	internal class TuskController : MonoBehaviour
	{
		private float lastShotTime = -999f;

		public static TuskController Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKeyDown(TuskPlugin.FireKey.Value) || Time.unscaledTime - lastShotTime < TuskPlugin.Cooldown.Value)
			{
				return;
			}
			try
			{
				if (TryFire())
				{
					lastShotTime = Time.unscaledTime;
				}
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogError((object)("Tusk shot failed: " + ex));
			}
		}

		private static bool TryFire()
		{
			//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_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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00c6: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: 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_02e4: Unknown result type (might be due to invalid IL or missing references)
			NewMovement val = TuskUtil.Get<NewMovement>();
			if ((Object)(object)val == (Object)null || val.dead || !val.activated)
			{
				return false;
			}
			if (TuskUtil.IsPaused())
			{
				return false;
			}
			Transform cameraTransform = TuskUtil.GetCameraTransform();
			if ((Object)(object)cameraTransform == (Object)null)
			{
				return false;
			}
			Vector3 position = cameraTransform.position;
			Vector3 forward = cameraTransform.forward;
			float num;
			if (!((Object)(object)val.rb != (Object)null))
			{
				num = 0f;
			}
			else
			{
				Vector3 velocity = val.rb.velocity;
				num = ((Vector3)(ref velocity)).magnitude;
			}
			float num2 = num;
			bool flag = val.sliding || val.boost || num2 >= TuskPlugin.GoldenMinSpeed.Value;
			NailHit nailHit = TuskUtil.CastNail(position, forward, TuskPlugin.MaxRange.Value, ((Component)val).transform, TuskPlugin.WallPiercing.Value);
			Vector3 point = nailHit.Point;
			TuskVfx.NailShot(position + forward * 0.6f - cameraTransform.up * 0.3f + cameraTransform.right * 0.15f, point);
			TuskAudio.PlayShot();
			if ((Object)(object)nailHit.Coin != (Object)null)
			{
				if (GoldenSpinCoin.TryApply(nailHit.Coin))
				{
					TuskPlugin.Log.LogInfo((object)"Nail hit a coin: golden spin coin.");
				}
				return true;
			}
			EnemyIdentifier enemy = nailHit.Enemy;
			Collider collider = nailHit.Collider;
			if ((Object)(object)enemy == (Object)null)
			{
				if (nailHit.HitWall && TuskWormhole.IsFloorBelow(val, nailHit.WallPoint, nailHit.WallNormal))
				{
					TuskWormhole.Spawn(nailHit.WallPoint, nailHit.WallNormal);
				}
				return true;
			}
			List<Vector3> list = TuskUtil.WallsBetween(position, point);
			bool flag2 = list.Count > 0;
			foreach (Vector3 item in list)
			{
				TuskVfx.BreachPortal(item, forward);
			}
			TuskPlugin.Log.LogInfo((object)($"Nail hit {enemy.enemyType} (boss: {enemy.isBoss}) | sliding={val.sliding} " + string.Format("dash={0} speed={1:0.0} -> {2}", val.boost, num2, flag ? "GOLDEN" : "imperfect") + (flag2 ? $" | breach through {list.Count} wall(s)" : "")));
			TuskUtil.Shake(flag ? 1.2f : 0.6f);
			if (TuskPlugin.HitStop.Value)
			{
				TimeController obj = TuskUtil.Get<TimeController>();
				if (obj != null)
				{
					obj.HitStop(flag ? 0.07f : 0.04f);
				}
			}
			if (flag2)
			{
				TuskStyle.Add("tusk.breach", TuskPlugin.BreachPoints.Value, enemy);
				TuskOverlay.Flash(new Color(1f, 0.2f, 0.9f), 0.25f, 0.25f);
			}
			if (flag)
			{
				GoldenRotation(enemy, collider, point, forward);
			}
			else
			{
				ImperfectRotation(enemy, point, forward);
			}
			return true;
		}

		private static void GoldenRotation(EnemyIdentifier eid, Collider hitCollider, Vector3 hitPoint, Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000e: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			TuskVfx.NailImpact(hitPoint, -direction);
			if (InfiniteSpinDebuff.Apply(eid, hitCollider, hitPoint))
			{
				TuskStyle.Add("tusk.goldennail", TuskPlugin.GoldenNailPoints.Value, eid);
				TuskOverlay.CutIn("TUSK  ACT 4", "黄金の回転  ―  GOLDEN ROTATION", "GOLDEN ROTATION", TuskAssets.Gold);
				TuskOverlay.Flash(new Color(1f, 0.8f, 0.2f), 0.22f, 0.3f);
			}
		}

		private static void ImperfectRotation(EnemyIdentifier eid, Vector3 hitPoint, Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0040: 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_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)
			TuskVfx.ImperfectImpact(hitPoint, -direction);
			TuskStyle.Add("tusk.imperfect", TuskPlugin.ImperfectPoints.Value, eid);
			TuskOverlay.CutIn("TUSK  ACT 3", "不完全な回転  ―  IMPERFECT ROTATION", "IMPERFECT ROTATION", new Color(0.95f, 0.9f, 0.45f));
			eid.hitter = "tusk_act3";
			eid.DeliverDamage(((Component)eid).gameObject, direction * 2000f, hitPoint, TuskPlugin.ImperfectDamage.Value, true, 0f, (GameObject)null, true, false);
		}
	}
	internal struct NailHit
	{
		public EnemyIdentifier Enemy;

		public Coin Coin;

		public Collider Collider;

		public Vector3 Point;

		public bool HitWall;

		public Vector3 WallPoint;

		public Vector3 WallNormal;
	}
	internal static class TuskUtil
	{
		internal static T Get<T>() where T : MonoSingleton<T>
		{
			T val = default(T);
			if (!MonoSingleton<T>.TryGetInstance(ref val) || !((Object)(object)val != (Object)null))
			{
				return default(T);
			}
			return val;
		}

		internal static bool IsPaused()
		{
			OptionsManager val = TuskUtil.Get<OptionsManager>();
			if ((Object)(object)val != (Object)null)
			{
				if (!val.paused)
				{
					return val.mainMenu;
				}
				return true;
			}
			return false;
		}

		internal static Camera GetCamera()
		{
			CameraController val = TuskUtil.Get<CameraController>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.cam != (Object)null)
			{
				return val.cam;
			}
			return Camera.main;
		}

		internal static Transform GetCameraTransform()
		{
			CameraController val = TuskUtil.Get<CameraController>();
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).transform;
			}
			Camera main = Camera.main;
			if (!((Object)(object)main != (Object)null))
			{
				return null;
			}
			return ((Component)main).transform;
		}

		internal static Quaternion FaceCamera(Vector3 position)
		{
			//IL_001c: 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_0022: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			Camera camera = GetCamera();
			Vector3 val = (((Object)(object)camera != (Object)null) ? (((Component)camera).transform.position - position) : Vector3.back);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.back;
			}
			return Quaternion.LookRotation(-((Vector3)(ref val)).normalized);
		}

		internal static void Shake(float amount)
		{
			float value = TuskPlugin.CameraShake.Value;
			if (!(value <= 0f))
			{
				CameraController obj = TuskUtil.Get<CameraController>();
				if (obj != null)
				{
					obj.CameraShake(amount * value);
				}
			}
		}

		internal static EnemyIdentifier ResolveEnemy(Collider col)
		{
			if ((Object)(object)col == (Object)null)
			{
				return null;
			}
			EnemyIdentifierIdentifier val = default(EnemyIdentifierIdentifier);
			if (((Component)col).TryGetComponent<EnemyIdentifierIdentifier>(ref val) && (Object)(object)val.eid != (Object)null)
			{
				return val.eid;
			}
			return ((Component)col).GetComponentInParent<EnemyIdentifier>();
		}

		internal static NailHit CastNail(Vector3 origin, Vector3 direction, float range, Transform player, bool pierceWalls)
		{
			//IL_000a: 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_0017: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			NailHit result = new NailHit
			{
				Point = origin + direction * range
			};
			RaycastHit[] array = Physics.RaycastAll(origin, direction, range, -1, (QueryTriggerInteraction)2);
			if (array == null || array.Length == 0)
			{
				return result;
			}
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			LayerMask val = LayerMaskDefaults.Get((LMD)1);
			int value = ((LayerMask)(ref val)).value;
			RaycastHit[] array2 = array;
			GoldenSpinCoin goldenSpinCoin = default(GoldenSpinCoin);
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val2 = array2[num];
				Collider collider = ((RaycastHit)(ref val2)).collider;
				if ((Object)(object)collider == (Object)null || ((Object)(object)player != (Object)null && ((Component)collider).transform.IsChildOf(player)))
				{
					continue;
				}
				Coin component = ((Component)collider).GetComponent<Coin>();
				if ((Object)(object)component == (Object)null && (Object)(object)collider.attachedRigidbody != (Object)null)
				{
					component = ((Component)collider.attachedRigidbody).GetComponent<Coin>();
				}
				if ((Object)(object)component != (Object)null && !((Component)component).TryGetComponent<GoldenSpinCoin>(ref goldenSpinCoin))
				{
					result.Coin = component;
					result.Point = ((RaycastHit)(ref val2)).point;
					return result;
				}
				EnemyIdentifier val3 = ResolveEnemy(collider);
				if ((Object)(object)val3 != (Object)null && !val3.dead)
				{
					result.Enemy = val3;
					result.Collider = collider;
					result.Point = ((RaycastHit)(ref val2)).point;
					return result;
				}
				if (!collider.isTrigger && (value & (1 << ((Component)collider).gameObject.layer)) != 0 && !result.HitWall)
				{
					result.HitWall = true;
					result.WallPoint = ((RaycastHit)(ref val2)).point;
					result.WallNormal = ((RaycastHit)(ref val2)).normal;
					result.Point = ((RaycastHit)(ref val2)).point;
					if (!pierceWalls)
					{
						return result;
					}
				}
			}
			return result;
		}

		internal static List<Vector3> WallsBetween(Vector3 from, Vector3 to)
		{
			//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_0008: 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_0020: 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_0023: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			Vector3 val = to - from;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.01f)
			{
				return list;
			}
			RaycastHit[] array = Physics.RaycastAll(from, val / magnitude, magnitude - 0.05f, LayerMask.op_Implicit(LayerMaskDefaults.Get((LMD)1)), (QueryTriggerInteraction)1);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val2 = array2[num];
				if ((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && (Object)(object)ResolveEnemy(((RaycastHit)(ref val2)).collider) == (Object)null)
				{
					list.Add(((RaycastHit)(ref val2)).point);
				}
			}
			return list;
		}

		internal static Vector3 GetCenter(EnemyIdentifier eid)
		{
			//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_0029: 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_0010: 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)
			Collider val = default(Collider);
			if (((Component)eid).TryGetComponent<Collider>(ref val))
			{
				Bounds bounds = val.bounds;
				return ((Bounds)(ref bounds)).center;
			}
			return ((Component)eid).transform.position + Vector3.up;
		}

		internal static float GetSize(EnemyIdentifier eid)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Collider val = default(Collider);
			if (((Component)eid).TryGetComponent<Collider>(ref val))
			{
				Bounds bounds = val.bounds;
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				return Mathf.Clamp(((Vector3)(ref extents)).magnitude, 0.6f, 6f);
			}
			return 1.2f;
		}
	}
	internal static class TuskStyle
	{
		public const string GoldenNail = "tusk.goldennail";

		public const string Chumimin = "tusk.chumimin";

		public const string ImperfectRotation = "tusk.imperfect";

		public const string DimensionalBreach = "tusk.breach";

		public const string ArigatoGyro = "tusk.arigato";

		public const string RichRotation = "tusk.richrotation";

		public const string WormholeSlam = "tusk.wormholeslam";

		public const string OraOraOra = "tusk.oraoraora";

		private static StyleHUD registeredHud;

		internal static void Add(string id, int points, EnemyIdentifier eid, int count = -1)
		{
			StyleHUD val = TuskUtil.Get<StyleHUD>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)registeredHud != (Object)(object)val)
				{
					Register(val, "tusk.goldennail", "<color=#FFD700>GOLDEN NAIL</color>");
					Register(val, "tusk.chumimin", "<color=red>CHUMIMIN</color>");
					Register(val, "tusk.imperfect", "<color=#FFFF00>IMPERFECT ROTATION</color>");
					Register(val, "tusk.breach", "<color=#FF00FF>DIMENSIONAL BREACH</color>");
					Register(val, "tusk.arigato", "<color=red>ARIGATO GYRO</color>");
					Register(val, "tusk.richrotation", "<color=#FFD700>RICH ROTATION</color>");
					Register(val, "tusk.wormholeslam", "<color=#FF00FF>WORMHOLE SLAM</color>");
					Register(val, "tusk.oraoraora", "<color=red>ORA ORA ORA</color>");
					registeredHud = val;
				}
				val.AddPoints(points, id, (GameObject)null, eid, count, "", "");
			}
			catch (Exception ex)
			{
				TuskPlugin.Log.LogWarning((object)("Could not add style bonus '" + id + "': " + ex.Message));
			}
		}

		private static void Register(StyleHUD hud, string id, string name)
		{
			if (hud.GetLocalizedName(id) == id)
			{
				hud.RegisterStyleItem(id, name);
			}
		}
	}
	internal class GoldenFigure
	{
		private const float Phi = 1.6180339f;

		private const int SpiralSteps = 9;

		private const int ArcSegments = 14;

		public LineRenderer Spiral;

		public Vector3[] SpiralPoints;

		public readonly List<LineRenderer> Squares = new List<LineRenderer>();

		public GoldenFigure(Transform parent, float width)
		{
			//IL_006f: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: 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_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: 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_0341: 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_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Rect> list2 = new List<Rect>();
			float num = 0f;
			float num2 = 0f;
			float num3 = 1.6180339f;
			float num4 = 1f;
			for (int i = 0; i < 9; i++)
			{
				float num5 = Mathf.Min(num3, num4);
				float num6;
				float num7;
				float num8;
				float num9;
				switch (i % 4)
				{
				case 0:
					list2.Add(new Rect(num, num2, num5, num5));
					num6 = num + num5;
					num7 = num2;
					num8 = 180f;
					num9 = 90f;
					num += num5;
					num3 -= num5;
					break;
				case 1:
					list2.Add(new Rect(num, num2 + num4 - num5, num5, num5));
					num6 = num;
					num7 = num2 + num4 - num5;
					num8 = 90f;
					num9 = 0f;
					num4 -= num5;
					break;
				case 2:
					list2.Add(new Rect(num + num3 - num5, num2, num5, num5));
					num6 = num + num3 - num5;
					num7 = num2 + num5;
					num8 = 0f;
					num9 = -90f;
					num3 -= num5;
					break;
				default:
					list2.Add(new Rect(num, num2, num5, num5));
					num6 = num + num5;
					num7 = num2 + num5;
					num8 = -90f;
					num9 = -180f;
					num2 += num5;
					num4 -= num5;
					break;
				}
				for (int j = ((i != 0) ? 1 : 0); j <= 14; j++)
				{
					float num10 = Mathf.Lerp(num8, num9, (float)j / 14f) * (MathF.PI / 180f);
					list.Add(new Vector3(num6 + Mathf.Cos(num10) * num5, num7 + Mathf.Sin(num10) * num5, 0f));
				}
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(num + num3 * 0.5f, num2 + num4 * 0.5f, 0f);
			float num11 = width / 1.6180339f;
			SpiralPoints = (Vector3[])(object)new Vector3[list.Count];
			for (int k = 0; k < list.Count; k++)
			{
				SpiralPoints[k] = (list[k] - val) * num11;
			}
			GameObject val2 = new GameObject("GoldenSpiral");
			val2.transform.SetParent(parent, false);
			Spiral = TuskAssets.NewLine(val2, SpiralPoints.Length, worldSpace: false, 0.06f * width);
			Spiral.SetPositions(SpiralPoints);
			Spiral.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
			{
				new Keyframe(0f, 1f),
				new Keyframe(1f, 0.35f)
			});
			foreach (Rect item in list2)
			{
				Rect current = item;
				GameObject val3 = new GameObject("GoldenSquare");
				val3.transform.SetParent(parent, false);
				LineRenderer val4 = TuskAssets.NewLine(val3, 4, worldSpace: false, 0.012f * width);
				val4.loop = true;
				val4.SetPosition(0, (new Vector3(((Rect)(ref current)).xMin, ((Rect)(ref current)).yMin, 0f) - val) * num11);
				val4.SetPosition(1, (new Vector3(((Rect)(ref current)).xMax, ((Rect)(ref current)).yMin, 0f) - val) * num11);
				val4.SetPosition(2, (new Vector3(((Rect)(ref current)).xMax, ((Rect)(ref current)).yMax, 0f) - val) * num11);
				val4.SetPosition(3, (new Vector3(((Rect)(ref current)).xMin, ((Rect)(ref current)).yMax, 0f) - val) * num11);
				Squares.Add(val4);
			}
		}

		public void SetDrawProgress(float progress)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(Mathf.CeilToInt((float)SpiralPoints.Length * Mathf.Clamp01(progress)), 2, SpiralPoints.Length);
			if (Spiral.positionCount != num)
			{
				Spiral.positionCount = num;
				for (int i = 0; i < num; i++)
				{
					Spiral.SetPosition(i, SpiralPoints[i]);
				}
			}
		}

		public void SetColors(Color spiralStart, Color spiralEnd, Color frame)
		{
			//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_0022: 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)
			TuskAssets.SetColor(Spiral, spiralStart, spiralEnd);
			foreach (LineRenderer square in Squares)
			{
				TuskAssets.SetColor(square, frame, frame);
			}
		}
	}
	internal class SpinVisual : MonoBehaviour
	{
		public static readonly List<SpinVisual> Active = new List<SpinVisual>();

		private Transform anchor;

		private Vector3 anchorLocalPoint;

		private float size;

		private GoldenFigure figure;

		private Transform ringRoot;

		private LineRenderer[] rings;

		private Light glow;

		private AudioSource drill;

		private float spinAngle;

		private float spinSpeed = 220f;

		private float pulse;

		private int ticks;

		private bool beatdown;

		public EnemyIdentifier Enemy { get; private set; }

		public float Age { get; private set; }

		public static SpinVisual Create(EnemyIdentifier eid, Collider hitCollider, Vector3 hitPoint)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TuskSpiral");
			SpinVisual spinVisual = val.AddComponent<SpinVisual>();
			spinVisual.Enemy = eid;
			spinVisual.size = TuskUtil.GetSize(eid);
			spinVisual.anchor = (((Object)(object)hitCollider != (Object)null) ? ((Component)hitCollider).transform : ((Component)eid).transform);
			spinVisual.anchorLocalPoint = spinVisual.anchor.InverseTransformPoint(hitPoint);
			val.transform.position = hitPoint;
			spinVisual.Build();
			Active.Add(spinVisual);
			return spinVisual;
		}

		private void Build()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(size * 1.1f, 0.9f, 7f);
			figure = new GoldenFigure(((Component)this).transform, num);
			ringRoot = new GameObject("TuskRings").transform;
			rings = (LineRenderer[])(object)new LineRenderer[3];
			for (int i = 0; i < rings.Length; i++)
			{
				GameObject val = new GameObject("Ring" + i);
				val.transform.SetParent(ringRoot, false);
				val.transform.localRotation = Quaternion.Euler(70f + (float)i * 25f, (float)i * 60f, 0f);
				rings[i] = TuskVfx.WavyRing(val, size * (1.05f + (float)i * 0.18f), 0.05f + size * 0.015f);
			}
			TuskVfx.Swirl(((Component)this).gameObject, num, 0.9f * num, 45f, TuskAssets.PaleGold, TuskAssets.Amber);
			glow = ((Component)this).gameObject.AddComponent<Light>();
			glow.type = (LightType)2;
			glow.color = TuskAssets.Gold;
			glow.range = 3f + size * 3f;
			glow.intensity = 2f;
			glow.shadows = (LightShadows)0;
			drill = TuskAudio.CreateDrillLoop(((Component)this).gameObject);
		}

		public void OnTick()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00ca: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			ticks++;
			pulse = 1f;
			spinSpeed = Mathf.Min(220f + (float)ticks * 90f, 2200f);
			if ((Object)(object)drill != (Object)null)
			{
				drill.pitch = Mathf.Min(0.8f + (float)ticks * 0.06f, 2.4f);
			}
			Vector3 position = ((Component)this).transform.position;
			TuskVfx.SparkBurst(position, 10, 3f, 8f, 0.07f, TuskAssets.PaleGold, TuskAssets.Amber);
			Camera camera = TuskUtil.GetCamera();
			Vector3 normal = (((Object)(object)camera != (Object)null) ? (((Component)camera).transform.position - position) : Vector3.up);
			FadingRing.Spawn(position, normal, size * 0.2f, size * 1.4f, 0.3f, TuskAssets.Gold, 0.05f + size * 0.02f);
		}

		public void SetBeatdown()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			beatdown = true;
			glow.color = new Color(1f, 0.15f, 0.85f);
			Light obj = glow;
			obj.range *= 1.5f;
		}

		private void LateUpdate()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c2: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_0211: 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_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: 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_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)anchor != (Object)null)
			{
				((Component)this).transform.position = anchor.TransformPoint(anchorLocalPoint);
			}
			else if ((Object)(object)Enemy != (Object)null)
			{
				((Component)this).transform.position = TuskUtil.GetCenter(Enemy);
			}
			Age += Time.deltaTime;
			pulse = Mathf.MoveTowards(pulse, 0f, Time.deltaTime * 3.5f);
			spinAngle -= spinSpeed * Time.deltaTime;
			((Component)this).transform.rotation = TuskUtil.FaceCamera(((Component)this).transform.position) * Quaternion.Euler(0f, 0f, spinAngle);
			float num = Mathf.Clamp01(Age / 0.25f);
			float num2 = 1f - (1f - num) * (1f - num);
			((Component)this).transform.localScale = Vector3.one * (num2 * (1f + 0.35f * pulse));
			figure.SetDrawProgress(Age / 0.35f);
			float num3 = 0.85f + 0.15f * Mathf.Sin(Age * 18f);
			Color val = (Color)(beatdown ? new Color(1f, 0.2f, 0.85f) : TuskAssets.Gold);
			Color spiralEnd = (beatdown ? new Color(0.6f, 0.2f, 1f, num3) : new Color(1f, 0.6f, 0.15f, num3));
			Color val2 = Color.Lerp(val, Color.white, pulse * 0.7f);
			figure.SetColors(new Color(val2.r, val2.g, val2.b, num3), spiralEnd, new Color(val.r, val.g, val.b, 0.35f + 0.4f * pulse));
			if ((Object)(object)Enemy != (Object)null)
			{
				ringRoot.position = TuskUtil.GetCenter(Enemy);
				ringRoot.rotation = Quaternion.Euler(0f, (0f - spinAngle) * 0.6f, 0f);
				ringRoot.localScale = Vector3.one * (num2 * (1f + 0.12f * pulse));
				for (int i = 0; i < rings.Length; i++)
				{
					float num4 = 0.55f + 0.35f * pulse;
					Color val3 = (beatdown ? ((i == 1) ? new Color(0.6f, 0.2f, 1f, num4) : new Color(1f, 0.2f, 0.85f, num4)) : ((i == 1) ? new Color(1f, 0.55f, 0.1f, num4) : new Color(1f, 0.85f, 0.3f, num4)));
					TuskAssets.SetColor(rings[i], val3, val3);
					((Component)rings[i]).transform.Rotate(0f, 0f, spinSpeed * ((i % 2 == 0) ? 1f : (-1.3f)) * Time.deltaTime, (Space)1);
				}
			}
			glow.intensity = (beatdown ? (4f + 3f * Mathf.Sin(Age * 14f)) : (1.5f + 4f * pulse + 0.5f * Mathf.Sin(Age * 12f)));
		}

		public void Finale(Vector3 center)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			TuskVfx.Finale(center, size);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			Active.Remove(this);
			if ((Object)(object)ringRoot != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)ringRoot).gameObject);
			}
		}
	}
	internal static class TuskAudio
	{
		private const int Rate = 44100;

		private static AudioClip shot;

		private static AudioClip tick;

		private static AudioClip drill;

		private static AudioClip chumimin;

		private static Random noise = new Random(4);

		private static AudioClip hum;

		private static AudioClip blast;

		private static AudioClip coinPing;

		private static AudioClip wormhole;

		private static AudioClip punch;

		private static float lowpass;

		private static float Volume => Mathf.Clamp01(TuskPlugin.SoundVolume.Value);

		public static void PlayShot()
		{
			if ((Object)(object)shot == (Object)null)
			{
				shot = Synth("TuskShot", 0.7f, ShotSample);
			}
			Play(shot, null, 0.9f, 1f);
		}

		public static void PlayTick(Vector3 position, int tickCount)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tick == (Object)null)
			{
				tick = Synth("TuskTick", 0.25f, TickSample);
			}
			Play(tick, position, 0.45f, Mathf.Min(0.9f + (float)tickCount * 0.04f, 2f));
		}

		public static void PlayChumimin(Vector3 position)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)chumimin == (Object)null)
			{
				chumimin = Synth("TuskChumimin", 1.25f, ChumiminSample);
			}
			Play(chumimin, position, 1f, 1f, 0.3f);
		}

		public static void PlayCoinPing(Vector3 position, float pitch)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)coinPing == (Object)null)
			{
				coinPing = Synth("TuskCoinPing", 0.5f, CoinPingSample);
			}
			Play(coinPing, position, 0.5f, pitch, 0.6f);
		}

		public static void PlayWormhole(Vector3 position, float pitch)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wormhole == (Object)null)
			{
				wormhole = Synth("TuskWormhole", 0.9f, WormholeSample);
			}
			Play(wormhole, position, 0.8f, pitch, 0.5f);
		}

		public static void PlayPunch(Vector3 position, float pitch, float volume = 0.8f)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)punch == (Object)null)
			{
				punch = Synth("TuskPunch", 0.18f, PunchSample);
			}
			Play(punch, position, volume, pitch, 0.4f);
		}

		public static AudioSource CreateVoiceSource(GameObject host)
		{
			AudioSource obj = host.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.loop = false;
			obj.spatialBlend = 0f;
			obj.priority = 0;
			obj.bypassReverbZones = true;
			obj.dopplerLevel = 0f;
			Route(obj);
			return obj;
		}

		public static AudioSource CreateBlackHoleHum(GameObject host, float duration)
		{
			if ((Object)(object)hum == (Object)null)
			{
				hum = Synth("TuskBlackHoleHum", 3f, HumSample);
			}
			AudioSource obj = host.AddComponent<AudioSource>();
			obj.clip = hum;
			obj.volume = 0.9f * Volume;
			obj.pitch = Mathf.Clamp(3f / duration, 0.3f, 3f);
			obj.spatialBlend = 0.7f;
			obj.minDistance = 10f;
			obj.maxDistance = 150f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.dopplerLevel = 0f;
			Route(obj);
			obj.Play();
			return obj;
		}

		public static void PlayBlackHoleBlast(Vector3 position)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)blast == (Object)null)
			{
				blast = Synth("TuskBlackHoleBlast", 2f, BlastSample);
			}
			Play(blast, position, 1f, 1f, 0.4f);
		}

		public static AudioSource CreateDrillLoop(GameObject host)
		{
			if ((Object)(object)drill == (Object)null)
			{
				drill = Synth("TuskDrill", 1f, DrillSample);
			}
			AudioSource obj = host.AddComponent<AudioSource>();
			obj.clip = drill;
			obj.loop = true;
			obj.volume = 0.35f * Volume;
			obj.pitch = 0.8f;
			obj.spatialBlend = 1f;
			obj.minDistance = 4f;
			obj.maxDistance = 70f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.dopplerLevel = 0f;
			Route(obj);
			obj.Play();
			return obj;
		}

		private static void Play(AudioClip clip, Vector3? position, float volume, float pitch, float spatial = 1f)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)clip == (Object)null) && !(Volume <= 0f))
			{
				GameObject val = new GameObject("TuskSound");
				if (position.HasValue)
				{
					val.transform.position = position.Value;
				}
				AudioSource obj = val.AddComponent<AudioSource>();
				obj.clip = clip;
				obj.volume = volume * Volume;
				obj.pitch = pitch;
				obj.spatialBlend = (position.HasValue ? spatial : 0f);
				obj.minDistance = 6f;
				obj.maxDistance = 120f;
				obj.rolloffMode = (AudioRolloffMode)1;
				obj.dopplerLevel = 0f;
				Route(obj);
				obj.Play();
				Object.Destroy((Object)(object)val, clip.length / Mathf.Max(0.1f, pitch) + 0.1f);
			}
		}

		private static void Route(AudioSource src)
		{
			AudioMixerController val = TuskUtil.Get<AudioMixerController>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.allGroup != (Object)null)
			{
				src.outputAudioMixerGroup = val.allGroup;
			}
		}

		private static AudioClip Synth(string name, float seconds, Func<float, float> sample)
		{
			int num = Mathf.CeilToInt(seconds * 44100f);
			float[] array = new float[num];
			float num2 = 0.0001f;
			for (int i = 0; i < num; i++)
			{
				array[i] = sample((float)i / 44100f);
				num2 = Mathf.Max(num2, Mathf.Abs(array[i]));
			}
			float num3 = 0.9f / num2;
			for (int j = 0; j < num; j++)
			{
				array[j] *= num3;
			}
			AudioClip obj = AudioClip.Create(name, num, 1, 44100, false);
			obj.SetData(array, 0);
			((Object)obj).hideFlags = (HideFlags)32;
			return obj;
		}

		private static float Noise()
		{
			return (float)(noise.NextDouble() * 2.0 - 1.0);
		}

		private static float Sin(float phase)
		{
			return Mathf.Sin(phase * MathF.PI * 2f);
		}

		private static float ChirpPhase(float t, float f0, float f1, float d)
		{
			float num = Mathf.Log(f1 / f0) / d;
			return f0 * (Mathf.Exp