BepInEx/plugins/Kulfs-Jak/JakSurvivor.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using EntityStates;
using JakSurvivor.States;
using KinematicCharacterController;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.ConVar;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.SurvivorMannequins;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("JakSurvivor.DevTools")]
[assembly: InternalsVisibleTo("JakSurvivor.Editor")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace JakSurvivor
{
	public sealed class ArcWielderSkillDef : SkillDef
	{
		public override bool CanExecute(GenericSkill slot)
		{
			if (!((SkillDef)this).IsAlreadyInState(slot) && JakWeaponCombat.CanUseWeapons(slot.characterBody))
			{
				return ((SkillDef)this).CanExecute(slot);
			}
			return false;
		}
	}
	public static class Balance
	{
		public readonly struct ClawStep
		{
			public readonly string Clip;

			public readonly float Duration;

			public readonly float HitStart;

			public readonly float HitEnd;

			public readonly float Damage;

			public readonly bool Finisher;

			public readonly Vector3 SlashPosition;

			public readonly Vector3 SlashRotation;

			public readonly Vector3 SlashScale;

			public ClawStep(string clip, float duration, float hitStart, float hitEnd, float damage, bool finisher, Vector3 slashPosition, Vector3 slashRotation, float slashScale)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				Clip = clip;
				Duration = duration;
				HitStart = hitStart;
				HitEnd = hitEnd;
				Damage = damage;
				Finisher = finisher;
				SlashPosition = slashPosition;
				SlashRotation = slashRotation;
				SlashScale = Vector3.one * slashScale;
			}
		}

		public const float BlasterDamage = 2.4f;

		public const float BlasterDuration = 0.3f;

		public const float ScatterCooldown = 5f;

		public const float ArcDamage = 1.6f;

		public const float ArcInterval = 0.4f;

		public const float ArcDamageRetention = 0.75f;

		public const float ArcProc = 0.5f;

		public const int WaveStocks = 2;

		public const float WaveCooldown = 5f;

		public const float WaveMinimumCharge = 0.1f;

		public const float WaveFullCharge = 1f;

		public const float WaveAutoReleaseDelay = 9.95f;

		public const float WaveBaseRadius = 3f;

		public const float WaveRadiusGain = 15f;

		public const float WaveMinimumDamage = 2f;

		public const float WaveFullDamage = 10f;

		public const float WaveOuterRetention = 0.5f;

		public const float WaveProc = 1f;

		public const float WaveExpansionDuration = 0.7f;

		public const float WaveRecoveryDuration = 0.3f;

		public const float WaveForce = 500f;

		public const float SpinDamage = 3.5f;

		public const float SpinProc = 0.5f;

		public const float SpinCooldown = 3f;

		public const float SpinForce = 800f;

		public const float SpinRadius = 4f;

		public const float DarkBlastDamage = 8f;

		public const float DarkBlastProc = 1f;

		public const float DarkBlastCooldown = 3f;

		public const float RollCooldown = 4f;

		public const float BoardDuration = 4f;

		public const float BoardSpeed = 2.64f;

		public const float BoardMinimumRide = 1f;

		public const float BoardCooldown = 6f;

		public const float DarkDuration = 10f;

		public const float DarkCooldown = 24f;

		public const float DarkArmor = 30f;

		public const float DarkMoveBonus = 0.2f;

		public static readonly Vector3 ClawHitBoxCenter = new Vector3(0f, 1.2f, 2.5f);

		public static readonly Vector3 ClawHitBoxSize = new Vector3(4f, 3f, 6f);

		public static readonly ClawStep[] ClawCombo = new ClawStep[3]
		{
			new ClawStep("jakb-darkjak-attack-combo1", 0.333333f, 0.62f, 0.82f, 1.6f, finisher: false, new Vector3(0f, 1.2f, 0.2f), new Vector3(55f, 90f, 90f), 0.405429f),
			new ClawStep("jakb-darkjak-attack-combo2", 0.466666f, 0.76f, 0.92f, 1.9f, finisher: false, new Vector3(0f, 1.2f, 0.2f), new Vector3(20f, 90f, 90f), 0.405429f),
			new ClawStep("jakb-darkjak-attack-combo3c", 0.666664f, 0.7f, 0.82f, 3f, finisher: true, new Vector3(0f, 1.7f, 1f), new Vector3(0f, 90f, 0f), 0.282857f)
		};

		public const float ClawStepGrace = 0.4f;

		public const float DarkBombDamage = 8f;

		public const float DarkBombRadius = 14f;
	}
	public sealed class DarkBlastSkillDef : SkillDef
	{
		private sealed class Instance : BaseSkillInstanceData
		{
			public EntityStateMachine Weapon;
		}

		public override BaseSkillInstanceData OnAssigned(GenericSkill slot)
		{
			return (BaseSkillInstanceData)(object)new Instance
			{
				Weapon = EntityStateMachine.FindByCustomName(((Component)slot).gameObject, "Weapon")
			};
		}

		public override bool CanExecute(GenericSkill slot)
		{
			if (((SkillDef)this).CanExecute(slot) && slot.skillInstanceData is Instance instance && Object.op_Implicit((Object)(object)instance.Weapon))
			{
				return instance.Weapon.CanInterruptState((InterruptPriority)1);
			}
			return false;
		}
	}
	public sealed class DarkBombSkillDef : SkillDef
	{
		public override int GetMaxStock(GenericSkill slot)
		{
			return slot.baseSkill.GetMaxStock(slot);
		}

		public override int GetRechargeStock(GenericSkill slot)
		{
			return slot.baseSkill.GetRechargeStock(slot);
		}

		public override float GetRechargeInterval(GenericSkill slot)
		{
			return slot.baseSkill.GetRechargeInterval(slot);
		}

		public override float GetRechargeRate(GenericSkill slot)
		{
			return slot.baseSkill.GetRechargeRate(slot);
		}
	}
	public sealed class DarkJakSkillDef : SkillDef
	{
		public override bool IsReady(GenericSkill slot)
		{
			if (((SkillDef)this).IsReady(slot))
			{
				return !slot.characterBody.HasBuff(JakContent.DarkBuff);
			}
			return false;
		}
	}
	internal static class Icons
	{
		public static Sprite Blaster => JakAssets.Get<Sprite>("blaster");

		public static Sprite Scatter => JakAssets.Get<Sprite>("scatter");

		public static Sprite ArcWielder => JakAssets.Get<Sprite>("arc_wielder");

		public static Sprite WaveConcussor => JakAssets.Get<Sprite>("wave_concussor");

		public static Sprite Spin => JakAssets.Get<Sprite>("spin");

		public static Sprite Roll => JakAssets.Get<Sprite>("roll");

		public static Sprite Board => JakAssets.Get<Sprite>("board");

		public static Sprite Dark => JakAssets.Get<Sprite>("jak3-icon-dark");

		public static Sprite Claws => JakAssets.Get<Sprite>("jak3-icon-claws");

		public static Sprite DarkBlast => JakAssets.Get<Sprite>("jak3-icon-blast");

		public static Sprite Bomb => JakAssets.Get<Sprite>("jak3-icon-bomb");

		public static Sprite Passive => JakAssets.Get<Sprite>("passive");

		public static Sprite DarkBuff => JakAssets.Get<Sprite>("buff_dark");

		public static Sprite Skin => JakAssets.Get<Sprite>("skin_default");

		public static Sprite Portrait => JakAssets.Get<Sprite>("jak3-portrait");
	}
	internal readonly struct JakShot
	{
		public readonly Ray Ray;

		public readonly bool Spinning;

		public JakShot(Ray ray, bool spinning)
		{
			//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)
			Ray = ray;
			Spinning = spinning;
		}

		public float Interval(float normal)
		{
			if (!Spinning)
			{
				return normal;
			}
			return 0.1f;
		}
	}
	internal static class JakAim
	{
		public static JakShot Shot(EntityStateMachine body, Ray aim)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body) || !(body.state is SpinAttack spinAttack) || !spinAttack.TryAim(aim, out var shot))
			{
				return new JakShot(aim, spinning: false);
			}
			return new JakShot(shot, spinning: true);
		}

		public static bool SpinOwnsGun(EntityStateMachine body)
		{
			if (Object.op_Implicit((Object)(object)body) && body.state is SpinAttack { Timeline: var timeline } spinAttack)
			{
				return timeline.OwnsGun(spinAttack.Age);
			}
			return false;
		}
	}
	public enum JakWeaponMode
	{
		Blaster,
		ArcWielder,
		WaveConcussor
	}
	internal static class JakAnimator
	{
		public static class Layers
		{
			public const string Body = "Body";

			public const string FullBody = "FullBody, Override";

			public const string Gesture = "Gesture, Override";

			public const string Transformation = "Transformation, Override";

			public const string AimPitch = "AimPitch";

			public const string AimYaw = "AimYaw";

			public const string BodyAction = "BodyAction";

			public const string Gun = "Gun";

			public const string Board = "Board";
		}

		public static class States
		{
			public const string Empty = "Empty";

			public const string Idle = "Idle";

			public const string Run = "Run";

			public const string Jump = "Jump";

			public const string Roll = "Roll";

			public const string RollLeap = "RollLeap";

			public const string BonusJump = "BonusJump";

			public const string AscendDescend = "AscendDescend";

			public const string Land = "Land";

			public const string Death = "Death";

			public static readonly string[] ClawCombo = new string[3] { "ClawCombo1", "ClawCombo2", "ClawCombo3" };

			public const string Bomb = "Bomb";

			public const string DarkEnter = "DarkEnter";

			public const string DarkExit = "DarkExit";

			public const string DarkExitEnd = "DarkExitEnd";

			public const string DarkExitBomb = "DarkExitBomb";

			public const string BoardOn = "BoardOn";

			public const string BoardOff = "BoardOff";

			public const string FireBlaster = "FireBlaster";

			public const string FireScatter = "FireScatter";

			public const string ArcStart = "ArcStart";

			public const string ArcLoop = "ArcLoop";

			public const string WaveCharge = "WaveCharge";

			public const string WaveChargeLoop = "WaveChargeLoop";

			public const string WaveRelease = "WaveRelease";

			public const string PitchControl = "PitchControl";

			public const string YawControl = "YawControl";

			public const string BoardOpen = "Open";

			public const string BoardClose = "Close";
		}

		public static class Parameters
		{
			public const string Form = "form";

			public const string MoveForward = "moveForward";

			public const string MoveRight = "moveRight";

			public const string WeaponMode = "weaponMode";

			public const string ArcRate = "Arc.playbackRate";

			public const string WaveRate = "Wave.playbackRate";

			public const string BlasterRate = "Blaster.playbackRate";

			public const string ScatterRate = "Scatter.playbackRate";

			public const string ClawRate = "Claw.playbackRate";

			public const string BombRate = "Bomb.playbackRate";

			public const string TransformRate = "Transform.playbackRate";

			public const string BoardRate = "Board.playbackRate";

			public const string SpinRate = "Spin.playbackRate";

			public const string RollRate = "Roll.playbackRate";

			public const string JumpRate = "Jump.playbackRate";

			public const string ClawHitBoxActive = "Claw.hitBoxActive";
		}

		public static class Spin
		{
			public const string DataAsset = "Jak3Spin";

			public const string HitBoxGroup = "JakSpin";

			public static readonly string[] EndStates = (from i in Enumerable.Range(0, JakSpinRecipe.Count)
				select (JakSpinVariant)i into v
				where JakSpinRecipe.Get(v).EndOverlay != null
				select v).Select(EndState).ToArray();

			public static string State(JakSpinVariant variant)
			{
				return "Spin" + variant;
			}

			public static string EndState(JakSpinVariant variant)
			{
				return "SpinEnd" + JakSpinRecipe.Get(variant).Form;
			}
		}

		public static class Blast
		{
			public const string Charge = "BlastCharge";

			public const string Release = "BlastRelease";

			public const string Recovery = "BlastRecovery";

			public const string Rate = "Blast.playbackRate";

			public static readonly string[] States = new string[3] { "BlastCharge", "BlastRelease", "BlastRecovery" };
		}

		public static class Bomb
		{
			public const float Duration = 0.9f;

			public const float ImpactFraction = 0.5f;

			public const float ImpactSourceTime = 1f / 30f;

			public const float LandingBlend = 0.05f;

			public const float FallTime = 0.36666664f;

			public const string Clip = "jakb-darkjak-bomb@sequence";

			public static void Sample(float time, float windupLength, float landingLength, out float windupTime, out float landingTime, out float landingWeight)
			{
				windupTime = Mathf.Clamp01(time / 0.36666664f) * windupLength;
				landingTime = ((time <= 0.45f) ? Mathf.Max(0f, time - 5f / 12f) : Mathf.Lerp(1f / 30f, landingLength, (time - 0.45f) / 0.45f));
				landingWeight = Mathf.Clamp01((time - 0.36666664f) / 0.05f);
			}
		}

		public static class Weapon
		{
			public const int ArcFrames = 7;

			public const int WaveFrames = 21;

			public const float WaveLoopStartFrame = 5f;

			public const float WaveLoopEndFrame = 8.5f;

			public const float WaveReleaseFrame = 10f;

			public const string ArcBody = "jakb-gun-blue-fire-2";

			public const string ArcGun = "gun-gun-blue-fire-2";

			public const string ArcStance = "jakb-gun-blue-stance-2";

			public const string ArcIdle = "jakb-gun-stance-blue";

			public const string WaveBody = "jakb-gun-red-fire-2";

			public const string WaveGun = "gun-gun-red-fire-2";

			public const string ChargeStart = "@charge-start";

			public const string ChargeLoop = "@charge-loop";

			public const string Release = "@release";

			public static readonly string[] RequiredBodyClips = new string[4] { "jakb-gun-stance-blue", "jakb-gun-blue-stance-2", "jakb-gun-blue-fire-2", "jakb-gun-red-fire-2" };

			public static readonly string[] RequiredGunClips = new string[4] { "gun-idle-blue2", "gun-gun-blue-fire-2", "gun-idle-red2", "gun-gun-red-fire-2" };

			public static readonly string[] ArcLocomotion = new string[7] { "jakb-gun-front-run", "jakb-jump@armed", "jakb-jump-forward@armed", "jakb-jump-double@armed", "jakb-jump-forward-double@armed", "jakb-jump-fall@armed", "jakb-gun-jump-land" };

			public static readonly string[] ActionStates = new string[5] { "ArcStart", "ArcLoop", "WaveCharge", "WaveChargeLoop", "WaveRelease" }.Concat(Spin.EndStates).ToArray();

			public static float FrameTime(float duration, int frames, float frame)
			{
				return duration * frame / (float)(frames - 1);
			}

			public static string ArcClip(string locomotion)
			{
				return locomotion.Replace("@armed", "") + "@arc";
			}
		}

		public static readonly string[] ControllerLayers = new string[9] { "Body", "FullBody, Override", "Transformation, Override", "Gesture, Override", "AimPitch", "AimYaw", "BodyAction", "Gun", "Board" };

		public static readonly string[] PoseLayers = new string[5] { "BodyAction", "Gesture, Override", "Transformation, Override", "FullBody, Override", "Body" };

		public const float JumpAirTime = 1f / 3f;

		public const float BoardAirTime = 0.25f;

		public const float Armed = 0f;

		public const float Dark = 1f;

		public const float Board = 2f;

		public const string BodyController = "animJak";

		public const string DisplayController = "animJakDisplay";

		public const string ModelPrefab = "mdlJak";

		public const string DisplayPrefab = "JakDisplay";

		public const string DrawOffset = "Jak3DrawOffset";

		public const string ClawHitBoxGroup = "JakClaws";

		public static readonly string[] ClawSlashChildren = new string[3] { "ClawSlash0", "ClawSlash1", "ClawSlash2" };

		public static void ArcStart(Animator animator, float sampledRate)
		{
			PlayWeaponAction(animator, "ArcStart", "Arc.playbackRate", sampledRate);
		}

		public static void ArcLoop(Animator animator, float sampledRate)
		{
			PlayWeaponAction(animator, "ArcLoop", "Arc.playbackRate", sampledRate);
		}

		public static void WaveCharge(Animator animator, float sampledRate, float normalizedTime = 0f)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				float num = ClipLength(animator, "jakb-gun-red-fire-2@charge-start");
				float num2 = ClipLength(animator, "jakb-gun-red-fire-2@charge-loop");
				float num3 = Mathf.Clamp01(normalizedTime) * 1f;
				bool flag = num3 >= num;
				float normalizedTime2 = (flag ? (Mathf.Repeat(num3 - num, num2) / num2) : (num3 / num));
				PlayWeaponAction(animator, flag ? "WaveChargeLoop" : "WaveCharge", "Wave.playbackRate", sampledRate, normalizedTime2);
			}
		}

		public static void WaveRelease(Animator animator, float sampledRate)
		{
			PlayWeaponAction(animator, "WaveRelease", "Wave.playbackRate", sampledRate);
		}

		public static void StopWeaponAction(Animator animator)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				int layerIndex = animator.GetLayerIndex("Gesture, Override");
				int layerIndex2 = animator.GetLayerIndex("Gun");
				if (layerIndex >= 0 && layerIndex2 >= 0)
				{
					animator.SetFloat("Arc.playbackRate", 1f);
					animator.SetFloat("Wave.playbackRate", 1f);
					animator.Play("Empty", layerIndex, 0f);
					animator.Play("Idle", layerIndex2, 0f);
				}
			}
		}

		public static bool HasWeaponAction(Animator animator)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)animator))
			{
				return false;
			}
			int layerIndex = animator.GetLayerIndex("Gesture, Override");
			if (layerIndex < 0)
			{
				return false;
			}
			string[] actionStates = Weapon.ActionStates;
			foreach (string text in actionStates)
			{
				AnimatorStateInfo val = animator.GetCurrentAnimatorStateInfo(layerIndex);
				if (!((AnimatorStateInfo)(ref val)).IsName(text))
				{
					if (!animator.IsInTransition(layerIndex))
					{
						continue;
					}
					val = animator.GetNextAnimatorStateInfo(layerIndex);
					if (!((AnimatorStateInfo)(ref val)).IsName(text))
					{
						continue;
					}
				}
				return true;
			}
			return false;
		}

		private static void PlayWeaponAction(Animator animator, string state, string rate, float sampledRate, float normalizedTime = 0f)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				animator.SetFloat(rate, Mathf.Max(0.01f, sampledRate));
				animator.Play(state, animator.GetLayerIndex("Gesture, Override"), normalizedTime);
				animator.Play(state, animator.GetLayerIndex("Gun"), normalizedTime);
			}
		}

		private static float ClipLength(Animator animator, string name)
		{
			AnimationClip[] animationClips = animator.runtimeAnimatorController.animationClips;
			foreach (AnimationClip val in animationClips)
			{
				if (((Object)val).name == name)
				{
					return val.length;
				}
			}
			throw new InvalidOperationException("Required Morph Gun animation is missing: " + name);
		}
	}
	internal sealed class JakArcAudio
	{
		private struct Biquad
		{
			private double b0;

			private double b1;

			private double b2;

			private double a1;

			private double a2;

			private double z1;

			private double z2;

			private Biquad(double b0, double b1, double b2, double a0, double a1, double a2)
			{
				this.b0 = b0 / a0;
				this.b1 = b1 / a0;
				this.b2 = b2 / a0;
				this.a1 = a1 / a0;
				this.a2 = a2 / a0;
				z1 = (z2 = 0.0);
			}

			internal double Process(double input)
			{
				double num = b0 * input + z1;
				z1 = b1 * input - a1 * num + z2;
				z2 = b2 * input - a2 * num;
				return num;
			}

			internal static Biquad LowPass(double hz)
			{
				double num = Math.PI * 2.0 * hz / 48000.0;
				double num2 = Math.Cos(num);
				double num3 = Math.Sin(num) / Math.Sqrt(2.0);
				return new Biquad((1.0 - num2) * 0.5, 1.0 - num2, (1.0 - num2) * 0.5, 1.0 + num3, -2.0 * num2, 1.0 - num3);
			}

			internal static Biquad Peaking(double hz, double q, double db)
			{
				double num = Math.PI * 2.0 * hz / 48000.0;
				double num2 = Math.Cos(num);
				double num3 = Math.Sin(num) / (2.0 * q);
				double num4 = Math.Pow(10.0, db / 40.0);
				return new Biquad(1.0 + num3 * num4, -2.0 * num2, 1.0 - num3 * num4, 1.0 + num3 / num4, -2.0 * num2, 1.0 - num3 / num4);
			}

			internal static Biquad HighShelf(double hz, double db)
			{
				double num = Math.PI * 2.0 * hz / 48000.0;
				double num2 = Math.Cos(num);
				double num3 = Math.Pow(10.0, db / 40.0);
				double num4 = Math.Sin(num) * Math.Sqrt(2.0 * num3);
				return new Biquad(num3 * (num3 + 1.0 + (num3 - 1.0) * num2 + num4), -2.0 * num3 * (num3 - 1.0 + (num3 + 1.0) * num2), num3 * (num3 + 1.0 + (num3 - 1.0) * num2 - num4), num3 + 1.0 - (num3 - 1.0) * num2 + num4, 2.0 * (num3 - 1.0 - (num3 + 1.0) * num2), num3 + 1.0 - (num3 - 1.0) * num2 - num4);
			}
		}

		private Biquad tone;

		private Biquad edge;

		private Biquad hiss;

		private readonly float authoredGain;

		private readonly float level;

		private readonly float detectorScale;

		private readonly bool beam;

		private readonly float[] delay;

		private int delayAt;

		private double reduction;

		private static readonly double Attack = Math.Exp(-1.0 / 288.0);

		private static readonly double Release = Math.Exp(-0.0002314814814814815);

		private const double Threshold = -32.0;

		private const double Knee = 12.0;

		private const double Ratio = 1.18;

		private const double Slope = 0.15254237288135586;

		private const float OutputGain = 2f;

		private static readonly double MakeupTrim = Math.Pow(10.0, (0.0 - Compression(0.0) + -4.8813559322033875) * 0.6 / 20.0);

		internal static Func<float, float> Create(string key, float gameplayGain)
		{
			return key switch
			{
				"arc-loop" => new JakArcAudio(8300.0, 0.65f, 0.7f, gameplayGain, beam: true).Process, 
				"arc-spin" => new JakArcAudio(3000.0, 0.20799999f, 0.76f, gameplayGain, beam: false).Process, 
				"blue-gun-whine" => new JakArcAudio(1300.0, 0.097500004f, 1f, gameplayGain, beam: false).Process, 
				_ => null, 
			};
		}

		private JakArcAudio(double cutoff, float authoredGain, float level, float gameplayGain, bool beam)
		{
			this.authoredGain = authoredGain;
			this.level = level * 2f;
			this.beam = beam;
			tone = Biquad.LowPass(cutoff);
			if (beam)
			{
				edge = Biquad.Peaking(3000.0, 0.85, -4.5);
				hiss = Biquad.HighShelf(5000.0, -3.5);
				delay = new float[288];
				detectorScale = Math.Max(1E-06f, gameplayGain * 0.75f * 0.7f);
			}
		}

		private float Process(float sample)
		{
			double num = tone.Process(sample * authoredGain);
			if (!beam)
			{
				return (float)num * level;
			}
			num = hiss.Process(edge.Process(num));
			double num2 = Compression(20.0 * Math.Log10(Math.Max(1E-12, Math.Abs(num) * (double)detectorScale)));
			double num3 = ((num2 < reduction) ? Attack : Release);
			reduction = num2 + num3 * (reduction - num2);
			float num4 = delay[delayAt];
			delay[delayAt] = (float)num;
			if (++delayAt == delay.Length)
			{
				delayAt = 0;
			}
			return (float)((double)num4 * Math.Pow(10.0, reduction / 20.0) * MakeupTrim) * level;
		}

		private static double Compression(double db)
		{
			double num = db - -32.0;
			if (num <= 0.0)
			{
				return 0.0;
			}
			if (!(num < 12.0))
			{
				return -0.15254237288135586 * (num - 6.0);
			}
			return -0.15254237288135586 * num * num / 24.0;
		}
	}
	internal sealed class JakArcRope
	{
		internal struct V
		{
			internal float x;

			internal float y;

			internal float z;

			internal float Length => (float)Math.Sqrt(Dot(this, this));

			internal V Unit
			{
				get
				{
					float length = Length;
					if (!(length > 0f))
					{
						return default(V);
					}
					return this / length;
				}
			}

			internal V(float x, float y, float z)
			{
				this.x = x;
				this.y = y;
				this.z = z;
			}

			public static V operator +(V a, V b)
			{
				return new V(a.x + b.x, a.y + b.y, a.z + b.z);
			}

			public static V operator -(V a, V b)
			{
				return new V(a.x - b.x, a.y - b.y, a.z - b.z);
			}

			public static V operator *(V a, float b)
			{
				return new V(a.x * b, a.y * b, a.z * b);
			}

			public static V operator /(V a, float b)
			{
				return a * (1f / b);
			}

			internal static float Dot(V a, V b)
			{
				return a.x * b.x + a.y * b.y + a.z * b.z;
			}

			internal static V Cross(V a, V b)
			{
				return new V(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
			}

			internal static V Lerp(V a, V b, float t)
			{
				return a + (b - a) * t;
			}

			internal static V Rotate(V v, V axis, float radians)
			{
				float num = (float)Math.Cos(radians);
				return v * num + Cross(axis, v) * (float)Math.Sin(radians) + axis * (Dot(axis, v) * (1f - num));
			}

			internal static void Frame(V forward, V up, out V right, out V vertical)
			{
				right = Cross(up, forward).Unit;
				if (right.Length == 0f)
				{
					right = Cross(new V(1f, 0f, 0f), forward).Unit;
				}
				vertical = Cross(forward, right).Unit;
			}
		}

		internal interface IWorld
		{
			int Targets { get; }

			float Probe(V start, V end, float radius);

			int Target(int index, V point, out V centre, out float distance);

			bool Visible(V from, V to);
		}

		internal struct Knot
		{
			internal V Point;

			internal V Direction;

			internal float Length;
		}

		internal readonly struct Span
		{
			internal readonly V Start;

			internal readonly V End;

			internal readonly int StartId;

			internal Span(V start, V end, int startId)
			{
				Start = start;
				End = end;
				StartId = startId;
			}
		}

		internal sealed class ArcPath
		{
			internal readonly V[] Points = new V[12];

			internal readonly int[] TargetIds = new int[12];

			internal readonly Span[] Spans = new Span[12];

			internal int Count;

			internal int SpanCount;

			internal bool Terminal;

			internal float RepeatDistance => Math.Min(64f, (Points[Count - 1] - Points[0]).Length + 4f);
		}

		internal const int Knots = 12;

		internal const float KnotLength = 6f;

		internal const float TargetRadius = 4f;

		internal const float TargetDot = 0.6f;

		internal const float KeepRadius = 8f;

		internal const float SweepRadius = 1f;

		internal const float MaxTurnDegreesPerSecond = 720f;

		internal const float CarryDegreesPerSecond = 360f;

		internal const float FullReach = 66f;

		internal static float FollowSeconds = 0.025f;

		internal static float AimSeconds = 0.07f;

		internal static float GrabSeconds = 0.08f;

		internal static float ReachSpeed = 250f;

		internal readonly Knot[] Constraints = new Knot[12];

		internal readonly ArcPath Path = new ArcPath();

		private readonly int[] found = new int[12];

		private readonly int[] held = new int[12];

		private readonly int[] grabbed = new int[12];

		private readonly int[] keep = new int[1];

		private int[] occluded = new int[12];

		private readonly float[] weights = new float[12];

		private readonly V[] centres = new V[12];

		private readonly V[] offsets = new V[12];

		private V previousBody;

		private V aim;

		private V requested;

		internal float Reach { get; private set; }

		internal float RevolveAngle { get; private set; }

		internal float SwayAngle { get; private set; }

		internal void Enter(V fire, V direction, V body)
		{
			previousBody = body;
			direction = direction.Unit;
			aim = (requested = direction);
			Reach = 0f;
			Array.Clear(held, 0, 12);
			Array.Clear(grabbed, 0, 12);
			Array.Clear(weights, 0, 12);
			for (int i = 0; i < 12; i++)
			{
				Constraints[i] = new Knot
				{
					Point = fire + direction * (6f * (float)i),
					Direction = direction,
					Length = 6f
				};
			}
		}

		internal static V Follow(V from, V to, float delta, float seconds)
		{
			float num = V.Dot(from, to);
			V v = V.Cross(from, to);
			float length = v.Length;
			if (length == 0f)
			{
				if (!(num < 0f))
				{
					return from;
				}
				return to;
			}
			return V.Rotate(from, v / length, (float)Math.Atan2(length, num) * (1f - (float)Math.Exp((0f - delta) / seconds))).Unit;
		}

		internal void Constrain(float delta)
		{
			for (int i = 0; i < 11; i++)
			{
				V v = Constraints[i + 1].Point - Constraints[i].Point;
				float length = v.Length;
				v = v.Unit;
				V unit = Constraints[i].Direction.Unit;
				float num = V.Dot(v, unit);
				V v2 = V.Cross(v, unit);
				float length2 = v2.Length;
				if (length2 > 0f && held[i + 1] == 0)
				{
					float radians = Math.Min((float)Math.Atan2(length2, num) * (1f - (float)Math.Exp((0f - delta) / FollowSeconds)), 720f * delta * MathF.PI / 180f);
					v = V.Rotate(v, v2 / length2, radians).Unit;
					Constraints[i + 1].Direction = v;
					Constraints[i + 1].Point = Constraints[i].Point + v * length;
				}
			}
			for (int j = 0; j < 11; j++)
			{
				Constraints[j + 1].Point = Constraints[j].Point + (Constraints[j + 1].Point - Constraints[j].Point).Unit * Constraints[j].Length;
			}
		}

		internal void Update(V fire, V direction, V body, float delta, bool active, IWorld world, float age = -1f)
		{
			if (active)
			{
				RevolveAngle += 65536f * delta;
				SwayAngle += 65536f * delta;
			}
			V v = body - previousBody;
			previousBody = body;
			for (int i = 0; i < 12; i++)
			{
				Constraints[i].Point += v;
			}
			direction = direction.Unit;
			V v2 = V.Cross(requested, direction);
			float length = v2.Length;
			float num = (float)Math.Atan2(length, V.Dot(requested, direction));
			if (length > 0f && num <= 360f * delta * MathF.PI / 180f)
			{
				aim = V.Rotate(aim, v2 / length, num).Unit;
			}
			requested = direction;
			aim = Follow(aim, direction, delta, AimSeconds);
			direction = aim;
			Constraints[0].Point = fire;
			Constraints[0].Direction = direction;
			Reach = Math.Min(66f, (age >= 0f) ? (ReachSpeed * age) : (Reach + ReachSpeed * delta));
			Constrain(delta);
			int num2 = 11;
			while (num2 > 0 && (float)num2 * 6f > Reach)
			{
				Constraints[num2].Direction = direction;
				Constraints[num2].Point = fire + direction * ((float)num2 * 6f);
				num2--;
			}
			Array.Clear(Path.TargetIds, 0, 12);
			Path.Count = 1;
			Path.SpanCount = 0;
			Path.Terminal = false;
			for (int j = 0; j < 12; j++)
			{
				Path.Points[j] = Constraints[j].Point;
			}
			V v3 = fire - direction * 1.8f;
			V v4 = v3 + direction * 2.16f;
			float num3 = world.Probe(v3, v4, 0.1f);
			float num4 = delta / GrabSeconds;
			if (num3 >= 0f)
			{
				Path.Points[0] = V.Lerp(v3, v4, num3);
				Path.Terminal = true;
				Release(1, num4);
				Array.Clear(held, 0, 12);
				return;
			}
			Path.Spans[Path.SpanCount++] = new Span(v3, v4, 0);
			int count = 0;
			int num5 = -1;
			int num6 = 1;
			float num7 = 1f;
			for (int k = 1; k < 12; k++)
			{
				float num8 = Clamp((Reach - (float)(k - 1) * 6f) / 6f);
				if (num8 <= 0f)
				{
					break;
				}
				num6 = k + 1;
				num7 = num8;
				V v5 = Path.Points[k];
				V centre = default(V);
				keep[0] = held[k];
				bool flag = keep[0] != 0;
				V v6 = (flag ? Constraints[k - 1].Direction : Constraints[k].Direction);
				V point = (flag ? (Constraints[k - 1].Point + v6 * (6f * num7)) : V.Lerp(Constraints[k - 1].Point, v5, num7));
				int num9 = FindTarget(world, Path.Points[k - 1], Constraints[k - 1].Point, point, v6, fire, direction, count, keep, flag ? 1 : 0, out centre);
				if (num9 != 0)
				{
					found[count++] = num9;
					Path.TargetIds[k] = num9;
					num5 = k;
					V v7 = Follow(Constraints[k].Direction.Unit, (centre - Constraints[k - 1].Point).Unit, delta, GrabSeconds);
					Constraints[k].Direction = v7;
					Constraints[k].Point = Constraints[k - 1].Point + v7 * Constraints[k - 1].Length;
				}
				else
				{
					Constraints[k].Direction = (Constraints[k].Point - Constraints[k - 1].Point).Unit;
				}
				if (num9 != 0 && (weights[k] == 0f || grabbed[k] == num9))
				{
					grabbed[k] = num9;
					centres[k] = centre;
					weights[k] = Math.Min(1f, weights[k] + num4);
				}
				else
				{
					Release(k, k + 1, num4);
				}
				v5 = V.Lerp(v5, centres[k], weights[k]);
				V v8 = Path.Points[k - 1];
				if (num7 < 1f)
				{
					v5 = V.Lerp(v8, v5, num7);
				}
				num3 = world.Probe(v8, v5, 0.21f);
				if (num3 >= 0f)
				{
					v5 = V.Lerp(v8, v5, num3);
					Path.Terminal = true;
				}
				Path.Points[k] = v5;
				Path.Count++;
				Path.Spans[Path.SpanCount++] = new Span(v8, v5, (weights[k - 1] >= 1f) ? grabbed[k - 1] : 0);
				if (num3 >= 0f || num7 < 1f)
				{
					break;
				}
			}
			Release(num6, num4);
			Array.Copy(Path.TargetIds, held, 12);
			if (num5 == Path.Count - 2)
			{
				Path.Terminal = false;
			}
			for (int l = 1; l < Path.Count; l++)
			{
				V.Frame(Constraints[l].Direction, new V(0f, 1f, 0f), out var _, out var vertical);
				short num10 = (short)(int)(RevolveAngle + 6144f * (float)l);
				offsets[l] = V.Rotate(vertical, Constraints[l].Direction, (float)num10 * 9.58738E-05f).Unit * (0.5f * (1f - weights[l]));
			}
			for (int m = 1; m < Path.Count; m++)
			{
				Path.Points[m] += ((m < Path.Count - 1 || num7 >= 1f) ? offsets[m] : V.Lerp((m > 1) ? offsets[m - 1] : default(V), offsets[m], num7));
			}
		}

		private void Release(int from, float grab)
		{
			Release(from, 12, grab);
		}

		private void Release(int from, int to, float grab)
		{
			for (int i = from; i < to; i++)
			{
				weights[i] = Math.Max(0f, weights[i] - grab);
				if (weights[i] == 0f)
				{
					grabbed[i] = 0;
				}
			}
		}

		private int FindTarget(IWorld world, V from, V previous, V point, V direction, V fire, V aim, int count, int[] held, int heldCount, out V centre)
		{
			int num = 0;
			int num2;
			while (true)
			{
				num2 = 0;
				float nearest = 8f;
				centre = default(V);
				int i = 0;
				for (int targets = world.Targets; i < targets; i++)
				{
					V centre2;
					float distance;
					int num3 = world.Target(i, point, out centre2, out distance);
					if (heldCount > 0 && num3 == held[0] && !Has(found, count, num3) && OnAim(fire, aim, centre2))
					{
						distance = 0f;
					}
					else if (!Candidate(previous, direction, centre2, distance, num3, found, count, held, heldCount, nearest))
					{
						continue;
					}
					if (!Has(occluded, num, num3))
					{
						nearest = distance;
						num2 = num3;
						centre = centre2;
					}
				}
				if (num2 == 0 || world.Visible(from, centre))
				{
					break;
				}
				if (num == occluded.Length)
				{
					Array.Resize(ref occluded, num * 2);
				}
				occluded[num++] = num2;
			}
			return num2;
		}

		internal static bool Candidate(V previous, V direction, V centre, float distance, int id, int[] excluded, int count, int[] held, int heldCount, float nearest)
		{
			if (id == 0 || distance >= nearest || Has(excluded, count, id))
			{
				return false;
			}
			bool num = Has(held, heldCount, id);
			float num2 = V.Dot((centre - previous).Unit, direction);
			if (!num)
			{
				if (distance < 4f)
				{
					return num2 > 0.6f;
				}
				return false;
			}
			if (distance < 8f)
			{
				return num2 > 0f;
			}
			return false;
		}

		private static bool Has(int[] ids, int count, int id)
		{
			for (int i = 0; i < count; i++)
			{
				if (ids[i] == id)
				{
					return true;
				}
			}
			return false;
		}

		private static bool OnAim(V fire, V aim, V centre)
		{
			V v = centre - fire;
			float num = V.Dot(v, aim);
			if (num > 0f)
			{
				return (v - aim * num).Length < 1f;
			}
			return false;
		}

		internal static float Clamp(float value)
		{
			return Math.Max(0f, Math.Min(1f, value));
		}
	}
	internal struct ArcCandidate
	{
		internal readonly int Health;

		internal readonly int Box;

		internal readonly Vector3 Point;

		internal readonly float Radius;

		internal float Distance;

		internal float Score;

		internal byte Flags;

		internal ArcCandidate(int health, int box, Vector3 point, float radius = 0f)
		{
			Health = health;
			Box = box;
			Point = point;
			Radius = Math.Max(0f, radius);
			Distance = (Score = 0f);
			Flags = 0;
		}
	}
	internal struct ArcFocus
	{
		internal int Health;

		internal int Box;
	}
	internal interface IArcWorld
	{
		bool Visible(Vector3 from, int candidate);
	}
	internal static class JakArcTargeting
	{
		private const byte Eligible = 1;

		private const byte Occluded = 2;

		internal const float Reach = 88f;

		internal const float ConeDegrees = 30f;

		internal const float AirReach = 30f;

		private static readonly float ConeTangent = (float)Math.Tan(Math.PI / 6.0);

		internal static int Select(Vector3 origin, Vector3 direction, ArcCandidate[] candidates, int count, IArcWorld world, ArcFocus focus, bool airborne = false)
		{
			float num = direction.Length();
			if (num <= 0f)
			{
				return -1;
			}
			direction /= num;
			for (int i = 0; i < count; i++)
			{
				ref ArcCandidate reference = ref candidates[i];
				reference.Flags = 0;
				reference.Distance = 0f;
				Vector3 vector = reference.Point - origin;
				float num2 = vector.LengthSquared();
				if (reference.Health == 0 || reference.Box == 0 || num2 <= 0f)
				{
					continue;
				}
				reference.Distance = (float)Math.Sqrt(num2);
				float num3 = Vector3.Dot(vector, direction);
				float num4 = Math.Max(-1f, Math.Min(1f, num3 / reference.Distance));
				float num5 = reference.Distance - reference.Radius;
				reference.Score = (airborne ? num5 : (num5 * Math.Max(0.01f, 1f - num4)));
				if (num5 >= (airborne ? 30f : 88f))
				{
					continue;
				}
				if (airborne)
				{
					if (num3 < 0f)
					{
						continue;
					}
				}
				else if ((float)Math.Sqrt(Math.Max(0f, num2 - num3 * num3)) - reference.Radius > num3 * ConeTangent)
				{
					continue;
				}
				reference.Flags = 1;
			}
			while (true)
			{
				int num6 = -1;
				for (int j = 0; j < count; j++)
				{
					if ((candidates[j].Flags & 3) == 1 && (num6 < 0 || Ranked(in candidates[j], in candidates[num6])))
					{
						num6 = j;
					}
				}
				if (num6 < 0)
				{
					break;
				}
				if (world.Visible(origin, num6))
				{
					return num6;
				}
				candidates[num6].Flags |= 2;
			}
			for (int k = 0; k < count; k++)
			{
				ref ArcCandidate reference2 = ref candidates[k];
				if (focus.Health == 0 || reference2.Health != focus.Health || reference2.Box != focus.Box || (reference2.Flags & 2) != 0 || reference2.Distance <= 0f)
				{
					continue;
				}
				float num7 = Vector3.Dot(reference2.Point - origin, direction) / reference2.Distance;
				if (airborne)
				{
					if (reference2.Distance > 25f && num7 < 0.5f)
					{
						return -1;
					}
				}
				else
				{
					Vector3 vector2 = reference2.Point - origin;
					float num8 = (float)Math.Sqrt((vector2.X * vector2.X + vector2.Z * vector2.Z) * (direction.X * direction.X + direction.Z * direction.Z));
					if (num8 > 0f && (vector2.X * direction.X + vector2.Z * direction.Z) / num8 < -0.5f)
					{
						return -1;
					}
				}
				if (!world.Visible(origin, k))
				{
					return -1;
				}
				return k;
			}
			return -1;
		}

		private static bool Ranked(in ArcCandidate a, in ArcCandidate b)
		{
			if (a.Score != b.Score)
			{
				return a.Score < b.Score;
			}
			if (a.Health == b.Health)
			{
				return a.Box < b.Box;
			}
			return a.Health < b.Health;
		}
	}
	[DisallowMultipleComponent]
	[DefaultExecutionOrder(10010)]
	internal sealed class JakArcTracker : MonoBehaviour
	{
		internal enum Phase
		{
			Active,
			Inactive,
			Dead
		}

		internal bool CaptureHidden;

		private readonly JakLightningBolt.TickClock clock = new JakLightningBolt.TickClock();

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

		private JakWeaponRules.PulseGate gate;

		private CharacterBody body;

		private JakWeaponPresentation presentation;

		private JakWeaponCombat combat;

		private JakArcWorld world;

		private Transform muzzle;

		private Transform model;

		private Random random;

		private Mesh[] meshes;

		private Material[] materials;

		private JakLightningBolt.Vertex[][] strips;

		private JakEffectPlayer effect;

		private uint effectLease;

		private JakAudio.Voice loop;

		private JakAudio.Voice spin;

		private Vector3[] positions;

		private Vector2[] uvs;

		private Vector2[] ends;

		private Color32[] colors;

		private JakShockSpec explodeSpec;

		private JakShockSpec terminalSpec;

		private float spinIntensity;

		private int lastSpark;

		private int sparkInterval;

		private int stateTick;

		private int sampledFrame;

		private bool requested;

		private uint actionId;

		internal Phase State { get; private set; } = Phase.Dead;

		internal JakArcRope Rope { get; private set; }

		internal JakLightningBolt[] Bolts { get; private set; }

		internal int CosmeticHitCount { get; private set; }

		internal int ResourceCount
		{
			get
			{
				if (meshes != null)
				{
					return meshes.Length;
				}
				return 0;
			}
		}

		internal Transform Muzzle => muzzle;

		private int Layer
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)muzzle))
				{
					return ((Component)this).gameObject.layer;
				}
				return ((Component)muzzle).gameObject.layer;
			}
		}

		internal void Drive(uint id, Transform follow)
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			SampleClock();
			requested = id != 0 && Object.op_Implicit((Object)(object)follow);
			if (!requested)
			{
				return;
			}
			body = ((Component)this).GetComponent<CharacterBody>();
			presentation = ((Component)this).GetComponent<JakWeaponPresentation>();
			combat = ((Component)this).GetComponent<JakWeaponCombat>();
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
			if ((Object)(object)model != (Object)(object)val || (Object)(object)muzzle != (Object)(object)follow)
			{
				Kill();
			}
			model = val;
			muzzle = follow;
			requested = true;
			if (State == Phase.Active && (!Object.op_Implicit((Object)(object)effect) || !effect.IsLease(effectLease)))
			{
				Release();
			}
			if (State == Phase.Active)
			{
				actionId = id;
				return;
			}
			if (Rope == null)
			{
				Initialize(id);
			}
			Rope.Enter(JakArcWorld.ToV(muzzle.position), JakArcWorld.ToV(Aim()), JakArcWorld.ToV(((Component)body).transform.position));
			JakLightningBolt[] bolts = Bolts;
			for (int i = 0; i < bolts.Length; i++)
			{
				bolts[i].Fade(0, clock.Now);
			}
			State = Phase.Active;
			actionId = id;
			effect = JakEffectPlayer.Spawn("arc-muzzle", muzzle.position, Quaternion.identity, muzzle);
			effectLease = effect.LeaseId;
			((Component)effect).gameObject.layer = Layer;
			effect.Driven = true;
			stateTick = clock.Now;
		}

		private void Initialize(uint id)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			lastSpark = (sparkInterval = 0);
			random = new Random((int)id);
			Rope = new JakArcRope();
			world = new JakArcWorld(body);
			explodeSpec = JakEffects.ShockSpec("lightning-blue-shot-attack-explode");
			terminalSpec = JakEffects.ShockSpec("lightning-blue-shot-terminal");
			Bolts = new JakLightningBolt[6];
			meshes = (Mesh[])(object)new Mesh[12];
			materials = (Material[])(object)new Material[2];
			strips = new JakLightningBolt.Vertex[12][];
			for (int i = 0; i < 6; i++)
			{
				Bolts[i] = new JakLightningBolt(random, i >= 4);
				for (int j = 0; j < 2; j++)
				{
					int num = i * 2 + j;
					int capacity = Bolts[i].Capacity;
					strips[num] = new JakLightningBolt.Vertex[capacity];
					meshes[num] = new Mesh
					{
						name = "JakNativeArcStrip"
					};
					meshes[num].MarkDynamic();
					meshes[num].vertices = (Vector3[])(object)new Vector3[capacity];
					meshes[num].triangles = Triangles(capacity);
				}
			}
			int capacity2 = Bolts[0].Capacity;
			positions = (Vector3[])(object)new Vector3[capacity2];
			uvs = (Vector2[])(object)new Vector2[capacity2];
			ends = (Vector2[])(object)new Vector2[capacity2];
			colors = (Color32[])(object)new Color32[capacity2];
			materials[0] = CreateMaterial("jak3-vfx-lightning-tile.png");
			materials[1] = CreateMaterial("jak3-vfx-pal-lightning.png");
		}

		internal static Material CreateMaterial(string texture)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Material val = new Material(JakEffects.Assets.lightningShader);
			val.SetTexture("_MainTex", JakEffects.Material(texture).GetTexture("_MainTex"));
			return val;
		}

		internal void Release()
		{
			SampleClock();
			requested = false;
			if (State == Phase.Active)
			{
				if (Object.op_Implicit((Object)(object)effect))
				{
					effect.Release(effectLease);
				}
				effect = null;
				JakLightningBolt[] bolts = Bolts;
				for (int i = 0; i < bolts.Length; i++)
				{
					bolts[i].Fade(2, clock.Now);
				}
				stateTick = clock.Now;
				State = Phase.Inactive;
			}
		}

		private void Awake()
		{
			clock.Reset(Time.time);
			sampledFrame = Time.frameCount;
		}

		private void SampleClock()
		{
			if (sampledFrame != Time.frameCount)
			{
				sampledFrame = Time.frameCount;
				clock.Advance(Time.deltaTime);
			}
		}

		private void OnEnable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Draw));
		}

		private void LateUpdate()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			SampleClock();
			if (State == Phase.Dead)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive || !Object.op_Implicit((Object)(object)muzzle) || !((Component)muzzle).gameObject.activeInHierarchy || !Object.op_Implicit((Object)(object)body.modelLocator) || (Object)(object)model != (Object)(object)body.modelLocator.modelTransform)
			{
				Kill();
				return;
			}
			if (!requested)
			{
				Release();
			}
			Sound();
			if (State == Phase.Active || Bolts[0].FadeMode != 3)
			{
				Rope.Update(JakArcWorld.ToV(muzzle.position), JakArcWorld.ToV(Aim()), JakArcWorld.ToV(((Component)body).transform.position), Time.deltaTime, State == Phase.Active, world, (State == Phase.Active && combat.ActionKind == JakWeaponCombat.Kind.Arc) ? combat.ActionAge : (-1f));
				JakLightningBolt[] bolts = Bolts;
				foreach (JakLightningBolt obj in bolts)
				{
					obj.Setup(Rope.Path);
					obj.Update(clock.Now, clock.Previous);
				}
				if (Rope.Path.Terminal && clock.Now - lastSpark >= sparkInterval)
				{
					lastSpark = clock.Now;
					sparkInterval = 5 * JakLightningBolt.IntRange(random, 3, 5);
					int num = JakLightningBolt.IntRange(random, 3, 5);
					for (int j = 0; j < num; j++)
					{
						JakShock.ProbeReplace(((Component)this).gameObject, terminalSpec, 168, JakArcWorld.ToVector(Rope.Path.Points[Rope.Path.Count - 1]), null, Layer);
					}
				}
				if (State == Phase.Active)
				{
					CosmeticSweep();
				}
			}
			if (State == Phase.Inactive)
			{
				JakLightningBolt[] bolts = Bolts;
				for (int i = 0; i < bolts.Length; i++)
				{
					bolts[i].Update(clock.Now, clock.Previous);
				}
				if (clock.Now - stateTick >= 2400)
				{
					Kill();
				}
			}
		}

		private void Sound()
		{
			float num = (Object.op_Implicit((Object)(object)presentation) ? presentation.GunSpinSpeed : 0f);
			float num2 = (float)(clock.Now - stateTick) / 60f;
			bool flag = State == Phase.Active;
			float num3 = (flag ? (1f - Square(1f - JakArcRope.Clamp(num / 109226.664f))) : JakArcRope.Clamp(num / 218453.33f));
			float num4 = 2f * Time.deltaTime;
			spinIntensity = ((spinIntensity < num3) ? Mathf.Min(num3, spinIntensity + num4) : Mathf.Max(num3, spinIntensity - num4));
			if (flag)
			{
				loop = JakAudio.Play("arc-loop", ((Component)muzzle).gameObject, null, loop: true, 0.8f, menu: false, (num2 < 1f) ? (1524f * Mathf.Lerp(-0.5f, 0f, num2)) : 0f, 768f);
			}
			else if (num2 < 1f)
			{
				loop = JakAudio.Play("arc-loop", ((Component)muzzle).gameObject, null, loop: true, 0.8f, menu: false, 1524f * Mathf.Lerp(0f, -0.5f, num2), 768f);
			}
			else
			{
				JakAudio.Stop(loop);
				loop = null;
			}
			if (spinIntensity > (flag ? 0.1f : 0.001f))
			{
				spin = JakAudio.Play("arc-spin", ((Component)muzzle).gameObject, null, loop: true, 0.8f, menu: false, volume1024: 1024f * Mathf.Lerp(flag ? 0.75f : 0.3f, 1f, spinIntensity), pitchMod: 1524f * Mathf.Lerp(-0.5f, 0f, spinIntensity));
			}
			else if (!flag)
			{
				JakAudio.Stop(spin);
				spin = null;
			}
		}

		private static float Square(float value)
		{
			return value * value;
		}

		private Vector3 Aim()
		{
			//IL_002d: 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)
			world.Focus = combat.ArcFocus;
			world.BeginUpdate();
			return world.Direction(muzzle.position, combat.ArcShot());
		}

		private void CosmeticSweep()
		{
			if (gate.TryPulse((double)clock.Now / 300.0, combat.SampledAttackSpeed))
			{
				victims.Clear();
			}
			for (int i = 0; i < Rope.Path.SpanCount; i++)
			{
				Vector3 point;
				HurtBox val = world.Sweep(Rope.Path.Spans[i], victims, out point);
				if (Object.op_Implicit((Object)(object)val))
				{
					victims.Add(((Object)val.healthComponent).GetInstanceID());
					CosmeticHitCount++;
					if (JakLightningBolt.IntRange(random, 0, 10) < 2)
					{
						JakShock.Probe(((Component)this).gameObject, explodeSpec, 664, JakShock.VictimJoint(val), ((Component)val.healthComponent).gameObject, Layer);
					}
				}
			}
		}

		private void Draw(Camera camera)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!CaptureHidden && State != Phase.Dead && Object.op_Implicit((Object)(object)camera) && meshes != null && (camera.cullingMask & (1 << Layer)) != 0)
			{
				for (int i = 0; i < 6; i++)
				{
					Bolts[i].Emit(JakArcWorld.ToV(((Component)camera).transform.up), strips[i * 2], strips[i * 2 + 1], out var count, out var count2);
					DrawStrip(camera, i * 2, count, Bolts[i].Width, materials[(i >= 4) ? 1u : 0u]);
					DrawStrip(camera, i * 2 + 1, count2, Bolts[i].Width, materials[(i >= 4) ? 1u : 0u]);
				}
			}
		}

		internal static int[] Triangles(int count)
		{
			int[] array = new int[Math.Max(0, count - 2) * 3];
			for (int i = 0; i < count - 2; i++)
			{
				array[i * 3] = i;
				array[i * 3 + 1] = i + ((i % 2 == 0) ? 1 : 2);
				array[i * 3 + 2] = i + ((i % 2 != 0) ? 1 : 2);
			}
			return array;
		}

		internal static Vector2 EndFade(JakLightningBolt.Vertex vertex, float length, float width)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(vertex.Distance / width, (length - vertex.Distance) / width);
		}

		private void DrawStrip(Camera camera, int index, int count, float width, Material material)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if (count >= 3)
			{
				Mesh val = meshes[index];
				int num = strips[index].Length;
				float distance = strips[index][count - 1].Distance;
				for (int i = 0; i < num; i++)
				{
					JakLightningBolt.Vertex vertex = strips[index][Math.Min(i, count - 1)];
					positions[i] = JakArcWorld.ToVector(vertex.Position);
					uvs[i] = new Vector2(vertex.U, vertex.V);
					ends[i] = EndFade(vertex, distance, width);
					colors[i] = new Color32((byte)128, (byte)128, (byte)128, vertex.Alpha);
				}
				val.SetVertices(positions, 0, num);
				val.SetUVs(0, uvs, 0, num);
				val.SetUVs(1, ends, 0, num);
				val.SetColors(colors, 0, num);
				val.RecalculateBounds();
				Graphics.DrawMesh(val, Matrix4x4.identity, material, Layer, camera, 0, (MaterialPropertyBlock)null, (ShadowCastingMode)0, false);
			}
		}

		internal void Kill()
		{
			Release();
			JakShock.Clear(((Component)this).gameObject);
			JakAudio.Stop(loop);
			JakAudio.Stop(spin);
			loop = (spin = null);
			spinIntensity = 0f;
			if (meshes != null)
			{
				Mesh[] array = meshes;
				foreach (Mesh val in array)
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						Object.Destroy((Object)(object)val);
					}
				}
			}
			if (materials != null)
			{
				Material[] array2 = materials;
				foreach (Material val2 in array2)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						Object.Destroy((Object)(object)val2);
					}
				}
			}
			meshes = null;
			materials = null;
			strips = null;
			Bolts = null;
			Rope = null;
			State = Phase.Dead;
			muzzle = (model = null);
		}

		private void OnDisable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Draw));
			Kill();
		}

		private void OnDestroy()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Draw));
			Kill();
		}
	}
	internal sealed class JakArcWorld : JakArcRope.IWorld
	{
		private struct TargetSnapshot
		{
			internal int Id;

			internal Bounds Bounds;
		}

		private readonly CharacterBody owner;

		private readonly List<TargetSnapshot> targets = new List<TargetSnapshot>(128);

		private RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[32];

		internal HurtBox Focus;

		private TeamMask Enemies => TeamMask.GetEnemyTeams(owner.teamComponent.teamIndex);

		public int Targets => targets.Count;

		internal JakArcWorld(CharacterBody owner)
		{
			this.owner = owner;
		}

		internal static JakArcRope.V ToV(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new JakArcRope.V(p.x, p.y, p.z);
		}

		internal static Vector3 ToVector(JakArcRope.V p)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(p.x, p.y, p.z);
		}

		public float Probe(JakArcRope.V start, JakArcRope.V end, float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ToVector(end - start);
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude == 0f)
			{
				return -1f;
			}
			Vector3 val2 = ToVector(start);
			Vector3 val3 = val / magnitude;
			LayerIndex world = LayerIndex.world;
			RaycastHit val4 = default(RaycastHit);
			if (!Physics.SphereCast(val2, radius, val3, ref val4, magnitude, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
			{
				return -1f;
			}
			return ((RaycastHit)(ref val4)).distance / magnitude;
		}

		internal void BeginUpdate()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			targets.Clear();
			TeamMask enemies = Enemies;
			ReadOnlyCollection<CharacterBody> readOnlyInstancesList = CharacterBody.readOnlyInstancesList;
			bool flag = JakWeaponTargets.Eligible(Focus, enemies);
			for (int i = 0; i < readOnlyInstancesList.Count; i++)
			{
				CharacterBody val = readOnlyInstancesList[i];
				HurtBox val2 = (Object.op_Implicit((Object)(object)val) ? val.mainHurtBox : null);
				if (Object.op_Implicit((Object)(object)val2) && flag && (Object)(object)Focus.healthComponent == (Object)(object)val2.healthComponent)
				{
					val2 = Focus;
				}
				if (JakWeaponTargets.Eligible(val2, enemies))
				{
					targets.Add(new TargetSnapshot
					{
						Id = ((Object)val2.healthComponent).GetInstanceID(),
						Bounds = val2.collider.bounds
					});
				}
			}
		}

		public int Target(int index, JakArcRope.V point, out JakArcRope.V centre, out float distance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			TargetSnapshot targetSnapshot = targets[index];
			centre = ToV(((Bounds)(ref targetSnapshot.Bounds)).center);
			distance = (ToV(((Bounds)(ref targetSnapshot.Bounds)).ClosestPoint(ToVector(point))) - point).Length;
			return targetSnapshot.Id;
		}

		public bool Visible(JakArcRope.V from, JakArcRope.V to)
		{
			//IL_0001: 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)
			return JakWeaponTargets.Visible(ToVector(from), ToVector(to));
		}

		internal HurtBox Sweep(JakArcRope.Span span, HashSet<int> victims, out Vector3 point)
		{
			//IL_0001: 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_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_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			point = default(Vector3);
			Vector3 val = ToVector(span.Start);
			Vector3 val2 = ToVector(span.End - span.Start);
			float num = ((Vector3)(ref val2)).magnitude;
			if (num == 0f)
			{
				return null;
			}
			Vector3 val3 = val2 / num;
			float num2 = num;
			LayerIndex val4 = LayerIndex.world;
			RaycastHit val5 = default(RaycastHit);
			if (Physics.SphereCast(val, 0.2f, val3, ref val5, num2, LayerMask.op_Implicit(((LayerIndex)(ref val4)).mask), (QueryTriggerInteraction)1))
			{
				num = ((RaycastHit)(ref val5)).distance;
			}
			int num4;
			while (true)
			{
				RaycastHit[] array = hits;
				float num3 = num;
				val4 = LayerIndex.entityPrecise;
				if ((num4 = Physics.SphereCastNonAlloc(val, 1f, val3, array, num3, LayerMask.op_Implicit(((LayerIndex)(ref val4)).mask), (QueryTriggerInteraction)2)) != hits.Length)
				{
					break;
				}
				hits = (RaycastHit[])(object)new RaycastHit[hits.Length * 2];
			}
			TeamMask enemies = Enemies;
			HurtBox val6;
			while (true)
			{
				val6 = null;
				int num5 = -1;
				for (int i = 0; i < num4; i++)
				{
					if (((RaycastHit)(ref hits[i])).distance < 0f || (num5 >= 0 && ((RaycastHit)(ref hits[i])).distance >= ((RaycastHit)(ref hits[num5])).distance))
					{
						continue;
					}
					Collider collider = ((RaycastHit)(ref hits[i])).collider;
					HurtBox val7 = (Object.op_Implicit((Object)(object)collider) ? ((Component)collider).GetComponent<HurtBox>() : null);
					if (JakWeaponTargets.Eligible(val7, enemies))
					{
						int instanceID = ((Object)val7.healthComponent).GetInstanceID();
						if (instanceID != span.StartId && !victims.Contains(instanceID))
						{
							num5 = i;
							val6 = val7;
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)val6))
				{
					point = default(Vector3);
					return null;
				}
				RaycastHit val8 = hits[num5];
				Vector3 val10;
				if (!(((RaycastHit)(ref val8)).distance > 0f))
				{
					Collider collider2 = ((RaycastHit)(ref val8)).collider;
					MeshCollider val9 = (MeshCollider)(object)((collider2 is MeshCollider) ? collider2 : null);
					if (val9 == null || val9.convex)
					{
						val10 = ((RaycastHit)(ref val8)).collider.ClosestPoint(val);
					}
					else
					{
						Bounds bounds = ((RaycastHit)(ref val8)).collider.bounds;
						val10 = ((Bounds)(ref bounds)).center;
					}
				}
				else
				{
					val10 = ((RaycastHit)(ref val8)).point;
				}
				point = val10;
				if (JakWeaponTargets.Visible(val, point))
				{
					break;
				}
				((RaycastHit)(ref hits[num5])).distance = -1f;
			}
			return val6;
		}

		internal Vector3 Direction(Vector3 fire, in JakShot shot)
		{
			//IL_0022: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001b: 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_0065: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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)
			Ray ray;
			Vector3 val;
			if (shot.Spinning)
			{
				ray = shot.Ray;
				val = ((Ray)(ref ray)).direction;
				return ((Vector3)(ref val)).normalized;
			}
			TeamMask enemies = Enemies;
			if (JakWeaponTargets.Eligible(Focus, enemies))
			{
				Bounds bounds = Focus.collider.bounds;
				val = ((Bounds)(ref bounds)).center - fire;
				return ((Vector3)(ref val)).normalized;
			}
			ray = shot.Ray;
			Vector3 point = ((Ray)(ref ray)).GetPoint(1000f);
			float num = 1000f;
			Ray ray2 = shot.Ray;
			LayerIndex val2 = LayerIndex.world;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(ray2, ref val3, 1000f, LayerMask.op_Implicit(((LayerIndex)(ref val2)).mask), (QueryTriggerInteraction)1))
			{
				point = ((RaycastHit)(ref val3)).point;
				num = ((RaycastHit)(ref val3)).distance;
			}
			int num3;
			while (true)
			{
				Ray ray3 = shot.Ray;
				RaycastHit[] array = hits;
				float num2 = num;
				val2 = LayerIndex.entityPrecise;
				if ((num3 = Physics.RaycastNonAlloc(ray3, array, num2, LayerMask.op_Implicit(((LayerIndex)(ref val2)).mask), (QueryTriggerInteraction)2)) != hits.Length)
				{
					break;
				}
				hits = (RaycastHit[])(object)new RaycastHit[hits.Length * 2];
			}
			for (int i = 0; i < num3; i++)
			{
				HurtBox box = (Object.op_Implicit((Object)(object)((RaycastHit)(ref hits[i])).collider) ? ((Component)((RaycastHit)(ref hits[i])).collider).GetComponent<HurtBox>() : null);
				if (((RaycastHit)(ref hits[i])).distance < num && JakWeaponTargets.Eligible(box, enemies))
				{
					point = ((RaycastHit)(ref hits[i])).point;
					num = ((RaycastHit)(ref hits[i])).distance;
				}
			}
			val = point - fire;
			return ((Vector3)(ref val)).normalized;
		}
	}
	internal static class JakAssets
	{
		public const string BundleName = "jaksurvivor";

		public static string PluginDirectory => Path.GetDirectoryName(typeof(Plugin).Assembly.Location);

		public static AssetBundle Bundle { get; private set; }

		internal static float ScatterRecovery { get; private set; }

		public static AssetBundleCreateRequest BeginLoad()
		{
			string text = Path.Combine(PluginDirectory, "jaksurvivor");
			if (!File.Exists(text))
			{
				throw new FileNotFoundException("Jak's AssetBundle is missing. Stage the plugin with scripts/Build-Unity.ps1.", text);
			}
			return AssetBundle.LoadFromFileAsync(text);
		}

		public static void EndLoad(AssetBundleCreateRequest request)
		{
			Bundle = request.assetBundle;
			if (!Object.op_Implicit((Object)(object)Bundle))
			{
				throw new InvalidDataException("Jak's AssetBundle could not be loaded.");
			}
			ScatterRecovery = JakAssets.Get<RuntimeAnimatorController>("animJak").animationClips.Single((AnimationClip c) => ((Object)c).name == "jakb-gun-red-fire-fast").length;
		}

		public static T Get<T>(string name) where T : Object
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			return Bundle.LoadAsset<T>(name) ?? throw new MissingReferenceException("Jak's AssetBundle has no " + typeof(T).Name + " named " + name + ".");
		}
	}
	internal sealed class JakAudio : MonoBehaviour
	{
		internal readonly struct Clip
		{
			public readonly float[] Samples;

			public readonly float Peak;

			public Clip(float[] samples)
			{
				Samples = samples;
				Peak = JakSoundLevels.Peak(samples);
			}
		}

		internal sealed class Voice
		{
			public NativeAudio.Voice Playback;

			public string Key;

			public GameObject Owner;

			public float Gain;

			public bool Menu;

			public bool HasPoint;

			public bool Fading;

			public Vector3 Point;

			public void SetPlaybackParameters(float pitchMod, float volume1024)
			{
				Playback.Rate = (float)Math.Pow(2.0, (double)pitchMod / 1536.0);
				Playback.Gain = Mathf.Max(0f, volume1024 / 1024f);
			}
		}

		internal static readonly string[] Keys = new string[39]
		{
			"blast-charge", "blast-swing", "blast-flight", "blast-hit", "blast-wall", "spin-kick", "blue-whoosh", "gun-spin-hit", "jump", "jump-double",
			"blaster", "scatter", "board-start", "board-loop", "board-jump", "board-q-jump", "board-bounce", "dark-enter", "dark-exit", "claws",
			"bomb-charge", "bomb-impact", "gun-draw", "gun-twirl", "arc-loop", "arc-spin", "blue-gun-whine", "wave-charge", "wave-shot", "roll-stn",
			"roll-drt", "roll-grs", "roll-san", "roll-wod", "roll-mtl", "roll-wtr", "roll-flip", "transform-zap", "stretched-zap"
		};

		private static readonly Dictionary<string, Clip> Clips = new Dictionary<string, Clip>();

		private static JakAudio instance;

		private readonly List<Voice> voices = new List<Voice>();

		private NativeAudio mixer;

		private BaseConVar masterVolume;

		private BaseConVar sfxVolume;

		private BaseConVar focusedOnly;

		private float volume = 1f;

		private float settingsAt;

		internal static bool IsLoop(string key)
		{
			switch (key)
			{
			default:
				return key == "wave-charge";
			case "blast-charge":
			case "blast-flight":
			case "board-loop":
			case "arc-loop":
			case "arc-spin":
			case "blue-gun-whine":
				return true;
			}
		}

		private void Awake()
		{
			instance = this;
		}

		public static void LoadClips()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if (Application.isBatchMode || (int)SystemInfo.graphicsDeviceType == 4)
			{
				return;
			}
			string[] keys = Keys;
			foreach (string text in keys)
			{
				if (!Clips.ContainsKey(text))
				{
					try
					{
						Clips.Add(text, new Clip(ReadClip(JakAssets.Bundle, text)));
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Could not load Jak sound " + text + ": " + ex.Message));
					}
				}
			}
			if (Clips.Count > 0 && Object.op_Implicit((Object)(object)instance) && instance.mixer == null)
			{
				try
				{
					instance.mixer = new NativeAudio();
				}
				catch (Exception ex2)
				{
					Clips.Clear();
					Plugin.Log.LogWarning((object)("Jak audio unavailable; using native fallback: " + ex2.Message));
				}
			}
			Plugin.Log.LogInfo((object)("Loaded " + Clips.Count + " original Jak 3 sound effects."));
		}

		internal static float[] ReadClip(AssetBundle bundle, string key)
		{
			TextAsset obj = bundle.LoadAsset<TextAsset>("jak3-sfx-" + key + ".bytes");
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidDataException("Missing raw PCM audio payload for " + key);
			}
			int channels;
			int sampleRate;
			float[] result = PcmWave.Decode(obj.bytes, out channels, out sampleRate);
			if (channels != 1 || sampleRate != 48000)
			{
				throw new InvalidDataException("Expected 48kHz mono PCM.");
			}
			return result;
		}

		internal static float Duration(string key)
		{
			if (!Clips.TryGetValue(key, out var value))
			{
				return 0f;
			}
			return (float)value.Samples.Length / 48000f;
		}

		public static Voice Play(string key, GameObject owner, string fallback = null, bool loop = false, float gain = 0.8f, bool menu = false, float pitchMod = 0f, float volume1024 = 1024f)
		{
			if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)instance) || instance.mixer == null || !Clips.TryGetValue(key, out var value))
			{
				if (Object.op_Implicit((Object)(object)owner) && !string.IsNullOrEmpty(fallback))
				{
					Util.PlaySound(fallback, owner);
				}
				return null;
			}
			instance.voices.RemoveAll((Voice v) => v.Playback.Stopped);
			if (loop)
			{
				foreach (Voice voice2 in instance.voices)
				{
					if ((Object)(object)voice2.Owner == (Object)(object)owner && voice2.Key == key && voice2.Playback.Loop)
					{
						voice2.SetPlaybackParameters(pitchMod, volume1024);
						return voice2;
					}
				}
			}
			float num = (menu ? gain : JakSoundLevels.GameplayGain(gain, value.Peak));
			Voice voice = new Voice
			{
				Key = key,
				Owner = owner,
				Gain = num,
				Menu = menu,
				Playback = instance.mixer.Play(value.Samples, loop, menu ? null : JakArcAudio.Create(key, num))
			};
			if (voice.Playback.Stopped)
			{
				return null;
			}
			voice.SetPlaybackParameters(pitchMod, volume1024);
			voice.Playback.Paused = Time.timeScale <= 0f && !menu;
			instance.voices.Add(voice);
			instance.Position(voice, instance.ListenerTransform());
			return voice;
		}

		public static Voice PlayAt(string key, Vector3 point, GameObject owner, float gain = 0.8f)
		{
			//IL_0023: 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)
			Voice voice = Play(key, owner, null, loop: false, gain);
			if (voice == null)
			{
				return null;
			}
			voice.HasPoint = true;
			voice.Point = point;
			instance.Position(voice, instance.ListenerTransform());
			return voice;
		}

		public static void Fade(Voice voice, float seconds)
		{
			//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)
			if (voice != null && !voice.Fading && !voice.Playback.Stopped)
			{
				if (!voice.HasPoint && Object.op_Implicit((Object)(object)voice.Owner))
				{
					voice.Point = voice.Owner.transform.position;
					voice.HasPoint = true;
				}
				voice.Fading = true;
				voice.Playback.FadeOut((int)(seconds * 48000f));
			}
		}

		public static void Stop(Voice voice)
		{
			if (voice != null)
			{
				voice.Playback.Stopped = true;
				if (Object.op_Implicit((Object)(object)instance))
				{
					instance.voices.Remove(voice);
				}
			}
		}

		private void Update()
		{
			if (mixer == null)
			{
				return;
			}
			if (mixer.Failure != null)
			{
				Plugin.Log.LogWarning((object)("Jak audio output stopped (" + mixer.Failure + "); using native fallback sounds."));
				Shutdown();
				return;
			}
			if (Time.unscaledTime >= settingsAt)
			{
				settingsAt = Time.unscaledTime + 0.2f;
				Console val = Console.instance;
				if (Object.op_Implicit((Object)(object)val))
				{
					masterVolume = masterVolume ?? val.FindConVar("volume_master");
					sfxVolume = sfxVolume ?? val.FindConVar("volume_sfx");
					focusedOnly = focusedOnly ?? val.FindConVar("audio_focused_only");
				}
				volume = Mathf.Clamp01(Read(masterVolume, 100f) / 100f) * Mathf.Clamp01(Read(sfxVolume, 100f) / 100f);
			}
			mixer.Paused = !Application.isFocused && Read(focusedOnly, 1f) != 0f;
			Transform listener = ListenerTransform();
			for (int num = voices.Count - 1; num >= 0; num--)
			{
				Voice voice = voices[num];
				if ((!voice.Fading && (!Object.op_Implicit((Object)(object)voice.Owner) || !voice.Owner.activeInHierarchy)) || voice.Playback.Stopped)
				{
					voice.Playback.Stopped = true;
					voices.RemoveAt(num);
				}
				else
				{
					voice.Playback.Paused = Time.timeScale <= 0f && !voice.Menu;
					Position(voice, listener);
				}
			}
		}

		private void Position(Voice voice, Transform listener)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0082: 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_00cc: 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)
			float left = 0f;
			float right = 0f;
			if (voice.Menu)
			{
				left = (right = volume * voice.Gain * Mathf.Sqrt(0.5f));
			}
			else if (Object.op_Implicit((Object)(object)listener) && (voice.HasPoint || Object.op_Implicit((Object)(object)voice.Owner)))
			{
				Vector3 val = (voice.HasPoint ? voice.Point : voice.Owner.transform.position) - listener.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				float num = ((magnitude >= 65f) ? 0f : Mathf.Min(1f, 8f / Mathf.Max(magnitude, 0.01f)));
				float num2 = Mathf.Clamp((magnitude > 0.01f) ? Vector3.Dot(listener.right, val / magnitude) : 0f, -1f, 1f);
				float num3 = volume * voice.Gain * num;
				left = num3 * Mathf.Sqrt((1f - num2) * 0.5f);
				right = num3 * Mathf.Sqrt((1f + num2) * 0.5f);
			}
			voice.Playback.Left = left;
			voice.Playback.Right = right;
		}

		private Transform ListenerTransform()
		{
			foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances) && ((Behaviour)readOnlyInstances).isActiveAndEnabled && readOnlyInstances.localUserViewer != null && Object.op_Implicit((Object)(object)readOnlyInstances.sceneCam) && ((Behaviour)readOnlyInstances.sceneCam).isActiveAndEnabled)
				{
					return ((Component)readOnlyInstances.sceneCam).transform;
				}
			}
			Camera main = Camera.main;
			if (!Object.op_Implicit((Object)(object)main))
			{
				return null;
			}
			return ((Component)main).transform;
		}

		private static float Read(BaseConVar convar, float fallback)
		{
			if (convar == null || !float.TryParse(convar.GetString(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return fallback;
			}
			return result;
		}

		private void Shutdown()
		{
			foreach (Voice voice in voices)
			{
				voice.Playback.Stopped = true;
			}
			voices.Clear();
			mixer?.Dispose();
			mixer = null;
		}

		private void OnDestroy()
		{
			Shutdown();
			Clips.Clear();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
	internal static class JakBlast
	{
		internal sealed class Stall
		{
			private readonly float[] history = new float[16]
			{
				999999f, 999999f, 999999f, 999999f, 999999f, 999999f, 999999f, 999999f, 999999f, 999999f,
				999999f, 999999f, 999999f, 999999f, 999999f, 999999f
			};

			private const float Seed = 999999f;

			private int next;

			internal bool Record(float distance, bool touchingWall)
			{
				history[next] = 0.0625f * distance;
				next = (next + 1) & 0xF;
				float num = 0f;
				float[] array = history;
				foreach (float num2 in array)
				{
					num += num2;
				}
				if (!touchingWall || !(num < 0.5f))
				{
					return num < 0.05f;
				}
				return true;
			}
		}

		internal const float SampleSeconds = 0.066666536f;

		internal const float LaunchTime = 0.46666574f;

		internal const float ReleaseTime = 0.7333319f;

		internal const float RecoveryTime = 0.59999883f;

		internal const float Speed = 60f;

		internal const float Lifetime = 4f;

		internal const float InitialRadius = 2f;

		internal const float MaxRadius = 6f;

		internal const float Growth = 6f;

		internal const float TrailStep = 1f / 60f;

		internal static float Radius(float age)
		{
			return Math.Min(6f, 2f + 6f * Math.Max(0f, age));
		}

		internal static float Flatten(float velocity, float dt)
		{
			return (float)Math.Sign(velocity) * Math.Max(0f, Math.Abs(velocity) - 20f * dt);
		}

		internal static float Lift(float height, float ground, float radius, float dt)
		{
			return Math.Min(Math.Max(0f, ground + radius * 0.5f - height), 10f * dt);
		}

		internal static float SegmentFraction(float px, float py, float pz, float dx, float dy, float dz)
		{
			float num = dx * dx + dy * dy + dz * dz;
			if (!(num <= 1E-08f))
			{
				return Math.Max(0f, Math.Min(1f, (px * dx + py * dy + pz * dz) / num));
			}
			return 0f;
		}

		internal static bool CrossesLaunch(float age, float rate)
		{
			return age * rate >= 0.46666574f;
		}

		internal static bool Slide(ref float vx, ref float vy, ref float vz, float nx, float ny, float nz)
		{
			float num = (float)Math.Sqrt(vx * vx + vy * vy + vz * vz);
			if (num <= 1E-08f)
			{
				return false;
			}
			float num2 = vx * nx + vy * ny + vz * nz;
			bool result = num2 / num < -0.3f;
			float num3 = vx - nx * 1.2f * num2;
			float num4 = vy - ny * 1.2f * num2;
			float num5 = vz - nz * 1.2f * num2;
			float num6 = (float)Math.Sqrt(num3 * num3 + num4 * num4 + num5 * num5);
			float num7 = Math.Min(0.4f, (num6 <= 1E-08f) ? 0f : (num4 / num6)) / 4096f;
			float num8 = num / (float)Math.Sqrt(vx * vx + num7 * num7 + vz * vz);
			if (float.IsInfinity(num8) || float.IsNaN(num8))
			{
				vx = (vz = 0f);
				vy = num;
				return result;
			}
			vx *= num8;
			vy = num7 * num8;
			vz *= num8;
			return result;
		}

		internal static bool Impacts(bool flagged, float height, float fireHeight, float speed)
		{
			if (flagged)
			{
				if (Math.Abs(height - fireHeight) < 1.5f)
				{
					return !(speed > 4f);
				}
				return true;
			}
			return false;
		}

		internal static float TrailFraction(float carried, float delta, int index)
		{
			if (!(delta <= 0f))
			{
				return Math.Max(0f, Math.Min(1f, ((float)(index + 1) * (1f / 60f) - carried) / delta));
			}
			return 1f;
		}
	}
	[DefaultExecutionOrder(10010)]
	internal sealed class JakBlastPresentation : MonoBehaviour
	{
		private JakBlastProjectile shot;

		private JakBlastAppearance style;

		private readonly JakEffectPlayer[] lobes = new JakEffectPlayer[2];

		private readonly uint[] lobeLeases = new uint[2];

		private readonly Mesh[] strips = (Mesh[])(object)new Mesh[6];

		private readonly Vector3[][] points = new Vector3[3][]
		{
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17]
		};

		private readonly Vector3[][] current = new Vector3[3][]
		{
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17]
		};

		private readonly Vector3[][] desired = new Vector3[3][]
		{
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17],
			(Vector3[])(object)new Vector3[17]
		};

		private readonly Vector3[] vertices = (Vector3[])(object)new Vector3[34];

		private readonly Vector2[] uv = (Vector2[])(object)new Vector2[34];

		private readonly Color32[] colors = (Color32[])(object)new Color32[34];

		private readonly int[] triangles = new int[96];

		private JakEffectPlayer trail;

		private JakAudio.Voice loop;

		private float retired = -1f;

		private float nextBolt;

		private float generated;

		private float emission;

		private float elapsed;

		private bool sampled;

		private bool trailed;

		private Vector3 trailFrom;

		internal void Begin(JakBlastProjectile projectile)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			shot = projectile;
			style = JakEffects.Assets.blast;
			((Component)this).transform.position = ((Component)projectile).transform.position;
			for (int i = 0; i < lobes.Length; i++)
			{
				lobes[i] = JakEffectPlayer.Spawn("blast-core", ((Component)this).transform);
				lobeLeases[i] = lobes[i].LeaseId;
				lobes[i].Driven = true;
			}
			trail = JakEffectPlayer.CreateLauncher(((Component)this).gameObject.layer);
			loop = JakAudio.Play("blast-flight", ((Component)this).gameObject, null, loop: true);
			for (int j = 0; j < 16; j++)
			{
				int num = j * 6;
				int num2 = j * 2;
				triangles[num] = num2;
				triangles[num + 1] = num2 + 1;
				triangles[num + 2] = num2 + 2;
				triangles[num + 3] = num2 + 1;
				triangles[num + 4] = num2 + 3;
				triangles[num + 5] = num2 + 2;
			}
			for (int k = 0; k < strips.Length; k++)
			{
				strips[k] = new Mesh
				{
					name = "DarkBlastNativeBolt" + k
				};
				strips[k].MarkDynamic();
			}
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Draw));
		}

		private void Midpoint(Vector3[] offsets, int first, int last, float scale)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (last - first > 1)
			{
				int num = (first + last) / 2;
				offsets[num] = (offsets[first] + offsets[last]) * 0.5f + Random.insideUnitSphere * scale;
				Midpoint(offsets, first, num, scale * style.reduction);
				Midpoint(offsets, num, last, scale * style.reduction);
			}
		}

		private void LateUpdate()
		{
			//IL_009e: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00fa: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: 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_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			if (retired >= 0f)
			{
				if (Time.time - retired >= style.fade)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)shot))
			{
				Retire();
				return;
			}
			for (int i = 0; i < lobes.Length; i++)
			{
				if (!Object.op_Implicit((Object)(object)lobes[i]) || !lobes[i].IsLease(lobeLeases[i]))
				{
					Retire();
					return;
				}
			}
			((Component)this).transform.position = ((Component)shot).transform.position;
			float num = FixedTimeStamp.now.t * 8.377581f;
			Vector3 val = new Vector3(Mathf.Cos(num), 0f, 0f - Mathf.Sin(num)) * (0.75f * shot.Radius);
			((Component)lobes[0]).transform.position = ((Component)this).transform.position + val;
			((Component)lobes[1]).transform.position = ((Component)this).transform.position - val;
			float num2 = elapsed;
			elapsed += Time.deltaTime;
			if (!sampled || elapsed >= nextBolt)
			{
				generated = num2;
				nextBolt = elapsed + Random.Range(style.regenerateMin, style.regenerateMax);
				for (int j = 0; j < 3; j++)
				{
					Array.Copy(current[j], desired[j], 17);
					desired[j][0] = Random.insideUnitSphere * style.endpointOffset;
					desired[j][15] = Random.insideUnitSphere * style.endpointOffset;
					Midpoint(desired[j], 0, 15, style.innerOffset);
					desired[j][16] = Vector3.zero;
				}
			}
			float num3 = Mathf.Clamp01((num2 - generated) / style.travel);
			float num4 = Mathf.Clamp01((elapsed - generated) / style.travel);
			float num5 = ((num3 < 1f) ? ((num4 - num3) / (1f - num3)) : 0f);
			for (int k = 0; k < 3; k++)
			{
				for (int l = 0; l < 17; l++)
				{
					current[k][l] = ((!sampled) ? desired[k][l] : Vector3.Lerp(current[k][l], desired[k][l], num5));
					points[k][l] = Vector3.Lerp(((Component)lobes[0]).transform.position, ((Component)lobes[1]).transform.position, (float)Mathf.Min(l, 15) / 15f) + current[k][l];
				}
			}
			sampled = true;
			Vector3 position = ((Component)this).transform.position;
			Vector3 val2 = position;
			Vector3 down = Vector3.down;
			LayerIndex world = LayerIndex.world;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2, down, ref val3, 30f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
			{
				position.y = ((RaycastHit)(ref val3)).point.y + 0.4f;
			}
			Vector3 val4 = Vector3.ProjectOnPlane(((Component)shot).transform.forward, Vector3.up);
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			Quaternion rotation = ((((Vector3)(ref normalized)).sqrMagnitude > 0f) ? Quaternion.LookRotation(normalized) : Quaternion.identity);
			if (!trailed)
			{
				trailFrom = position;
				trailed = true;
			}
			float carried = emission;
			emission += Time.deltaTime;
			int num6 = 0;
			while (emission >= 1f / 60f)
			{
				trail.Launch(628, Vector3.Lerp(trailFrom, position, JakBlast.TrailFraction(carried, Time.deltaTime, num6)), rotation);
				num6++;
				emission -= 1f / 60f;
			}
			trailFrom = position;
		}

		private void Draw(Camera camera)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unkno