Decompiled source of UltraDodge v1.3.0

UltraDodge.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using UltraDodge.Detection;
using UltraDodge.Effects;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("KiyroPrower")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Rewards dashing away from enemy attacks with slow motion, a shockwave and a short screen tint.")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+f6b5b961a7e286fd70eed1f197ae0e02bb0a92f1")]
[assembly: AssemblyProduct("UltraDodge")]
[assembly: AssemblyTitle("UltraDodge")]
[assembly: AssemblyVersion("1.3.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UltraDodge
{
	internal sealed class DodgeRuntime : MonoBehaviour
	{
		private static DodgeRuntime instance;

		private static float lastHurtTime = float.NegativeInfinity;

		private const int InvinciblePlayerLayer = 15;

		private const float SlowMotionRecoveredScale = 0.95f;

		private const float SlowMotionRecoveryTimeout = 3f;

		private const float InsigniaOuterFactor = 2.5f;

		private const float FullStamina = 300f;

		private readonly ColorDrain drain = new ColorDrain();

		private readonly StaminaHighlight staminaHighlight = new StaminaHighlight();

		private Coroutine slowMotion;

		private bool slowMotionActive;

		private float highlightUntil;

		private float staminaBonusUntil;

		private float nextTriggerTime;

		private float windowEndsAt;

		private float dodgeTime = float.NegativeInfinity;

		private Vector3 dodgeOrigin;

		private ThreatMask windowMask;

		private string windowTrigger;

		private bool windowOpen;

		internal static bool IsAlive => (Object)(object)instance != (Object)null;

		internal static void Create()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)instance != (Object)null))
			{
				GameObject val = new GameObject("UltraDodge Runtime");
				Object.DontDestroyOnLoad((Object)val);
				instance = val.AddComponent<DodgeRuntime>();
			}
		}

		internal static void Shutdown()
		{
			ThreatTracker.Clear();
			DistortionWave.Reset();
			if (!((Object)(object)instance == (Object)null))
			{
				instance.drain.Stop();
				instance.staminaHighlight.Set(wanted: false);
				Object.Destroy((Object)(object)((Component)instance).gameObject);
				instance = null;
			}
		}

		internal static void NotifyDash(NewMovement movement)
		{
			Revive();
			if ((Object)(object)instance != (Object)null)
			{
				instance.TryDodge(movement, ThreatMask.All, "dash");
			}
		}

		internal static void NotifyJump(NewMovement movement)
		{
			if (UltraDodgeConfig.JumpDodge)
			{
				Revive();
				if ((Object)(object)instance != (Object)null)
				{
					instance.TryDodge(movement, ThreatMask.Shockwave, "jump");
				}
			}
		}

		internal static void NotifySlam(NewMovement movement)
		{
			if (UltraDodgeConfig.SlamDodge)
			{
				Revive();
				if ((Object)(object)instance != (Object)null)
				{
					instance.TryDodge(movement, ThreatMask.All, "slam");
				}
			}
		}

		internal static void ReportBlast(Vector3 center, float radius, Object source)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance != (Object)null)
			{
				instance.HandleBlast(center, radius, source);
			}
		}

		internal static void ReportBeam(Vector3 origin, Vector3 direction, Object source)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance != (Object)null)
			{
				instance.HandleBeam(origin, direction, source);
			}
		}

		internal static void ReportInsigniaFired(Vector3 center, float radius, Object source)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance != (Object)null)
			{
				instance.HandleInsigniaFired(center, radius, source);
			}
		}

		internal static void NotifyPlayerHurt()
		{
			lastHurtTime = Time.unscaledTime;
		}

		private static void Revive()
		{
			if (!((Object)(object)instance != (Object)null))
			{
				Create();
				Plugin.Log.LogWarning((object)"Runtime object was missing and has been recreated.");
			}
		}

		private void Awake()
		{
			SceneManager.sceneUnloaded += OnSceneUnloaded;
		}

		private void OnDestroy()
		{
			SceneManager.sceneUnloaded -= OnSceneUnloaded;
		}

		private void OnSceneUnloaded(Scene scene)
		{
			ThreatTracker.Clear();
			DistortionWave.Reset();
			drain.Stop();
			staminaHighlight.Set(wanted: false);
			slowMotionActive = false;
			highlightUntil = 0f;
			windowOpen = false;
		}

		private void Update()
		{
			ThreatTracker.SampleThreats(Time.deltaTime);
			drain.Tick(Time.unscaledDeltaTime);
			TickStaminaBonus();
			if (windowOpen)
			{
				TickDodgeWindow();
			}
		}

		private void TickStaminaBonus()
		{
			NewMovement val = default(NewMovement);
			if (!(Time.unscaledTime >= staminaBonusUntil) && MonoSingleton<NewMovement>.TryGetInstance(ref val) && !val.dead && !val.sliding && !val.slowMode && !(val.boostCharge >= 300f))
			{
				val.boostCharge = Mathf.Min(300f, val.boostCharge + UltraDodgeConfig.StaminaBonusRate * Time.deltaTime);
			}
		}

		private void LateUpdate()
		{
			bool wanted = UltraDodgeConfig.StaminaHighlight && (slowMotionActive || Time.unscaledTime < highlightUntil);
			staminaHighlight.Set(wanted);
		}

		private void TryDodge(NewMovement movement, ThreatMask allowed, string trigger)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool debugLogging = UltraDodgeConfig.DebugLogging;
				if (!UltraDodgeConfig.Enabled || (Object)(object)movement == (Object)null || movement.dead)
				{
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)$"[dodge] {trigger} ignored | enabled={UltraDodgeConfig.Enabled} dead={(Object)(object)movement != (Object)null && movement.dead}");
					}
					return;
				}
				if (Time.unscaledTime < nextTriggerTime)
				{
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)$"[dodge] {trigger} ignored, cooldown for another {nextTriggerTime - Time.unscaledTime:0.00}s");
					}
					return;
				}
				DodgeQuery query = BuildQuery(movement, allowed);
				dodgeTime = Time.unscaledTime;
				dodgeOrigin = query.PlayerCenter;
				query.Origin = dodgeOrigin;
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] {trigger} | tracked projectiles={ThreatTracker.ProjectileCount} swings={ThreatTracker.SwingCount} shockwaves={ThreatTracker.ShockwaveCount} explosives={ThreatTracker.ExplosiveCount} insignias={ThreatTracker.InsigniaCount} beams={ThreatTracker.BeamCount} blades={ThreatTracker.BladeCount}");
				}
				if (ThreatTracker.TryFindIncoming(in query, out var threat))
				{
					windowOpen = false;
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)$"[dodge] inbound {threat.Kind} '{threat.SourceName}' would land in {threat.TimeToImpact:0.000}s");
					}
					Reward(movement, threat);
					return;
				}
				windowOpen = true;
				windowMask = allowed;
				windowTrigger = trigger;
				float num = Mathf.Max(UltraDodgeConfig.DodgeWindow, UltraDodgeConfig.TelegraphGrace);
				windowEndsAt = dodgeTime + num;
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] nothing inbound, watching for a near miss for {num:0.00}s");
					ThreatTracker.LogCandidates(in query);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Dodge attempt (" + trigger + ") failed: " + ex));
			}
		}

		private void TickDodgeWindow()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool debugLogging = UltraDodgeConfig.DebugLogging;
				if (Time.unscaledTime > windowEndsAt)
				{
					windowOpen = false;
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)("[dodge] " + windowTrigger + " window expired without a near miss"));
					}
					return;
				}
				if (UltraDodgeConfig.RequireCleanDodge && lastHurtTime >= dodgeTime)
				{
					windowOpen = false;
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)("[dodge] " + windowTrigger + " window cancelled, damage was taken"));
					}
					return;
				}
				NewMovement val = default(NewMovement);
				if (!MonoSingleton<NewMovement>.TryGetInstance(ref val) || val.dead)
				{
					windowOpen = false;
					return;
				}
				DodgeQuery query = BuildQuery(val, windowMask);
				query.Origin = dodgeOrigin;
				if (ThreatTracker.TryFindNearMiss(in query, out var threat) && (threat.Kind != ThreatKind.Shockwave || val.boost || !((Object)(object)val.gc != (Object)null) || !val.gc.onGround))
				{
					windowOpen = false;
					if (debugLogging)
					{
						Plugin.Log.LogInfo((object)$"[dodge] near miss {threat.Kind} '{threat.SourceName}' passed {threat.Distance:0.0} units away");
					}
					Reward(val, threat);
				}
			}
			catch (Exception ex)
			{
				windowOpen = false;
				Plugin.Log.LogError((object)("Dodge window handling failed: " + ex));
			}
		}

		private void HandleBlast(Vector3 center, float radius, Object source)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (UltraDodgeConfig.ExplosiveDodge && TryGetGracePlayer(ThreatMask.Blast, out var movement))
			{
				RewardInstant(movement, ThreatKind.Blast, Vector3.Distance(center, dodgeOrigin), Vector3.Distance(center, PlayerCenter(movement)), radius, source);
			}
		}

		private void HandleBeam(Vector3 origin, Vector3 direction, Object source)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (UltraDodgeConfig.BeamDodge && TryGetGracePlayer(ThreatMask.Beam, out var movement))
			{
				Vector3 closest;
				float originDistance = ThreatTracker.DistanceToRay(origin, direction, dodgeOrigin, out closest);
				if (ThreatTracker.IsInView(BuildQuery(movement, windowMask), closest))
				{
					RewardInstant(movement, ThreatKind.Beam, originDistance, ThreatTracker.DistanceToRay(origin, direction, PlayerCenter(movement), out var _), UltraDodgeConfig.BeamRadius, source);
				}
			}
		}

		private void HandleInsigniaFired(Vector3 center, float radius, Object source)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!UltraDodgeConfig.InsigniaDodge || !TryGetGracePlayer(ThreatMask.Insignia, out var movement))
			{
				return;
			}
			float num = HorizontalDistance(center, PlayerCenter(movement));
			if (num <= radius)
			{
				return;
			}
			float num2 = HorizontalDistance(center, dodgeOrigin);
			if (num2 <= radius || num <= radius * 2.5f)
			{
				ThreatInfo threat = new ThreatInfo
				{
					Kind = ThreatKind.Insignia,
					Distance = num2,
					Source = source
				};
				if (UltraDodgeConfig.DebugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] insignia '{threat.SourceName}' fired, dodge origin {num2:0.0} from it, player now {num:0.0} away (radius {radius:0.0})");
				}
				Reward(movement, threat);
			}
		}

		private void RewardInstant(NewMovement movement, ThreatKind kind, float originDistance, float currentDistance, float radius, Object source)
		{
			if (!(originDistance > radius) && !(currentDistance <= radius))
			{
				ThreatInfo threat = new ThreatInfo
				{
					Kind = kind,
					Distance = originDistance,
					Source = source
				};
				if (UltraDodgeConfig.DebugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] {kind} '{threat.SourceName}' covered the {windowTrigger} origin at {originDistance:0.0} units, player now {currentDistance:0.0} away");
				}
				Reward(movement, threat);
			}
		}

		private bool TryGetGracePlayer(ThreatMask required, out NewMovement movement)
		{
			movement = null;
			if (Time.unscaledTime - dodgeTime > UltraDodgeConfig.TelegraphGrace)
			{
				return false;
			}
			if ((windowMask & required) == 0 || Time.unscaledTime < nextTriggerTime)
			{
				return false;
			}
			if (UltraDodgeConfig.RequireCleanDodge && lastHurtTime >= dodgeTime)
			{
				return false;
			}
			if (MonoSingleton<NewMovement>.TryGetInstance(ref movement))
			{
				return !movement.dead;
			}
			return false;
		}

		private static float HorizontalDistance(Vector3 a, Vector3 b)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(a.x - b.x, a.z - b.z);
			return ((Vector2)(ref val)).magnitude;
		}

		private void Reward(NewMovement movement, ThreatInfo threat)
		{
			nextTriggerTime = Time.unscaledTime + UltraDodgeConfig.Cooldown;
			bool debugLogging = UltraDodgeConfig.DebugLogging;
			if (UltraDodgeConfig.InvincibilityEnabled)
			{
				float invincibilityDuration = UltraDodgeConfig.InvincibilityDuration;
				movement.hurtInvincibility = Mathf.Max(movement.hurtInvincibility, invincibilityDuration);
				((Component)movement).gameObject.layer = 15;
				highlightUntil = Time.unscaledTime + invincibilityDuration;
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] invincible for {invincibilityDuration:0.00}s");
				}
			}
			if (UltraDodgeConfig.StaminaRewardEnabled)
			{
				staminaBonusUntil = Time.unscaledTime + UltraDodgeConfig.StaminaBonusDuration;
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] dash bar charging {UltraDodgeConfig.StaminaBonusRate:0} faster per second for {UltraDodgeConfig.StaminaBonusDuration:0.00}s");
				}
			}
			if (UltraDodgeConfig.SlowMotionEnabled)
			{
				float slowMotionScale = UltraDodgeConfig.SlowMotionScale;
				float slowMotionHold = UltraDodgeConfig.SlowMotionHold;
				if (slowMotion != null)
				{
					((MonoBehaviour)this).StopCoroutine(slowMotion);
				}
				slowMotion = ((MonoBehaviour)this).StartCoroutine(HoldSlowMotion(slowMotionScale, slowMotionHold));
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)$"[dodge] slow motion {slowMotionScale:0.00} held for {slowMotionHold:0.00}s");
				}
			}
			if (UltraDodgeConfig.WaveEnabled)
			{
				bool flag = DistortionWave.TrySpawn(movement);
				if (debugLogging)
				{
					Plugin.Log.LogInfo((object)(flag ? "[dodge] shockwave spawned" : "[dodge] shockwave prefab unavailable"));
				}
			}
			if (UltraDodgeConfig.ColorDrainEnabled)
			{
				drain.Play(UltraDodgeConfig.DrainStrength, UltraDodgeConfig.DrainFadeIn, UltraDodgeConfig.DrainHold, UltraDodgeConfig.DrainFadeOut);
			}
			if (debugLogging)
			{
				Plugin.Log.LogInfo((object)$"[dodge] rewarded dodge of {threat.Kind} '{threat.SourceName}'");
			}
		}

		private IEnumerator HoldSlowMotion(float scale, float holdSeconds)
		{
			slowMotionActive = true;
			float releaseAt = Time.unscaledTime + holdSeconds;
			TimeController val = default(TimeController);
			while (MonoSingleton<TimeController>.TryGetInstance(ref val))
			{
				val.SlowDown(scale);
				yield return null;
				if (!(Time.unscaledTime < releaseAt))
				{
					break;
				}
			}
			float giveUpAt = Time.unscaledTime + 3f;
			while (Time.timeScale < 0.95f && Time.unscaledTime < giveUpAt)
			{
				yield return null;
			}
			slowMotionActive = false;
			slowMotion = null;
		}

		private static DodgeQuery BuildQuery(NewMovement movement, ThreatMask allowed)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			DodgeQuery result = default(DodgeQuery);
			result.Allowed = allowed;
			result.PlayerCenter = PlayerCenter(movement);
			result.Origin = result.PlayerCenter;
			Camera val = (((Object)(object)movement.cc != (Object)null) ? movement.cc.cam : Camera.main);
			if ((Object)(object)val != (Object)null)
			{
				Transform transform = ((Component)val).transform;
				result.EyePosition = transform.position;
				result.EyeForward = transform.forward;
			}
			else
			{
				result.EyePosition = result.PlayerCenter;
				result.EyeForward = ((Component)movement).transform.forward;
			}
			return result;
		}

		private static Vector3 PlayerCenter(NewMovement movement)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			CapsuleCollider playerCollider = movement.playerCollider;
			if (!((Object)(object)playerCollider != (Object)null))
			{
				return ((Component)movement).transform.position;
			}
			Bounds bounds = ((Collider)playerCollider).bounds;
			return ((Bounds)(ref bounds)).center;
		}
	}
	[BepInPlugin("ultradodge.kiyroprower.ultrakill", "UltraDodge", "1.3.0")]
	[BepInProcess("ULTRAKILL.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "ultradodge.kiyroprower.ultrakill";

		public const string PluginConfiguratorGuid = "com.eternalUnion.pluginConfigurator";

		internal static ManualLogSource Log;

		private Harmony harmony;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			UltraDodgeConfig.Initialize(((BaseUnityPlugin)this).Logger);
			harmony = new Harmony("ultradodge.kiyroprower.ultrakill");
			harmony.PatchAll(typeof(Plugin).Assembly);
			DodgeRuntime.Create();
			SceneManager.sceneLoaded += OnSceneLoaded;
			Log.LogInfo((object)"UltraDodge loaded (ultradodge.kiyroprower.ultrakill).");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			DodgeRuntime.Shutdown();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			DodgeRuntime.Create();
		}
	}
	internal static class UltraDodgeConfig
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static PostBoolValueChangeEvent <>9__151_0;

			internal void <CreateMenu>b__151_0(bool _)
			{
				UpdateEnabledInteractable();
			}
		}

		public const float DefaultDodgeWindow = 0.25f;

		public const float DefaultCooldown = 1f;

		public const float DefaultProjectileHitRadius = 3.5f;

		public const float DefaultMeleeReach = 3.5f;

		public const float DefaultShockwaveReach = 4f;

		public const float DefaultNearMissDistance = 5f;

		public const float DefaultMinClosingSpeed = 2f;

		public const float DefaultLookAngle = 90f;

		public const float DefaultBlastRadius = 6f;

		public const float DefaultBeamRadius = 3f;

		public const float DefaultContinuousBeamMargin = 1.5f;

		public const float DefaultTelegraphGrace = 1f;

		public const float DefaultSlowMotionScale = 0.25f;

		public const float DefaultSlowMotionHold = 0.35f;

		public const float DefaultWaveSize = 0.6f;

		public const float DefaultWaveSpeed = 1.25f;

		public const float DefaultInvincibilityDuration = 0.25f;

		public const float DefaultStaminaBonusRate = 70f;

		public const float DefaultStaminaBonusDuration = 1.5f;

		public const float DefaultDrainStrength = 1f;

		public const float DefaultDrainFadeIn = 0.05f;

		public const float DefaultDrainHold = 0.25f;

		public const float DefaultDrainFadeOut = 0.5f;

		public const float DefaultKeepColorRange = 0.22f;

		private static PluginConfigurator _configurator;

		private static ManualLogSource _log;

		private static BoolField _enabledField;

		private static BoolField _debugLoggingField;

		private static BoolField _cleanDodgeField;

		private static BoolField _jumpDodgeField;

		private static BoolField _slamDodgeField;

		private static BoolField _explosiveDodgeField;

		private static BoolField _beamDodgeField;

		private static BoolField _continuousBeamDodgeField;

		private static BoolField _insigniaDodgeField;

		private static BoolField _requireLookingAtField;

		private static FloatSliderField _blastRadiusField;

		private static FloatSliderField _beamRadiusField;

		private static FloatSliderField _continuousBeamMarginField;

		private static FloatSliderField _telegraphGraceField;

		private static FloatSliderField _dodgeWindowField;

		private static FloatSliderField _cooldownField;

		private static FloatSliderField _projectileRadiusField;

		private static FloatSliderField _meleeReachField;

		private static FloatSliderField _shockwaveReachField;

		private static FloatSliderField _nearMissField;

		private static FloatSliderField _minClosingSpeedField;

		private static FloatSliderField _lookAngleField;

		private static BoolField _slowMotionField;

		private static FloatSliderField _slowMotionScaleField;

		private static FloatSliderField _slowMotionHoldField;

		private static BoolField _waveField;

		private static FloatSliderField _waveSizeField;

		private static FloatSliderField _waveSpeedField;

		private static BoolField _invincibilityField;

		private static FloatSliderField _invincibilityDurationField;

		private static BoolField _staminaHighlightField;

		private static BoolField _staminaRewardField;

		private static FloatSliderField _staminaBonusRateField;

		private static FloatSliderField _staminaBonusDurationField;

		private static BoolField _drainField;

		private static FloatSliderField _drainStrengthField;

		private static FloatSliderField _drainFadeInField;

		private static FloatSliderField _drainHoldField;

		private static FloatSliderField _drainFadeOutField;

		private static BoolField _keepBarColorField;

		private static FloatSliderField _keepColorRangeField;

		private static readonly List<ConfigField> GreyableFields = new List<ConfigField>();

		private static readonly Color TitleColor = new Color(1f, 0.62f, 0.16f);

		private static readonly Color EnabledColor = new Color(0.56f, 0.86f, 0.56f);

		private static readonly Color SlowMotionColor = new Color(0.45f, 0.8f, 1f);

		private static readonly Color WaveColor = new Color(0.75f, 0.65f, 1f);

		private static readonly Color InvincibilityColor = new Color(1f, 0.85f, 0.35f);

		private static readonly Color StaminaColor = new Color(0.55f, 0.95f, 0.75f);

		private static readonly Color DrainColor = new Color(0.8f, 0.8f, 0.8f);

		public static bool Enabled
		{
			get
			{
				if (_enabledField != null)
				{
					return _enabledField.value;
				}
				return true;
			}
		}

		public static bool DebugLogging
		{
			get
			{
				if (_debugLoggingField != null)
				{
					return _debugLoggingField.value;
				}
				return false;
			}
		}

		public static bool RequireCleanDodge
		{
			get
			{
				if (_cleanDodgeField != null)
				{
					return _cleanDodgeField.value;
				}
				return true;
			}
		}

		public static bool JumpDodge
		{
			get
			{
				if (_jumpDodgeField != null)
				{
					return _jumpDodgeField.value;
				}
				return true;
			}
		}

		public static bool SlamDodge
		{
			get
			{
				if (_slamDodgeField != null)
				{
					return _slamDodgeField.value;
				}
				return true;
			}
		}

		public static bool ExplosiveDodge
		{
			get
			{
				if (_explosiveDodgeField != null)
				{
					return _explosiveDodgeField.value;
				}
				return true;
			}
		}

		public static bool BeamDodge
		{
			get
			{
				if (_beamDodgeField != null)
				{
					return _beamDodgeField.value;
				}
				return true;
			}
		}

		public static bool ContinuousBeamDodge
		{
			get
			{
				if (_continuousBeamDodgeField != null)
				{
					return _continuousBeamDodgeField.value;
				}
				return true;
			}
		}

		public static bool InsigniaDodge
		{
			get
			{
				if (_insigniaDodgeField != null)
				{
					return _insigniaDodgeField.value;
				}
				return true;
			}
		}

		public static float BlastRadius => Value(_blastRadiusField, 6f, 0.5f);

		public static float BeamRadius => Value(_beamRadiusField, 3f, 0.5f);

		public static float ContinuousBeamMargin => Value(_continuousBeamMarginField, 1.5f, 0f);

		public static float TelegraphGrace => Value(_telegraphGraceField, 1f, 0f);

		public static bool RequireLookingAt
		{
			get
			{
				if (_requireLookingAtField != null)
				{
					return _requireLookingAtField.value;
				}
				return true;
			}
		}

		public static float LookAngle => Value(_lookAngleField, 90f, 5f);

		public static float ShockwaveReach => Value(_shockwaveReachField, 4f, 0.5f);

		public static float DodgeWindow => Value(_dodgeWindowField, 0.25f, 0.05f);

		public static float Cooldown => Value(_cooldownField, 1f, 0f);

		public static float ProjectileHitRadius => Value(_projectileRadiusField, 3.5f, 0.5f);

		public static float MeleeReach => Value(_meleeReachField, 3.5f, 0.5f);

		public static float NearMissDistance => Value(_nearMissField, 5f, 1f);

		public static float MinClosingSpeed => Value(_minClosingSpeedField, 2f, 0f);

		public static bool SlowMotionEnabled
		{
			get
			{
				if (_slowMotionField != null)
				{
					return _slowMotionField.value;
				}
				return true;
			}
		}

		public static float SlowMotionScale => Value(_slowMotionScaleField, 0.25f, 0.01f);

		public static float SlowMotionHold => Value(_slowMotionHoldField, 0.35f, 0f);

		public static bool WaveEnabled
		{
			get
			{
				if (_waveField != null)
				{
					return _waveField.value;
				}
				return true;
			}
		}

		public static float WaveSizeMultiplier => Value(_waveSizeField, 0.6f, 0.1f);

		public static float WaveSpeedMultiplier => Value(_waveSpeedField, 1.25f, 0.1f);

		public static bool InvincibilityEnabled
		{
			get
			{
				if (_invincibilityField != null)
				{
					return _invincibilityField.value;
				}
				return true;
			}
		}

		public static float InvincibilityDuration => Value(_invincibilityDurationField, 0.25f, 0f);

		public static bool StaminaHighlight
		{
			get
			{
				if (_staminaHighlightField != null)
				{
					return _staminaHighlightField.value;
				}
				return true;
			}
		}

		public static bool StaminaRewardEnabled
		{
			get
			{
				if (_staminaRewardField != null)
				{
					return _staminaRewardField.value;
				}
				return true;
			}
		}

		public static float StaminaBonusRate => Value(_staminaBonusRateField, 70f, 0f);

		public static float StaminaBonusDuration => Value(_staminaBonusDurationField, 1.5f, 0f);

		public static bool ColorDrainEnabled
		{
			get
			{
				if (_drainField != null)
				{
					return _drainField.value;
				}
				return true;
			}
		}

		public static float DrainStrength => Value(_drainStrengthField, 1f, 0f);

		public static float DrainFadeIn => Value(_drainFadeInField, 0.05f, 0f);

		public static float DrainHold => Value(_drainHoldField, 0.25f, 0f);

		public static float DrainFadeOut => Value(_drainFadeOutField, 0.5f, 0f);

		public static bool KeepBarColor
		{
			get
			{
				if (_keepBarColorField != null)
				{
					return _keepBarColorField.value;
				}
				return true;
			}
		}

		public static float KeepColorRange => Value(_keepColorRangeField, 0.22f, 0.02f);

		public static void Initialize(ManualLogSource log)
		{
			_log = log;
			try
			{
				CreateMenu();
				_log.LogInfo((object)"Config menu initialized.");
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("PluginConfigurator menu could not be initialized: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private static void CreateMenu()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_006c: 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_01f1: Expected O, but got Unknown
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Expected O, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Expected O, but got Unknown
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Expected O, but got Unknown
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Expected O, but got Unknown
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Expected O, but got Unknown
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Expected O, but got Unknown
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Expected O, but got Unknown
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Expected O, but got Unknown
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Expected O, but got Unknown
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Expected O, but got Unknown
			//IL_07e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07eb: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			if (_configurator != null)
			{
				return;
			}
			_configurator = PluginConfigurator.Create("UltraDodge", "ultradodge.kiyroprower.ultrakill");
			ConfigPanel rootPanel = _configurator.rootPanel;
			_enabledField = new BoolField(rootPanel, "Enabled", "ultradodge.enabled", true, true);
			BoolField enabledField = _enabledField;
			object obj = <>c.<>9__151_0;
			if (obj == null)
			{
				PostBoolValueChangeEvent val = delegate
				{
					UpdateEnabledInteractable();
				};
				<>c.<>9__151_0 = val;
				obj = (object)val;
			}
			enabledField.postValueChangeEvent += (PostBoolValueChangeEvent)obj;
			AddDescription(rootPanel, "Dash away from an attack and time slows down for a moment.", EnabledColor);
			AddTitle(rootPanel, "Detection");
			_dodgeWindowField = Slider(rootPanel, "Dodge Window", "ultradodge.window", 0.05f, 3f, 0.25f, 2);
			AddDescription(rootPanel, "How long before an attack lands a dash or jump still counts as a dodge.");
			_cooldownField = Slider(rootPanel, "Cooldown", "ultradodge.cooldown", 0f, 5f, 1f, 2);
			AddDescription(rootPanel, "Minimum real time between two rewarded dodges.");
			_projectileRadiusField = Slider(rootPanel, "Projectile Hit Radius", "ultradodge.projectileRadius", 0.5f, 10f, 3.5f, 1);
			AddDescription(rootPanel, "How close a shot has to pass to count as aimed at you. Larger values trigger dodges more often.");
			_meleeReachField = Slider(rootPanel, "Melee Reach", "ultradodge.meleeReach", 0.5f, 12f, 3.5f, 1);
			AddDescription(rootPanel, "Distance from an enemy's active melee hitbox that counts as a hit about to land.");
			_shockwaveReachField = Slider(rootPanel, "Shockwave Reach", "ultradodge.shockwaveReach", 1f, 15f, 4f, 1);
			AddDescription(rootPanel, "How close the edge of an expanding shockwave has to be to count as reaching you.");
			_nearMissField = Slider(rootPanel, "Near Miss Distance", "ultradodge.nearMiss", 1f, 15f, 5f, 1);
			AddDescription(rootPanel, "After a dash or jump, an attack passing this close counts as dodged. This is what catches melee swings that only become dangerous after the dash.");
			_minClosingSpeedField = Slider(rootPanel, "Minimum Closing Speed", "ultradodge.minClosing", 0f, 50f, 2f, 0);
			AddDescription(rootPanel, "Attacks approaching slower than this are ignored.");
			_requireLookingAtField = Track<BoolField>(new BoolField(rootPanel, "Only Attacks In View", "ultradodge.requireLooking", true, true));
			AddDescription(rootPanel, "Reward only attacks you are facing. Shots and swings coming from behind are ignored.");
			_lookAngleField = Slider(rootPanel, "Look Angle", "ultradodge.lookAngle", 10f, 360f, 90f, 0);
			AddDescription(rootPanel, "Width of the cone in front of the camera that counts as in view. 360 accepts everything.");
			_jumpDodgeField = Track<BoolField>(new BoolField(rootPanel, "Jump Over Shockwaves", "ultradodge.jumpDodge", true, true));
			AddDescription(rootPanel, "Jumping over an expanding shockwave at the right moment counts as a dodge as well.");
			_slamDodgeField = Track<BoolField>(new BoolField(rootPanel, "Ground Slam Dodges", "ultradodge.slamDodge", true, true));
			AddDescription(rootPanel, "Starting a ground slam counts as a dodge, the same as a dash.");
			_explosiveDodgeField = Track<BoolField>(new BoolField(rootPanel, "Dodge Explosives", "ultradodge.explosiveDodge", true, true));
			AddDescription(rootPanel, "Rockets and grenades count while they are still flying, and a blast counts when it goes off where you just were.");
			_blastRadiusField = Slider(rootPanel, "Blast Radius", "ultradodge.blastRadius", 1f, 20f, 6f, 1);
			AddDescription(rootPanel, "How much room a flying explosive is assumed to cover. Blasts that already exist use their real size instead.");
			_beamDodgeField = Track<BoolField>(new BoolField(rootPanel, "Dodge Enemy Beams", "ultradodge.beamDodge", true, true));
			AddDescription(rootPanel, "Instant shots such as the Sentry rifle and the Malicious Face beam count when they pass through the spot you just left.");
			_beamRadiusField = Slider(rootPanel, "Beam Radius", "ultradodge.beamRadius", 0.5f, 10f, 3f, 1);
			AddDescription(rootPanel, "How close a beam has to pass to that spot.");
			_continuousBeamDodgeField = Track<BoolField>(new BoolField(rootPanel, "Dodge Sweeping Beams", "ultradodge.continuousBeamDodge", true, true));
			AddDescription(rootPanel, "Sustained beams such as the Leviathan's count when you leave their path while they are firing.");
			_continuousBeamMarginField = Slider(rootPanel, "Sweeping Beam Margin", "ultradodge.continuousBeamMargin", 0f, 6f, 1.5f, 1);
			AddDescription(rootPanel, "Extra room added to the beam's own width when deciding how close counts as being in it.");
			_telegraphGraceField = Slider(rootPanel, "Telegraph Grace", "ultradodge.telegraphGrace", 0.1f, 3f, 1f, 2);
			AddDescription(rootPanel, "How long after a dodge a telegraphed attack that fires late, such as the Malicious Face beam or a holy beam, still counts. Longer than the dodge window because these attacks land after their wind up.");
			_insigniaDodgeField = Track<BoolField>(new BoolField(rootPanel, "Dodge Virtue Insignias", "ultradodge.insigniaDodge", true, true));
			AddDescription(rootPanel, "Leaving a Virtue's marked circle before it fires counts as a dodge.");
			_cleanDodgeField = Track<BoolField>(new BoolField(rootPanel, "Clean Dodges Only", "ultradodge.cleanOnly", true, true));
			AddDescription(rootPanel, "Cancel the reward if you take damage during the dodge window.");
			AddTitle(rootPanel, "Slow Motion");
			_slowMotionField = Track<BoolField>(new BoolField(rootPanel, "Enabled", "ultradodge.slowMotion", true, true));
			AddDescription(rootPanel, "Slow time down on a successful dodge.", SlowMotionColor);
			_slowMotionScaleField = Slider(rootPanel, "Time Scale", "ultradodge.slowMotionScale", 0.05f, 0.95f, 0.25f, 2);
			AddDescription(rootPanel, "How slow time gets. Lower is slower.");
			_slowMotionHoldField = Slider(rootPanel, "Hold Duration", "ultradodge.slowMotionHold", 0f, 2f, 0.35f, 2);
			AddDescription(rootPanel, "How long the slow motion is held in real seconds. The game then ramps time back to normal on its own.");
			AddTitle(rootPanel, "Shockwave");
			_waveField = Track<BoolField>(new BoolField(rootPanel, "Enabled", "ultradodge.wave", true, true));
			AddDescription(rootPanel, "Spawn the expanding distortion ring around you. Visual only, it cannot damage or push anything.", WaveColor);
			_waveSizeField = Slider(rootPanel, "Size Multiplier", "ultradodge.waveSize", 0.1f, 3f, 0.6f, 2);
			AddDescription(rootPanel, "How wide the ring grows before it fades.");
			_waveSpeedField = Slider(rootPanel, "Speed Multiplier", "ultradodge.waveSpeed", 0.1f, 4f, 1.25f, 2);
			AddDescription(rootPanel, "How fast the ring expands.");
			AddTitle(rootPanel, "Invincibility");
			_invincibilityField = Track<BoolField>(new BoolField(rootPanel, "Enabled", "ultradodge.iframes", true, true));
			AddDescription(rootPanel, "A successful dodge makes you briefly immune to damage, the same way the dash and the grace period after a hit already do.", InvincibilityColor);
			_invincibilityDurationField = Slider(rootPanel, "Duration", "ultradodge.iframeDuration", 0.05f, 1f, 0.25f, 2);
			AddDescription(rootPanel, "How long the immunity lasts. Counted in game time, so slow motion stretches it.");
			_staminaHighlightField = Track<BoolField>(new BoolField(rootPanel, "Yellow Stamina Bar", "ultradodge.staminaHighlight", true, true));
			AddDescription(rootPanel, "Hold the dash bar yellow until the slow motion ends.");
			AddTitle(rootPanel, "Dash Bar Reward");
			_staminaRewardField = Track<BoolField>(new BoolField(rootPanel, "Enabled", "ultradodge.staminaReward", true, true));
			AddDescription(rootPanel, "A successful dodge makes the dash bar refill faster for a moment, so chaining dodges keeps you moving.", StaminaColor);
			_staminaBonusRateField = Slider(rootPanel, "Extra Charge Rate", "ultradodge.staminaBonusRate", 10f, 300f, 70f, 0);
			AddDescription(rootPanel, "Extra charge per second on top of the game's own refill. One dash costs 100, and the game refills 70 per second on Standard, so the default roughly doubles the rate.");
			_staminaBonusDurationField = Slider(rootPanel, "Bonus Duration", "ultradodge.staminaBonusDuration", 0.1f, 5f, 1.5f, 2);
			AddDescription(rootPanel, "How long the faster refill lasts in real seconds.");
			AddTitle(rootPanel, "Colour Drain");
			_drainField = Track<BoolField>(new BoolField(rootPanel, "Enabled", "ultradodge.drain", true, true));
			AddDescription(rootPanel, "Pull the colour out of the screen during the dodge, leaving it black, white and grey. Uses the same pass the game runs when you die.", DrainColor);
			_drainStrengthField = Slider(rootPanel, "Strength", "ultradodge.drainStrength", 0f, 1f, 1f, 2);
			AddDescription(rootPanel, "How far the colour is pulled out. 1 is fully grey.");
			_drainFadeInField = Slider(rootPanel, "Fade In", "ultradodge.drainFadeIn", 0f, 1f, 0.05f, 2);
			AddDescription(rootPanel, "Fade in time in real seconds.");
			_drainHoldField = Slider(rootPanel, "Hold", "ultradodge.drainHold", 0f, 2f, 0.25f, 2);
			AddDescription(rootPanel, "Time at full strength in real seconds.");
			_drainFadeOutField = Slider(rootPanel, "Fade Out", "ultradodge.drainFadeOut", 0f, 3f, 0.5f, 2);
			AddDescription(rootPanel, "Fade out time in real seconds.");
			_keepBarColorField = Track<BoolField>(new BoolField(rootPanel, "Keep Bar Yellow", "ultradodge.keepBarColor", true, true));
			AddDescription(rootPanel, "Leave the yellow of the dash bar untouched while everything else turns grey.");
			_keepColorRangeField = Slider(rootPanel, "Yellow Range", "ultradodge.keepColorRange", 0.05f, 0.5f, 0.22f, 2);
			AddDescription(rootPanel, "How far a colour can sit from that yellow and still keep its hue. Raise it if the bar still greys out, lower it if other yellow things in the level stay coloured.");
			AddTitle(rootPanel, "Diagnostics");
			_debugLoggingField = Track<BoolField>(new BoolField(rootPanel, "Debug Logging", "ultradodge.debug", false, true));
			AddDescription(rootPanel, "Write every dash, every attack considered and every rejected candidate to the BepInEx log. Use it to tune the detection values, then turn it back off.");
			UpdateEnabledInteractable();
		}

		private static FloatSliderField Slider(ConfigPanel panel, string name, string guid, float min, float max, float value, int decimals)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return Track<FloatSliderField>(new FloatSliderField(panel, name, guid, new Tuple<float, float>(min, max), value, decimals, true));
		}

		private static float Value(FloatSliderField field, float fallback, float min)
		{
			if (field != null)
			{
				return Mathf.Max(field.value, min);
			}
			return fallback;
		}

		private static T Track<T>(T field) where T : ConfigField
		{
			GreyableFields.Add((ConfigField)(object)field);
			return field;
		}

		private static void UpdateEnabledInteractable()
		{
			bool enabled = Enabled;
			foreach (ConfigField greyableField in GreyableFields)
			{
				greyableField.interactable = enabled;
			}
		}

		private static ConfigHeader AddTitle(ConfigPanel panel, string text)
		{
			//IL_0004: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return Track<ConfigHeader>(new ConfigHeader(panel, text, 18)
			{
				textColor = TitleColor
			});
		}

		private static ConfigHeader AddDescription(ConfigPanel panel, string text)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return AddDescription(panel, text, Color.gray);
		}

		private static ConfigHeader AddDescription(ConfigPanel panel, string text, Color color)
		{
			//IL_0004: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			return Track<ConfigHeader>(new ConfigHeader(panel, text, 14)
			{
				textColor = color
			});
		}
	}
}
namespace UltraDodge.Patches
{
	[HarmonyPatch(typeof(NewMovement), "TryDash")]
	internal static class DashPatch
	{
		internal struct DashState
		{
			internal float BoostLeft;

			internal float BoostCharge;

			internal bool WasBoosting;
		}

		private static readonly FieldRef<NewMovement, float> BoostLeftRef = AccessTools.FieldRefAccess<NewMovement, float>("boostLeft");

		[HarmonyPrefix]
		private static void Prefix(NewMovement __instance, out DashState __state)
		{
			__state = new DashState
			{
				BoostLeft = BoostLeftRef.Invoke(__instance),
				BoostCharge = __instance.boostCharge,
				WasBoosting = __instance.boost
			};
		}

		[HarmonyPostfix]
		private static void Postfix(NewMovement __instance, DashState __state)
		{
			float num = BoostLeftRef.Invoke(__instance);
			bool flag = (!__state.WasBoosting && __instance.boost) || (num >= 100f && __state.BoostLeft < 100f) || __state.BoostCharge - __instance.boostCharge >= 99f;
			if (UltraDodgeConfig.DebugLogging)
			{
				Plugin.Log.LogInfo((object)($"[dodge] TryDash started={flag} " + $"boostLeft {__state.BoostLeft:0.0}->{num:0.0} " + $"stamina {__state.BoostCharge:0.0}->{__instance.boostCharge:0.0} " + $"boost {__state.WasBoosting}->{__instance.boost} " + $"noDashSlide={__instance.modNoDashSlide} runtime={DodgeRuntime.IsAlive}"));
			}
			if (flag)
			{
				DodgeRuntime.NotifyDash(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(NewMovement), "Jump")]
	internal static class JumpPatch
	{
		[HarmonyPrefix]
		private static void Prefix(NewMovement __instance, out bool __state)
		{
			__state = __instance.jumping;
		}

		[HarmonyPostfix]
		private static void Postfix(NewMovement __instance, bool __state)
		{
			if (!__state && __instance.jumping)
			{
				DodgeRuntime.NotifyJump(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(NewMovement), "GetHurt")]
	internal static class PlayerHurtPatch
	{
		[HarmonyPrefix]
		private static void Prefix(NewMovement __instance, out int __state)
		{
			__state = __instance.hp;
		}

		[HarmonyPostfix]
		private static void Postfix(NewMovement __instance, int __state)
		{
			if (__instance.hp < __state)
			{
				DodgeRuntime.NotifyPlayerHurt();
			}
		}
	}
	[HarmonyPatch(typeof(NewMovement), "TryStartSlam")]
	internal static class SlamPatch
	{
		[HarmonyPrefix]
		private static void Prefix(NewMovement __instance, out bool __state)
		{
			__state = (Object)(object)__instance.gc != (Object)null && __instance.gc.heavyFall;
		}

		[HarmonyPostfix]
		private static void Postfix(NewMovement __instance, bool __state)
		{
			if (!__state && (Object)(object)__instance.gc != (Object)null && __instance.gc.heavyFall)
			{
				DodgeRuntime.NotifySlam(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnEnable")]
	internal static class ProjectileEnabledPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Projectile __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnDisable")]
	internal static class ProjectileDisabledPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Projectile __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(SwingCheck2), "DamageStart")]
	internal static class SwingStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SwingCheck2 __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(SwingCheck2), "DamageStop")]
	internal static class SwingStopPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SwingCheck2 __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(PhysicalShockwave), "Start")]
	internal static class ShockwaveStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysicalShockwave __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(PhysicalShockwave), "OnDestroy")]
	internal static class ShockwaveDestroyedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysicalShockwave __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(Grenade), "Start")]
	internal static class GrenadeSpawnedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Grenade __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(Grenade), "OnDestroy")]
	internal static class GrenadeDestroyedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Grenade __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(VirtueInsignia), "Start")]
	internal static class InsigniaSpawnedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(VirtueInsignia __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(VirtueInsignia), "Explode")]
	internal static class InsigniaFiredPatch
	{
		[HarmonyPostfix]
		private static void Postfix(VirtueInsignia __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.explosion != (Object)null)
			{
				float radius = Mathf.Max(1f, __instance.explosion.transform.lossyScale.x * 0.5f);
				DodgeRuntime.ReportInsigniaFired(((Component)__instance).transform.position, radius, (Object)(object)__instance);
			}
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(ContinuousBeam), "Start")]
	internal static class ContinuousBeamStartedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ContinuousBeam __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(ContinuousBeam), "OnDestroy")]
	internal static class ContinuousBeamDestroyedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ContinuousBeam __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(ThrownSword), "Start")]
	internal static class ThrownSwordSpawnedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ThrownSword __instance)
		{
			ThreatTracker.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(ThrownSword), "OnDestroy")]
	internal static class ThrownSwordDestroyedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ThrownSword __instance)
		{
			ThreatTracker.Unregister(__instance);
		}
	}
	[HarmonyPatch(typeof(Explosion), "Start")]
	internal static class ExplosionSpawnedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Explosion __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.harmless && __instance.damage > 0 && (int)__instance.canHit != 2)
			{
				DodgeRuntime.ReportBlast(((Component)__instance).transform.position, __instance.maxSize * 0.5f, (Object)(object)__instance);
			}
		}
	}
	[HarmonyPatch(typeof(RevolverBeam), "Start")]
	internal static class BeamFiredPatch
	{
		[HarmonyPostfix]
		private static void Postfix(RevolverBeam __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			if (!__instance.fake && !__instance.deflected && !(__instance.damage <= 0f) && ((int)__instance.beamType == 3 || (int)__instance.beamType == 2))
			{
				Transform transform = ((Component)__instance).transform;
				DodgeRuntime.ReportBeam(transform.position, transform.forward, (Object)(object)__instance);
			}
		}
	}
}
namespace UltraDodge.Effects
{
	internal sealed class ColorDrain
	{
		private const int LutSize = 16;

		private const string PalettizeKeyword = "PALETTIZE";

		private const int GradingPrecision = 2048;

		private const float RebuildThreshold = 0.02f;

		private static readonly int LutId = Shader.PropertyToID("_LUT");

		private static readonly int PrecisionId = Shader.PropertyToID("_ColorPrecision");

		private Texture3D lut;

		private Color32[] pixels;

		private float appliedAmount = -1f;

		private Texture previousLut;

		private bool previousPalettize;

		private int previousPrecision;

		private bool overriding;

		private float elapsed;

		private float peak;

		private float fadeIn;

		private float hold;

		private float fadeOut;

		private bool playing;

		internal void Play(float strength, float fadeInTime, float holdTime, float fadeOutTime)
		{
			peak = Mathf.Clamp01(strength);
			fadeIn = Mathf.Max(0f, fadeInTime);
			hold = Mathf.Max(0f, holdTime);
			fadeOut = Mathf.Max(0f, fadeOutTime);
			elapsed = 0f;
			playing = peak > 0f && fadeIn + hold + fadeOut > 0f;
			if (playing)
			{
				SetAmount((fadeIn > 0f) ? 0f : peak);
				if (UltraDodgeConfig.DebugLogging)
				{
					Plugin.Log.LogInfo((object)string.Format("[dodge] colour drain to {0:0.00}, previous palette {1}, palettize was {2}", peak, ((Object)(object)previousLut != (Object)null) ? ((Object)previousLut).name : "none", previousPalettize));
				}
			}
		}

		internal void Tick(float unscaledDeltaTime)
		{
			if (playing)
			{
				elapsed += unscaledDeltaTime;
				float num = fadeIn + hold + fadeOut;
				if (elapsed >= num)
				{
					Stop();
					return;
				}
				float amount = ((elapsed < fadeIn) ? (peak * (elapsed / fadeIn)) : ((!(elapsed < fadeIn + hold)) ? (peak * (1f - (elapsed - fadeIn - hold) / fadeOut)) : peak));
				SetAmount(amount);
			}
		}

		internal void Stop()
		{
			playing = false;
			if (overriding)
			{
				overriding = false;
				appliedAmount = -1f;
				if ((Object)(object)previousLut != (Object)null)
				{
					Shader.SetGlobalTexture(LutId, previousLut);
				}
				if (previousPalettize)
				{
					Shader.EnableKeyword("PALETTIZE");
					Shader.SetGlobalInt(PrecisionId, previousPrecision);
				}
				else
				{
					Shader.DisableKeyword("PALETTIZE");
				}
				previousLut = null;
			}
		}

		private void SetAmount(float amount)
		{
			if (!overriding)
			{
				previousLut = Shader.GetGlobalTexture(LutId);
				previousPalettize = Shader.IsKeywordEnabled("PALETTIZE");
				previousPrecision = Shader.GetGlobalInt(PrecisionId);
				overriding = true;
				Shader.EnableKeyword("PALETTIZE");
				Shader.SetGlobalInt(PrecisionId, 2048);
			}
			if (!(Mathf.Abs(amount - appliedAmount) < 0.02f))
			{
				appliedAmount = amount;
				BuildLut(amount);
				Shader.SetGlobalTexture(LutId, (Texture)(object)lut);
			}
		}

		private void BuildLut(float amount)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003a: Expected O, but got Unknown
			//IL_014e: 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_0158: 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)
			if ((Object)(object)lut == (Object)null)
			{
				lut = new Texture3D(16, 16, 16, (TextureFormat)4, false)
				{
					name = "UltraDodge Grey LUT",
					wrapMode = (TextureWrapMode)1,
					filterMode = (FilterMode)1
				};
				pixels = (Color32[])(object)new Color32[4096];
			}
			bool keepBarColor = UltraDodgeConfig.KeepBarColor;
			float keepColorRange = UltraDodgeConfig.KeepColorRange;
			float num = keepColorRange * 0.4f;
			Color highlightColor = StaminaHighlight.HighlightColor;
			float highlightLengthSquared = highlightColor.r * highlightColor.r + highlightColor.g * highlightColor.g + highlightColor.b * highlightColor.b;
			int num2 = 0;
			for (int i = 0; i < 16; i++)
			{
				float num3 = (float)i * (1f / 15f);
				for (int j = 0; j < 16; j++)
				{
					float num4 = (float)j * (1f / 15f);
					for (int k = 0; k < 16; k++)
					{
						float num5 = (float)k * (1f / 15f);
						float num6 = num5 * 0.299f + num4 * 0.587f + num3 * 0.114f;
						float num7 = amount;
						if (keepBarColor)
						{
							float num8 = DistanceToHighlightRamp(num5, num4, num3, highlightColor, highlightLengthSquared);
							float num9 = 1f - Mathf.InverseLerp(num, keepColorRange, num8);
							num7 *= 1f - num9;
						}
						pixels[num2++] = Color32.op_Implicit(new Color(Mathf.Lerp(num5, num6, num7), Mathf.Lerp(num4, num6, num7), Mathf.Lerp(num3, num6, num7), 1f));
					}
				}
			}
			lut.SetPixels32(pixels);
			lut.Apply(false);
		}

		private static float DistanceToHighlightRamp(float red, float green, float blue, Color highlight, float highlightLengthSquared)
		{
			//IL_0001: 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_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_002e: 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)
			float num = Mathf.Clamp01((red * highlight.r + green * highlight.g + blue * highlight.b) / highlightLengthSquared);
			float num2 = red - highlight.r * num;
			float num3 = green - highlight.g * num;
			float num4 = blue - highlight.b * num;
			return Mathf.Sqrt(num2 * num2 + num3 * num3 + num4 * num4);
		}
	}
	internal static class DistortionWave
	{
		private static GroundCheck cachedGroundCheck;

		private static GameObject cachedPrefab;

		private static bool warnedAboutMissingPrefab;

		internal static void Reset()
		{
			cachedGroundCheck = null;
			cachedPrefab = null;
		}

		internal static bool TrySpawn(NewMovement movement)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedGroundCheck == (Object)null || (Object)(object)cachedPrefab == (Object)null)
			{
				Resolve(FindGroundCheck(movement));
			}
			if ((Object)(object)cachedGroundCheck == (Object)null || (Object)(object)cachedPrefab == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)cachedGroundCheck).transform;
			MakeVisualOnly(Object.Instantiate<GameObject>(cachedPrefab, transform.position, Quaternion.LookRotation(transform.forward, transform.up)));
			return true;
		}

		private static void MakeVisualOnly(GameObject wave)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			PhysicalShockwave val = default(PhysicalShockwave);
			if (wave.TryGetComponent<PhysicalShockwave>(ref val))
			{
				val.hasHurtPlayer = true;
				val.damage = 0;
				val.force = 0f;
				val.noDamageToEnemy = true;
				val.enemy = false;
				val.soundEffect = null;
				PhysicalShockwave obj = val;
				obj.speed *= UltraDodgeConfig.WaveSpeedMultiplier;
				float num = val.maxSize * UltraDodgeConfig.WaveSizeMultiplier;
				val.maxSize = Mathf.Max(num, wave.transform.localScale.x + 1f);
			}
			Collider[] componentsInChildren = wave.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}

		private static void Resolve(GroundCheck groundCheck)
		{
			cachedGroundCheck = groundCheck;
			cachedPrefab = (((Object)(object)groundCheck != (Object)null) ? groundCheck.shockwave : null);
			if ((Object)(object)cachedPrefab != (Object)null)
			{
				if (UltraDodgeConfig.DebugLogging)
				{
					Plugin.Log.LogInfo((object)("[dodge] using shockwave prefab '" + ((Object)cachedPrefab).name + "' from '" + ((Object)groundCheck).name + "'"));
				}
			}
			else if (!warnedAboutMissingPrefab)
			{
				warnedAboutMissingPrefab = true;
				Plugin.Log.LogWarning((object)"Could not find the player ground slam shockwave prefab. The dodge ring will be skipped.");
			}
		}

		private static GroundCheck FindGroundCheck(NewMovement movement)
		{
			if ((Object)(object)movement == (Object)null)
			{
				return null;
			}
			GroundCheck val = null;
			if ((Object)(object)movement.gc != (Object)null)
			{
				val = ((Component)movement.gc).GetComponentInChildren<GroundCheck>(true);
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)movement).GetComponentInChildren<GroundCheck>(true);
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<GroundCheck>();
			}
			return val;
		}
	}
	internal sealed class StaminaHighlight
	{
		internal static readonly Color HighlightColor = new Color(1f, 0.85f, 0.1f);

		private static readonly FieldRef<StaminaMeter, Image> BarRef = AccessTools.FieldRefAccess<StaminaMeter, Image>("staminaBar");

		private const float SearchInterval = 0.5f;

		private StaminaMeter[] meters;

		private float nextSearchTime;

		private bool active;

		internal void Set(bool wanted)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (wanted)
			{
				active = true;
				Paint(HighlightColor);
			}
			else if (active)
			{
				active = false;
				Restore();
			}
		}

		private void Paint(Color color)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!ResolveMeters())
			{
				return;
			}
			for (int i = 0; i < meters.Length; i++)
			{
				StaminaMeter val = meters[i];
				if (!((Object)(object)val == (Object)null))
				{
					Image val2 = BarRef.Invoke(val);
					if ((Object)(object)val2 != (Object)null)
					{
						((Graphic)val2).color = color;
					}
				}
			}
		}

		private void Restore()
		{
			if (meters == null)
			{
				return;
			}
			for (int i = 0; i < meters.Length; i++)
			{
				StaminaMeter val = meters[i];
				if ((Object)(object)val != (Object)null)
				{
					val.UpdateColors();
				}
			}
		}

		private bool ResolveMeters()
		{
			if (meters != null && meters.Length != 0 && (Object)(object)meters[0] != (Object)null)
			{
				return true;
			}
			if (Time.unscaledTime < nextSearchTime)
			{
				return false;
			}
			nextSearchTime = Time.unscaledTime + 0.5f;
			meters = Object.FindObjectsOfType<StaminaMeter>();
			if (meters != null)
			{
				return meters.Length != 0;
			}
			return false;
		}
	}
}
namespace UltraDodge.Detection
{
	internal enum ThreatKind
	{
		None,
		Projectile,
		Melee,
		Shockwave,
		Explosive,
		Blast,
		Beam,
		Insignia,
		ContinuousBeam,
		ThrownBlade
	}
	[Flags]
	internal enum ThreatMask
	{
		None = 0,
		Projectile = 1,
		Melee = 2,
		Shockwave = 4,
		Explosive = 8,
		Blast = 0x10,
		Beam = 0x20,
		Insignia = 0x40,
		ContinuousBeam = 0x80,
		ThrownBlade = 0x100,
		All = 0x1FF
	}
	internal struct ThreatInfo
	{
		internal ThreatKind Kind;

		internal float TimeToImpact;

		internal float Distance;

		internal Object Source;

		internal string SourceName
		{
			get
			{
				if (!(Source != (Object)null))
				{
					return "unknown";
				}
				return Source.name;
			}
		}
	}
	internal struct DodgeQuery
	{
		internal Vector3 PlayerCenter;

		internal Vector3 Origin;

		internal Vector3 EyePosition;

		internal Vector3 EyeForward;

		internal ThreatMask Allowed;
	}
	internal static class ThreatTracker
	{
		private sealed class TrackedProjectile
		{
			internal Projectile Projectile;

			internal Transform Transform;

			internal Rigidbody Body;
		}

		private sealed class TrackedSwing
		{
			internal SwingCheck2 Swing;

			internal Transform Transform;

			internal Vector3 LastPosition;

			internal Vector3 Velocity;

			internal bool HasVelocity;
		}

		private sealed class TrackedShockwave
		{
			internal PhysicalShockwave Wave;

			internal Transform Transform;

			internal Collider Body;

			internal Renderer Visual;

			internal float Radius;

			internal float Growth;

			internal bool HasRadius;
		}

		private sealed class TrackedExplosive
		{
			internal Grenade Grenade;

			internal Transform Transform;
		}

		private sealed class TrackedInsignia
		{
			internal VirtueInsignia Insignia;

			internal Transform Transform;

			internal float Radius;
		}

		private sealed class TrackedBeam
		{
			internal ContinuousBeam Beam;

			internal Transform Transform;
		}

		private sealed class TrackedBlade
		{
			internal ThrownSword Sword;

			internal Transform Transform;

			internal Vector3 LastPosition;

			internal Vector3 Velocity;

			internal bool HasVelocity;
		}

		private const float Smoothing = 0.5f;

		private const int MaxDiagnosticLines = 4;

		private static readonly FieldRef<VirtueInsignia, bool> InsigniaActivatingRef = AccessTools.FieldRefAccess<VirtueInsignia, bool>("activating");

		private static readonly FieldRef<VirtueInsignia, float> InsigniaProgressRef = AccessTools.FieldRefAccess<VirtueInsignia, float>("activationTime");

		private static readonly List<TrackedProjectile> Projectiles = new List<TrackedProjectile>(64);

		private static readonly List<TrackedSwing> Swings = new List<TrackedSwing>(8);

		private static readonly List<TrackedShockwave> Shockwaves = new List<TrackedShockwave>(8);

		private static readonly List<TrackedExplosive> Explosives = new List<TrackedExplosive>(16);

		private static readonly List<TrackedInsignia> Insignias = new List<TrackedInsignia>(8);

		private static readonly List<TrackedBeam> Beams = new List<TrackedBeam>(4);

		private static readonly List<TrackedBlade> Blades = new List<TrackedBlade>(8);

		internal static int ProjectileCount => Projectiles.Count;

		internal static int SwingCount => Swings.Count;

		internal static int ShockwaveCount => Shockwaves.Count;

		internal static int ExplosiveCount => Explosives.Count;

		internal static int InsigniaCount => Insignias.Count;

		internal static int BeamCount => Beams.Count;

		internal static int BladeCount => Blades.Count;

		internal static ThreatMask MaskOf(ThreatKind kind)
		{
			return kind switch
			{
				ThreatKind.Projectile => ThreatMask.Projectile, 
				ThreatKind.Melee => ThreatMask.Melee, 
				ThreatKind.Shockwave => ThreatMask.Shockwave, 
				ThreatKind.Explosive => ThreatMask.Explosive, 
				ThreatKind.Blast => ThreatMask.Blast, 
				ThreatKind.Beam => ThreatMask.Beam, 
				ThreatKind.ContinuousBeam => ThreatMask.ContinuousBeam, 
				ThreatKind.ThrownBlade => ThreatMask.ThrownBlade, 
				ThreatKind.Insignia => ThreatMask.Insignia, 
				_ => ThreatMask.None, 
			};
		}

		internal static float DistanceToRay(Vector3 origin, Vector3 direction, Vector3 point, out Vector3 closest)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = point - origin;
			float magnitude = ((Vector3)(ref direction)).magnitude;
			if (magnitude < 0.0001f)
			{
				closest = origin;
				return ((Vector3)(ref val)).magnitude;
			}
			Vector3 val2 = direction / magnitude;
			float num = Mathf.Max(0f, Vector3.Dot(val, val2));
			closest = origin + val2 * num;
			Vector3 val3 = val - val2 * num;
			return ((Vector3)(ref val3)).magnitude;
		}

		internal static void Register(Projectile projectile)
		{
			if ((Object)(object)projectile == (Object)null || projectile.decorative || projectile.playerBullet)
			{
				return;
			}
			for (int i = 0; i < Projectiles.Count; i++)
			{
				if ((Object)(object)Projectiles[i].Projectile == (Object)(object)projectile)
				{
					return;
				}
			}
			Projectiles.Add(new TrackedProjectile
			{
				Projectile = projectile,
				Transform = ((Component)projectile).transform,
				Body = ((Component)projectile).GetComponent<Rigidbody>()
			});
		}

		internal static void Unregister(Projectile projectile)
		{
			for (int num = Projectiles.Count - 1; num >= 0; num--)
			{
				TrackedProjectile trackedProjectile = Projectiles[num];
				if ((Object)(object)trackedProjectile.Projectile == (Object)null || (Object)(object)trackedProjectile.Projectile == (Object)(object)projectile)
				{
					Projectiles.RemoveAt(num);
				}
			}
		}

		internal static void Register(SwingCheck2 swing)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)swing == (Object)null)
			{
				return;
			}
			for (int i = 0; i < Swings.Count; i++)
			{
				if ((Object)(object)Swings[i].Swing == (Object)(object)swing)
				{
					return;
				}
			}
			Transform transform = ((Component)swing).transform;
			Swings.Add(new TrackedSwing
			{
				Swing = swing,
				Transform = transform,
				LastPosition = transform.position
			});
		}

		internal static void Unregister(SwingCheck2 swing)
		{
			for (int num = Swings.Count - 1; num >= 0; num--)
			{
				TrackedSwing trackedSwing = Swings[num];
				if ((Object)(object)trackedSwing.Swing == (Object)null || (Object)(object)trackedSwing.Swing == (Object)(object)swing)
				{
					Swings.RemoveAt(num);
				}
			}
		}

		internal static void Register(PhysicalShockwave wave)
		{
			if ((Object)(object)wave == (Object)null || wave.damage <= 0 || wave.hasHurtPlayer)
			{
				return;
			}
			for (int i = 0; i < Shockwaves.Count; i++)
			{
				if ((Object)(object)Shockwaves[i].Wave == (Object)(object)wave)
				{
					return;
				}
			}
			Shockwaves.Add(new TrackedShockwave
			{
				Wave = wave,
				Transform = ((Component)wave).transform,
				Body = ((Component)wave).GetComponentInChildren<Collider>(),
				Visual = ((Component)wave).GetComponentInChildren<Renderer>()
			});
		}

		internal static void Unregister(PhysicalShockwave wave)
		{
			for (int num = Shockwaves.Count - 1; num >= 0; num--)
			{
				TrackedShockwave trackedShockwave = Shockwaves[num];
				if ((Object)(object)trackedShockwave.Wave == (Object)null || (Object)(object)trackedShockwave.Wave == (Object)(object)wave)
				{
					Shockwaves.RemoveAt(num);
				}
			}
		}

		internal static void Register(Grenade grenade)
		{
			if ((Object)(object)grenade == (Object)null || !grenade.enemy || (Object)(object)grenade.rb == (Object)null)
			{
				return;
			}
			for (int i = 0; i < Explosives.Count; i++)
			{
				if ((Object)(object)Explosives[i].Grenade == (Object)(object)grenade)
				{
					return;
				}
			}
			Explosives.Add(new TrackedExplosive
			{
				Grenade = grenade,
				Transform = ((Component)grenade).transform
			});
		}

		internal static void Unregister(Grenade grenade)
		{
			for (int num = Explosives.Count - 1; num >= 0; num--)
			{
				TrackedExplosive trackedExplosive = Explosives[num];
				if ((Object)(object)trackedExplosive.Grenade == (Object)null || (Object)(object)trackedExplosive.Grenade == (Object)(object)grenade)
				{
					Explosives.RemoveAt(num);
				}
			}
		}

		internal static void Register(VirtueInsignia insignia)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)insignia == (Object)null || insignia.damage <= 0 || (Object)(object)insignia.explosion == (Object)null)
			{
				return;
			}
			for (int i = 0; i < Insignias.Count; i++)
			{
				if ((Object)(object)Insignias[i].Insignia == (Object)(object)insignia)
				{
					return;
				}
			}
			float radius = Mathf.Max(1f, insignia.explosion.transform.lossyScale.x * 0.5f);
			Insignias.Add(new TrackedInsignia
			{
				Insignia = insignia,
				Transform = ((Component)insignia).transform,
				Radius = radius
			});
		}

		internal static void Unregister(VirtueInsignia insignia)
		{
			for (int num = Insignias.Count - 1; num >= 0; num--)
			{
				TrackedInsignia trackedInsignia = Insignias[num];
				if ((Object)(object)trackedInsignia.Insignia == (Object)null || (Object)(object)trackedInsignia.Insignia == (Object)(object)insignia)
				{
					Insignias.RemoveAt(num);
				}
			}
		}

		internal static void Register(ContinuousBeam beam)
		{
			if ((Object)(object)beam == (Object)null || !beam.canHitPlayer || beam.damage <= 0f)
			{
				return;
			}
			for (int i = 0; i < Beams.Count; i++)
			{
				if ((Object)(object)Beams[i].Beam == (Object)(object)beam)
				{
					return;
				}
			}
			Beams.Add(new TrackedBeam
			{
				Beam = beam,
				Transform = ((Component)beam).transform
			});
		}

		internal static void Unregister(ContinuousBeam beam)
		{
			for (int num = Beams.Count - 1; num >= 0; num--)
			{
				TrackedBeam trackedBeam = Beams[num];
				if ((Object)(object)trackedBeam.Beam == (Object)null || (Object)(object)trackedBeam.Beam == (Object)(object)beam)
				{
					Beams.RemoveAt(num);
				}
			}
		}

		internal static void Register(ThrownSword sword)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sword == (Object)null)
			{
				return;
			}
			for (int i = 0; i < Blades.Count; i++)
			{
				if ((Object)(object)Blades[i].Sword == (Object)(object)sword)
				{
					return;
				}
			}
			Transform transform = ((Component)sword).transform;
			Blades.Add(new TrackedBlade
			{
				Sword = sword,
				Transform = transform,
				LastPosition = transform.position
			});
		}

		internal static void Unregister(ThrownSword sword)
		{
			for (int num = Blades.Count - 1; num >= 0; num--)
			{
				TrackedBlade trackedBlade = Blades[num];
				if ((Object)(object)trackedBlade.Sword == (Object)null || (Object)(object)trackedBlade.Sword == (Object)(object)sword)
				{
					Blades.RemoveAt(num);
				}
			}
		}

		internal static void Clear()
		{
			Projectiles.Clear();
			Swings.Clear();
			Shockwaves.Clear();
			Explosives.Clear();
			Insignias.Clear();
			Beams.Clear();
			Blades.Clear();
		}

		internal static void SampleThreats(float deltaTime)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0078: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			if (deltaTime <= 0f)
			{
				return;
			}
			for (int num = Swings.Count - 1; num >= 0; num--)
			{
				TrackedSwing trackedSwing = Swings[num];
				if ((Object)(object)trackedSwing.Swing == (Object)null || (Object)(object)trackedSwing.Transform == (Object)null)
				{
					Swings.RemoveAt(num);
				}
				else
				{
					Vector3 position = trackedSwing.Transform.position;
					Vector3 val = (position - trackedSwing.LastPosition) / deltaTime;
					trackedSwing.Velocity = (trackedSwing.HasVelocity ? Vector3.Lerp(trackedSwing.Velocity, val, 0.5f) : val);
					trackedSwing.LastPosition = position;
					trackedSwing.HasVelocity = true;
				}
			}
			for (int num2 = Shockwaves.Count - 1; num2 >= 0; num2--)
			{
				TrackedShockwave trackedShockwave = Shockwaves[num2];
				if ((Object)(object)trackedShockwave.Wave == (Object)null || (Object)(object)trackedShockwave.Transform == (Object)null)
				{
					Shockwaves.RemoveAt(num2);
				}
				else
				{
					float num3 = MeasureRadius(trackedShockwave);
					float num4 = (num3 - trackedShockwave.Radius) / deltaTime;
					trackedShockwave.Growth = (trackedShockwave.HasRadius ? Mathf.Lerp(trackedShockwave.Growth, num4, 0.5f) : Mathf.Max(0f, num4));
					trackedShockwave.Radius = num3;
					trackedShockwave.HasRadius = true;
				}
			}
			for (int num5 = Blades.Count - 1; num5 >= 0; num5--)
			{
				TrackedBlade trackedBlade = Blades[num5];
				if ((Object)(object)trackedBlade.Sword == (Object)null || (Object)(object)trackedBlade.Transform == (Object)null)
				{
					Blades.RemoveAt(num5);
				}
				else
				{
					Vector3 position2 = trackedBlade.Transform.position;
					Vector3 val2 = (position2 - trackedBlade.LastPosition) / deltaTime;
					trackedBlade.Velocity = (trackedBlade.HasVelocity ? Vector3.Lerp(trackedBlade.Velocity, val2, 0.5f) : val2);
					trackedBlade.LastPosition = position2;
					trackedBlade.HasVelocity = true;
				}
			}
		}

		internal static bool TryFindIncoming(in DodgeQuery query, out ThreatInfo threat)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0104: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: 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_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			float dodgeWindow = UltraDodgeConfig.DodgeWindow;
			float minClosingSpeed = UltraDodgeConfig.MinClosingSpeed;
			threat = default(ThreatInfo);
			threat.TimeToImpact = float.MaxValue;
			if ((query.Allowed & ThreatMask.Projectile) != ThreatMask.None)
			{
				float projectileHitRadius = UltraDodgeConfig.ProjectileHitRadius;
				for (int num = Projectiles.Count - 1; num >= 0; num--)
				{
					if (TryGetLiveProjectile(num, out var tracked))
					{
						Vector3 position = tracked.Transform.position;
						if (IsInView(in query, position) && TryGetInterceptTime(position, VelocityOf(tracked), query.PlayerCenter, projectileHitRadius, minClosingSpeed, out var time) && time <= dodgeWindow && time < threat.TimeToImpact)
						{
							threat.Kind = ThreatKind.Projectile;
							threat.TimeToImpact = time;
							threat.Distance = Vector3.Distance(position, query.PlayerCenter);
							threat.Source = (Object)(object)tracked.Projectile;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Melee) != ThreatMask.None)
			{
				float meleeReach = UltraDodgeConfig.MeleeReach;
				for (int num2 = Swings.Count - 1; num2 >= 0; num2--)
				{
					if (TryGetLiveSwing(num2, out var tracked2))
					{
						Vector3 val = SwingPoint(tracked2, query.PlayerCenter);
						if (IsInView(in query, val))
						{
							float distance = Vector3.Distance(val, query.PlayerCenter);
							if (TrySwingImpactTime(tracked2, query.PlayerCenter, distance, meleeReach, minClosingSpeed, out var time2) && time2 <= dodgeWindow && time2 < threat.TimeToImpact)
							{
								threat.Kind = ThreatKind.Melee;
								threat.TimeToImpact = time2;
								threat.Distance = distance;
								threat.Source = SwingSource(tracked2.Swing);
							}
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Shockwave) != ThreatMask.None)
			{
				float shockwaveReach = UltraDodgeConfig.ShockwaveReach;
				for (int num3 = Shockwaves.Count - 1; num3 >= 0; num3--)
				{
					if (TryGetLiveShockwave(num3, out var tracked3) && TryShockwaveImpactTime(tracked3, query.PlayerCenter, shockwaveReach, out var time3, out var gap) && time3 <= dodgeWindow && time3 < threat.TimeToImpact)
					{
						threat.Kind = ThreatKind.Shockwave;
						threat.TimeToImpact = time3;
						threat.Distance = gap;
						threat.Source = (Object)(object)tracked3.Wave;
					}
				}
			}
			if ((query.Allowed & ThreatMask.Explosive) != ThreatMask.None && UltraDodgeConfig.ExplosiveDodge)
			{
				float blastRadius = UltraDodgeConfig.BlastRadius;
				for (int num4 = Explosives.Count - 1; num4 >= 0; num4--)
				{
					if (TryGetLiveExplosive(num4, out var tracked4))
					{
						Vector3 position2 = tracked4.Transform.position;
						if (IsInView(in query, position2) && TryGetInterceptTime(position2, tracked4.Grenade.rb.velocity, query.PlayerCenter, blastRadius, minClosingSpeed, out var time4) && time4 <= dodgeWindow && time4 < threat.TimeToImpact)
						{
							threat.Kind = ThreatKind.Explosive;
							threat.TimeToImpact = time4;
							threat.Distance = Vector3.Distance(position2, query.PlayerCenter);
							threat.Source = (Object)(object)tracked4.Grenade;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Insignia) != ThreatMask.None && UltraDodgeConfig.InsigniaDodge)
			{
				for (int num5 = Insignias.Count - 1; num5 >= 0; num5--)
				{
					if (TryGetLiveInsignia(num5, out var tracked5, out var remaining))
					{
						float num6 = HorizontalDistance(tracked5.Transform.position, query.PlayerCenter);
						if (!(num6 > tracked5.Radius) && remaining <= dodgeWindow && remaining < threat.TimeToImpact)
						{
							threat.Kind = ThreatKind.Insignia;
							threat.TimeToImpact = remaining;
							threat.Distance = num6;
							threat.Source = (Object)(object)tracked5.Insignia;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.ContinuousBeam) != ThreatMask.None && UltraDodgeConfig.ContinuousBeamDodge)
			{
				float continuousBeamMargin = UltraDodgeConfig.ContinuousBeamMargin;
				for (int num7 = Beams.Count - 1; num7 >= 0; num7--)
				{
					if (TryGetLiveBeam(num7, out var tracked6))
					{
						Vector3 position3 = tracked6.Transform.position;
						Vector3 forward = tracked6.Transform.forward;
						float num8 = tracked6.Beam.beamWidth + continuousBeamMargin;
						Vector3 closest;
						float num9 = DistanceToRay(position3, forward, query.PlayerCenter, out closest);
						if (num9 <= num8 && num9 < threat.Distance && IsInView(in query, closest))
						{
							threat.Kind = ThreatKind.ContinuousBeam;
							threat.TimeToImpact = 0f;
							threat.Distance = num9;
							threat.Source = (Object)(object)tracked6.Beam;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.ThrownBlade) != ThreatMask.None)
			{
				float projectileHitRadius2 = UltraDodgeConfig.ProjectileHitRadius;
				for (int num10 = Blades.Count - 1; num10 >= 0; num10--)
				{
					if (TryGetLiveBlade(num10, out var tracked7) && tracked7.HasVelocity)
					{
						Vector3 position4 = tracked7.Transform.position;
						if (IsInView(in query, position4) && TryGetInterceptTime(position4, tracked7.Velocity, query.PlayerCenter, projectileHitRadius2, minClosingSpeed, out var time5) && time5 <= dodgeWindow && time5 < threat.TimeToImpact)
						{
							threat.Kind = ThreatKind.ThrownBlade;
							threat.TimeToImpact = time5;
							threat.Distance = Vector3.Distance(position4, query.PlayerCenter);
							threat.Source = (Object)(object)tracked7.Sword;
						}
					}
				}
			}
			return threat.Kind != ThreatKind.None;
		}

		internal static bool TryFindNearMiss(in DodgeQuery query, out ThreatInfo threat)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: 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_041a: 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_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			threat = default(ThreatInfo);
			threat.Distance = float.MaxValue;
			if ((query.Allowed & ThreatMask.Projectile) != ThreatMask.None)
			{
				float nearMissDistance = UltraDodgeConfig.NearMissDistance;
				for (int num = Projectiles.Count - 1; num >= 0; num--)
				{
					if (TryGetLiveProjectile(num, out var tracked))
					{
						Vector3 position = tracked.Transform.position;
						float num2 = Mathf.Min(Vector3.Distance(position, query.PlayerCenter), Vector3.Distance(position, query.Origin));
						if (!(num2 > nearMissDistance) && !(num2 >= threat.Distance) && IsInView(in query, position))
						{
							threat.Kind = ThreatKind.Projectile;
							threat.Distance = num2;
							threat.TimeToImpact = 0f;
							threat.Source = (Object)(object)tracked.Projectile;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Melee) != ThreatMask.None)
			{
				float meleeReach = UltraDodgeConfig.MeleeReach;
				for (int num3 = Swings.Count - 1; num3 >= 0; num3--)
				{
					if (TryGetLiveSwing(num3, out var tracked2))
					{
						Vector3 val = SwingPoint(tracked2, query.PlayerCenter);
						float num4 = Mathf.Min(Vector3.Distance(val, query.PlayerCenter), Vector3.Distance(SwingPoint(tracked2, query.Origin), query.Origin));
						if (!(num4 > meleeReach) && !(num4 >= threat.Distance) && IsInView(in query, val))
						{
							threat.Kind = ThreatKind.Melee;
							threat.Distance = num4;
							threat.TimeToImpact = 0f;
							threat.Source = SwingSource(tracked2.Swing);
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Shockwave) != ThreatMask.None)
			{
				float shockwaveReach = UltraDodgeConfig.ShockwaveReach;
				for (int num5 = Shockwaves.Count - 1; num5 >= 0; num5--)
				{
					if (TryGetLiveShockwave(num5, out var tracked3) && TryShockwaveImpactTime(tracked3, query.Origin, shockwaveReach, out var time, out var gap) && !(time > 0f) && !(Mathf.Abs(gap) >= threat.Distance))
					{
						threat.Kind = ThreatKind.Shockwave;
						threat.Distance = Mathf.Abs(gap);
						threat.TimeToImpact = 0f;
						threat.Source = (Object)(object)tracked3.Wave;
					}
				}
			}
			if ((query.Allowed & ThreatMask.Explosive) != ThreatMask.None && UltraDodgeConfig.ExplosiveDodge)
			{
				float blastRadius = UltraDodgeConfig.BlastRadius;
				for (int num6 = Explosives.Count - 1; num6 >= 0; num6--)
				{
					if (TryGetLiveExplosive(num6, out var tracked4))
					{
						Vector3 position2 = tracked4.Transform.position;
						float num7 = Mathf.Min(Vector3.Distance(position2, query.PlayerCenter), Vector3.Distance(position2, query.Origin));
						if (!(num7 > blastRadius) && !(num7 >= threat.Distance) && IsInView(in query, position2))
						{
							threat.Kind = ThreatKind.Explosive;
							threat.Distance = num7;
							threat.TimeToImpact = 0f;
							threat.Source = (Object)(object)tracked4.Grenade;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.Insignia) != ThreatMask.None && UltraDodgeConfig.InsigniaDodge)
			{
				float dodgeWindow = UltraDodgeConfig.DodgeWindow;
				for (int num8 = Insignias.Count - 1; num8 >= 0; num8--)
				{
					if (TryGetLiveInsignia(num8, out var tracked5, out var remaining) && !(remaining > dodgeWindow))
					{
						Vector3 position3 = tracked5.Transform.position;
						float num9 = HorizontalDistance(position3, query.Origin);
						if (!(num9 > tracked5.Radius) && !(num9 >= threat.Distance) && !(HorizontalDistance(position3, query.PlayerCenter) <= tracked5.Radius))
						{
							threat.Kind = ThreatKind.Insignia;
							threat.Distance = num9;
							threat.TimeToImpact = 0f;
							threat.Source = (Object)(object)tracked5.Insignia;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.ContinuousBeam) != ThreatMask.None && UltraDodgeConfig.ContinuousBeamDodge)
			{
				float continuousBeamMargin = UltraDodgeConfig.ContinuousBeamMargin;
				for (int num10 = Beams.Count - 1; num10 >= 0; num10--)
				{
					if (TryGetLiveBeam(num10, out var tracked6))
					{
						Vector3 position4 = tracked6.Transform.position;
						Vector3 forward = tracked6.Transform.forward;
						float num11 = tracked6.Beam.beamWidth + continuousBeamMargin;
						Vector3 closest;
						float num12 = DistanceToRay(position4, forward, query.Origin, out closest);
						if (!(num12 > num11) && !(num12 >= threat.Distance) && !(DistanceToRay(position4, forward, query.PlayerCenter, out var _) <= num11) && IsInView(in query, closest))
						{
							threat.Kind = ThreatKind.ContinuousBeam;
							threat.Distance = num12;
							threat.TimeToImpact = 0f;
							threat.Source = (Object)(object)tracked6.Beam;
						}
					}
				}
			}
			if ((query.Allowed & ThreatMask.ThrownBlade) != ThreatMask.None)
			{
				float nearMissDistance2 = UltraDodgeConfig.NearMissDistance;
				for (int num13 = Blades.Count - 1; num13 >= 0; num13--)
				{
					if (TryGetLiveBlade(num13, out var tracked7))
					{
						Vector3 position5 = tracked7.Transform.position;
						float num14 = Mathf.Min(Vector3.Distance(position5, query.PlayerCenter), Vector3.Distance(position5, query.Origin));
						if (!(num14 > nearMissDistance2) && !(num14 >= threat.Distance) && IsInView(in query, position5))
						{
							threat.Kind = ThreatKind.ThrownBlade;
							threat.Distance = num14;
							threat.TimeToImpact = 0f;
							threat.Source = (Object)(object)tracked7.Sword;
						}
					}
				}
			}
			return threat.Kind != ThreatKind.None;
		}

		internal static void LogCandidates(in DodgeQuery query)
		{
			LogProjectiles(in query);
			LogSwings(in query);
			LogShockwaves(in query);
			LogExplosives(in query);
			LogInsignias(in query);
			LogBeams(in query);
			LogBlades(in query);
		}

		private static void LogBlades(in D