Decompiled source of Afterimages v1.0.0

rewind.rwafterimages.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("rewind")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("[rw]Afterimages")]
[assembly: AssemblyTitle("rewind.rwafterimages")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
internal static class Gscope
{
	public static Player? Player;
}
namespace Plugin
{
	public static class AfterimageManager
	{
		public struct AfterimageStyle
		{
			public readonly Color Color;

			public readonly Color SecondaryColor;

			public readonly GradientMode GradientMode;

			public readonly string GradientTexturePath;

			public readonly Texture2D? GradientTexture;

			public readonly float Interval;

			public readonly float Lifetime;

			public readonly float FadeSpeed;

			public readonly int Priority;

			public readonly long Sequence;

			public AfterimageStyle(Color color, Color secondaryColor, GradientMode gradientMode, string gradientTexturePath, Texture2D? gradientTexture, float interval = 0.05f, float lifetime = 0.2f, float fadeSpeed = 8f, int priority = 0, long sequence = 0L)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Color = color;
				SecondaryColor = secondaryColor;
				GradientMode = gradientMode;
				GradientTexturePath = gradientTexturePath;
				GradientTexture = gradientTexture;
				Interval = interval;
				Lifetime = lifetime;
				FadeSpeed = fadeSpeed;
				Priority = priority;
				Sequence = sequence;
			}

			public AfterimageStyle WithSequence(long sequence)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return new AfterimageStyle(Color, SecondaryColor, GradientMode, GradientTexturePath, GradientTexture, Interval, Lifetime, FadeSpeed, Priority, sequence);
			}
		}

		private class VisualState
		{
			public readonly Dictionary<string, AfterimageStyle> Requests = new Dictionary<string, AfterimageStyle>();

			public Coroutine? ActiveTrailCoroutine;

			public AfterimageStyle? ActiveStyle;
		}

		[CompilerGenerated]
		private sealed class <FadeAndDestroy>d__8 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AfterimageStyle style;

			public MeshRenderer renderer;

			public GameObject go;

			private float <elapsed>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeAndDestroy>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<elapsed>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__2 < style.Lifetime)
				{
					<elapsed>5__2 += Time.deltaTime;
					float num = Mathf.Clamp01(<elapsed>5__2 / style.Lifetime);
					Color styleColor = GetStyleColor(style, num);
					styleColor.a *= Mathf.Pow(1f - num, style.FadeSpeed);
					((Renderer)renderer).material.color = styleColor;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				Object.Destroy((Object)(object)go);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TrailRoutine>d__6 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AfterimageStyle style;

			public CharacterVisual visual;

			private float <interval>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TrailRoutine>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
				}
				else
				{
					<>1__state = -1;
					<interval>5__2 = Mathf.Max(0.0001f, style.Interval);
				}
				SpawnAfterimage(visual, style);
				<>2__current = (object)new WaitForSeconds(<interval>5__2);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Dictionary<CharacterVisual, VisualState> VisualStates = new Dictionary<CharacterVisual, VisualState>();

		private static readonly Material AfterimgMaterial = new Material(Shader.Find("Sprites/Default"));

		private static long NextStyleSequence;

		public static void Request(CharacterVisual visual, string requesterId, bool enabled, AfterimageStyle style = default(AfterimageStyle))
		{
			if ((Object)(object)visual == (Object)null || (Object)(object)visual.mainRenderer == (Object)null)
			{
				return;
			}
			if (!VisualStates.TryGetValue(visual, out VisualState value))
			{
				value = new VisualState();
				VisualStates[visual] = value;
			}
			if (enabled)
			{
				value.Requests[requesterId] = style.WithSequence(++NextStyleSequence);
			}
			else
			{
				value.Requests.Remove(requesterId);
			}
			AfterimageStyle? afterimageStyle = ((value.Requests.Count > 0) ? new AfterimageStyle?((from s in value.Requests.Values
				orderby s.Priority descending, s.Sequence descending
				select s).First()) : null);
			if (!AreStylesEqual(afterimageStyle, value.ActiveStyle))
			{
				value.ActiveStyle = afterimageStyle;
				if (value.ActiveTrailCoroutine != null)
				{
					((MonoBehaviour)visual).StopCoroutine(value.ActiveTrailCoroutine);
					value.ActiveTrailCoroutine = null;
				}
				if (afterimageStyle.HasValue)
				{
					value.ActiveTrailCoroutine = ((MonoBehaviour)visual).StartCoroutine(TrailRoutine(visual, afterimageStyle.Value));
				}
			}
		}

		[IteratorStateMachine(typeof(<TrailRoutine>d__6))]
		private static IEnumerator TrailRoutine(CharacterVisual visual, AfterimageStyle style)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TrailRoutine>d__6(0)
			{
				visual = visual,
				style = style
			};
		}

		private static void SpawnAfterimage(CharacterVisual visual, AfterimageStyle style)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0028: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			SkinnedMeshRenderer mainRenderer = visual.mainRenderer;
			if (!((Object)(object)mainRenderer == (Object)null))
			{
				GameObject val = new GameObject("afterimage");
				val.transform.SetPositionAndRotation(((Component)mainRenderer).transform.position, ((Component)mainRenderer).transform.rotation);
				val.transform.localScale = ((Component)mainRenderer).transform.lossyScale;
				Mesh val2 = new Mesh();
				mainRenderer.BakeMesh(val2);
				val.AddComponent<MeshFilter>().mesh = val2;
				MeshRenderer val3 = val.AddComponent<MeshRenderer>();
				((Renderer)val3).material = new Material(AfterimgMaterial)
				{
					color = GetStyleColor(style, 0f)
				};
				((MonoBehaviour)visual).StartCoroutine(FadeAndDestroy(val, val3, style));
			}
		}

		[IteratorStateMachine(typeof(<FadeAndDestroy>d__8))]
		private static IEnumerator FadeAndDestroy(GameObject go, MeshRenderer renderer, AfterimageStyle style)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FadeAndDestroy>d__8(0)
			{
				go = go,
				renderer = renderer,
				style = style
			};
		}

		private static Color GetStyleColor(AfterimageStyle style, float t)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (style.GradientMode == GradientMode.TextureFile)
			{
				if ((Object)(object)style.GradientTexture != (Object)null)
				{
					return style.GradientTexture.GetPixelBilinear(t, 0.5f);
				}
				return Color.Lerp(style.Color, style.SecondaryColor, t);
			}
			if (style.GradientMode == GradientMode.TwoColor)
			{
				return Color.Lerp(style.Color, style.SecondaryColor, t);
			}
			return style.Color;
		}

		private static bool AreStylesEqual(AfterimageStyle? a, AfterimageStyle? b)
		{
			//IL_002f: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!a.HasValue && !b.HasValue)
			{
				return true;
			}
			if (!a.HasValue || !b.HasValue)
			{
				return false;
			}
			Color val = a.Value.Color;
			if (((Color)(ref val)).Equals(b.Value.Color))
			{
				val = a.Value.SecondaryColor;
				if (((Color)(ref val)).Equals(b.Value.SecondaryColor) && a.Value.GradientMode == b.Value.GradientMode && string.Equals(a.Value.GradientTexturePath, b.Value.GradientTexturePath, StringComparison.OrdinalIgnoreCase) && Mathf.Approximately(a.Value.Interval, b.Value.Interval) && Mathf.Approximately(a.Value.Lifetime, b.Value.Lifetime) && Mathf.Approximately(a.Value.FadeSpeed, b.Value.FadeSpeed))
				{
					return a.Value.Priority == b.Value.Priority;
				}
			}
			return false;
		}
	}
	public enum GradientMode
	{
		Off,
		TwoColor,
		TextureFile
	}
	public enum FadeCurveMode
	{
		Linear,
		Smooth,
		FastStart,
		SlowStart,
		Custom
	}
	public class Config
	{
		public class MovementStateConfig
		{
			public ConfigEntry<bool> Enabled { get; }

			public ConfigEntry<Color> Color { get; }

			public ConfigEntry<Color> SecondaryColor { get; }

			public ConfigEntry<GradientMode> GradientModeEntry { get; }

			public ConfigEntry<string> GradientTextureFile { get; }

			public ConfigEntry<FadeCurveMode> FadeCurveModeEntry { get; }

			public ConfigEntry<float> FadeSpeed { get; }

			public ConfigEntry<float> Interval { get; }

			public ConfigEntry<float> Lifetime { get; }

			public ConfigEntry<int> Priority { get; }

			public AfterimageManager.AfterimageStyle CurrentData { get; private set; }

			public MovementStateConfig(ConfigFile config, string name, bool enabled, Color color, Color secondaryColor, GradientMode gradientMode, FadeCurveMode fadeCurveMode, string gradientTextureFile, float interval, float lifetime, float fadeSpeed, int priority)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				string text = "Afterimage: " + name;
				Enabled = config.Bind<bool>(text, "Enabled", enabled, "Enable or disable this afterimage state");
				Color = config.Bind<Color>(text, "Color", color, "Primary color of the afterimage");
				SecondaryColor = config.Bind<Color>(text, "SecondaryColor", secondaryColor, "Secondary color for two-color gradients");
				GradientModeEntry = config.Bind<GradientMode>(text, "GradientMode", gradientMode, "Choose no gradient, a two-color gradient, or a texture-based gradient file");
				GradientTextureFile = config.Bind<string>(text, "GradientTextureFile", gradientTextureFile, "Gradient image file name in the plugin config folder");
				FadeCurveModeEntry = config.Bind<FadeCurveMode>(text, "FadeCurveMode", fadeCurveMode, "Choose a fade curve shape or use Custom to specify a custom speed");
				FadeSpeed = config.Bind<float>(text, "FadeSpeed", fadeSpeed, "Custom fade speed used when FadeCurveMode is Custom");
				Interval = config.Bind<float>(text, "Interval", interval, "Time between afterimages");
				Lifetime = config.Bind<float>(text, "Lifetime", lifetime, "Lifetime of each afterimage");
				Priority = config.Bind<int>(text, "Priority", priority, "Higher-priority styles override lower-priority styles");
				UpdateCurrentData();
				ConfigEntryBase[] array = (ConfigEntryBase[])(object)new ConfigEntryBase[10]
				{
					(ConfigEntryBase)Enabled,
					(ConfigEntryBase)Color,
					(ConfigEntryBase)SecondaryColor,
					(ConfigEntryBase)GradientModeEntry,
					(ConfigEntryBase)GradientTextureFile,
					(ConfigEntryBase)FadeCurveModeEntry,
					(ConfigEntryBase)FadeSpeed,
					(ConfigEntryBase)Interval,
					(ConfigEntryBase)Lifetime,
					(ConfigEntryBase)Priority
				};
				foreach (ConfigEntryBase entry in array)
				{
					entry.ConfigFile.SettingChanged += delegate(object _, SettingChangedEventArgs e)
					{
						if (e.ChangedSetting == entry)
						{
							UpdateCurrentData();
						}
					};
				}
			}

			internal void UpdateCurrentData()
			{
				//IL_0038: 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 (GradientModeEntry.Value == GradientMode.TextureFile)
				{
					EnsureGradientFileForState(this, overwrite: false);
				}
				float fadeSpeed = GetFadeSpeed(FadeCurveModeEntry.Value, FadeSpeed.Value);
				CurrentData = new AfterimageManager.AfterimageStyle(Color.Value, SecondaryColor.Value, GradientModeEntry.Value, GradientTextureFile.Value, LoadGradientTexture(GradientTextureFile.Value), Interval.Value, Lifetime.Value, fadeSpeed, Priority.Value, 0L);
			}

			public static float GetFadeSpeed(FadeCurveMode mode, float customSpeed)
			{
				return mode switch
				{
					FadeCurveMode.Linear => 1f, 
					FadeCurveMode.Smooth => 2f, 
					FadeCurveMode.FastStart => 4f, 
					FadeCurveMode.SlowStart => 0.5f, 
					_ => Mathf.Max(0.01f, customSpeed), 
				};
			}
		}

		public MovementStateConfig staticaf;

		public MovementStateConfig boost;

		public MovementStateConfig trick;

		public MovementStateConfig boosttrick;

		public MovementStateConfig airtrick;

		public MovementStateConfig airboosttrick;

		public MovementStateConfig slidenormal;

		public MovementStateConfig slideslope;

		public MovementStateConfig slidesuper;

		public MovementStateConfig airDash;

		public MovementStateConfig grindnormal;

		public MovementStateConfig grindtrick;

		public MovementStateConfig grindboosttrick;

		public MovementStateConfig grindcorner;

		private const int GradientTextureWidth = 256;

		private static readonly Dictionary<string, Texture2D> GradientTextureCache = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

		public ConfigEntry<bool> RegenerateGradientTextures { get; private set; }

		public ConfigEntry<bool> ReloadGradientTextures { get; private set; }

		public static string ConfigDirectory => Path.Combine(Paths.ConfigPath, "rewind.rwafterimages");

		private IEnumerable<MovementStateConfig> GetAllStateConfigs()
		{
			return new MovementStateConfig[14]
			{
				staticaf, boost, trick, boosttrick, airtrick, airboosttrick, slidenormal, slideslope, slidesuper, airDash,
				grindnormal, grindtrick, grindboosttrick, grindcorner
			};
		}

		public Config(ConfigFile config)
		{
			//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_0055: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			EnsureConfigDirectory();
			staticaf = new MovementStateConfig(config, "Static", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "StaticGradient.png", 0.05f, 0.2f, 4f, 0);
			boost = new MovementStateConfig(config, "Boost", enabled: true, new Color(0.7f, 0.9f, 1f), new Color(0.05f, 0.2f, 0.6f), GradientMode.TextureFile, FadeCurveMode.Linear, "BoostGradient.png", 0.05f, 0.4f, 2f, 1);
			trick = new MovementStateConfig(config, "Trick", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "GroundTrickGradient.png", 0.05f, 0.2f, 4f, 3);
			boosttrick = new MovementStateConfig(config, "Trick (Boost)", enabled: true, new Color(0.7f, 0.9f, 1f), new Color(0.05f, 0.2f, 0.6f), GradientMode.TextureFile, FadeCurveMode.Linear, "GroundBoostTrickGradient.png", 0.05f, 0.25f, 2f, 4);
			airtrick = new MovementStateConfig(config, "Air Trick", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "AirTrickGradient.png", 0.05f, 0.2f, 4f, 3);
			airboosttrick = new MovementStateConfig(config, "Air Trick (Boost)", enabled: true, new Color(0.7f, 0.9f, 1f), new Color(0.05f, 0.2f, 0.6f), GradientMode.TextureFile, FadeCurveMode.Linear, "AirBoostTrickGradient.png", 0.05f, 0.25f, 2f, 4);
			slidenormal = new MovementStateConfig(config, "Slide (Normal)", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "SlideNormalGradient.png", 0.05f, 0.2f, 4f, 2);
			slideslope = new MovementStateConfig(config, "Slide (Slope)", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "SlideSlopeGradient.png", 0.05f, 0.2f, 4f, 2);
			slidesuper = new MovementStateConfig(config, "Slide (Super)", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "SlideSuperGradient.png", 0.05f, 0.2f, 4f, 2);
			airDash = new MovementStateConfig(config, "Air Dash", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "AirDashGradient.png", 0.05f, 0.2f, 4f, 5);
			grindnormal = new MovementStateConfig(config, "Grind (Normal)", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "GrindNormalGradient.png", 0.05f, 0.2f, 4f, 6);
			grindtrick = new MovementStateConfig(config, "Grind Trick", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "GrindTrickGradient.png", 0.05f, 0.2f, 4f, 7);
			grindboosttrick = new MovementStateConfig(config, "Grind Trick (Boost)", enabled: true, new Color(0.7f, 0.9f, 1f), new Color(0.05f, 0.2f, 0.6f), GradientMode.TextureFile, FadeCurveMode.Linear, "GrindBoostTrickGradient.png", 0.05f, 0.25f, 2f, 8);
			grindcorner = new MovementStateConfig(config, "Grind Corner", enabled: false, Color.white, Color.white, GradientMode.Off, FadeCurveMode.Linear, "GrindCornerGradient.png", 0.05f, 0.2f, 4f, 9);
			EnsureDefaultGradientTextures();
			RegenerateGradientTextures = config.Bind<bool>("Tools", "RegenerateGradientTextures", false, "Set this to true to regenerate the default gradient texture files in the plugin config folder.");
			ReloadGradientTextures = config.Bind<bool>("Tools", "ReloadGradientTextures", false, "Set this to true to reload gradient image files from disk for all current afterimage styles.");
			RegenerateGradientTextures.SettingChanged += delegate
			{
				if (RegenerateGradientTextures.Value)
				{
					RegenerateDefaultGradientTextures();
					RegenerateGradientTextures.Value = false;
				}
			};
			ReloadGradientTextures.SettingChanged += delegate
			{
				if (ReloadGradientTextures.Value)
				{
					ReloadAllGradientTextures();
					ReloadGradientTextures.Value = false;
				}
			};
		}

		private static void EnsureConfigDirectory()
		{
			Directory.CreateDirectory(ConfigDirectory);
		}

		private void EnsureDefaultGradientTextures()
		{
			EnsureConfigDirectory();
			foreach (MovementStateConfig allStateConfig in GetAllStateConfigs())
			{
				if (allStateConfig.GradientModeEntry.Value == GradientMode.TextureFile)
				{
					EnsureGradientFileForState(allStateConfig, overwrite: false);
				}
			}
		}

		private void RegenerateDefaultGradientTextures()
		{
			EnsureConfigDirectory();
			foreach (MovementStateConfig allStateConfig in GetAllStateConfigs())
			{
				EnsureGradientFileForState(allStateConfig, overwrite: true);
			}
		}

		private void ReloadAllGradientTextures()
		{
			ClearGradientTextureCache();
			staticaf.UpdateCurrentData();
			boost.UpdateCurrentData();
			trick.UpdateCurrentData();
			boosttrick.UpdateCurrentData();
			airtrick.UpdateCurrentData();
			airboosttrick.UpdateCurrentData();
			slidenormal.UpdateCurrentData();
			slideslope.UpdateCurrentData();
			slidesuper.UpdateCurrentData();
			airDash.UpdateCurrentData();
			grindnormal.UpdateCurrentData();
			grindtrick.UpdateCurrentData();
			grindboosttrick.UpdateCurrentData();
			grindcorner.UpdateCurrentData();
		}

		private static void ClearGradientTextureCache()
		{
			foreach (Texture2D value in GradientTextureCache.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)value);
				}
			}
			GradientTextureCache.Clear();
		}

		private static void EnsureGradientFile(string fileName, Color[] stops, bool overwrite)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(ConfigDirectory, fileName);
			if (!File.Exists(path) || overwrite)
			{
				Texture2D val = new Texture2D(256, 1, (TextureFormat)4, false);
				for (int i = 0; i < 256; i++)
				{
					float t = (float)i / 255f;
					val.SetPixel(i, 0, EvaluateGradient(stops, t));
				}
				val.Apply();
				File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val));
				Object.DestroyImmediate((Object)(object)val);
			}
		}

		private static Color EvaluateGradient(Color[] stops, float t)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (stops == null || stops.Length == 0)
			{
				return Color.white;
			}
			if (stops.Length == 1)
			{
				return stops[0];
			}
			float num = 1f / (float)(stops.Length - 1);
			int num2 = Mathf.Min(stops.Length - 2, Mathf.FloorToInt(t / num));
			float num3 = Mathf.InverseLerp((float)num2 * num, (float)(num2 + 1) * num, t);
			return Color.Lerp(stops[num2], stops[num2 + 1], num3);
		}

		private static Texture2D? LoadGradientTexture(string fileName)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			string text = NormalizeGradientPath(fileName);
			if (text == null)
			{
				return null;
			}
			if (GradientTextureCache.TryGetValue(text, out Texture2D value))
			{
				return value;
			}
			if (!File.Exists(text))
			{
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					Object.DestroyImmediate((Object)(object)val);
					return null;
				}
				((Object)val).name = Path.GetFileName(text);
				GradientTextureCache[text] = val;
				return val;
			}
			catch
			{
				return null;
			}
		}

		private static string? NormalizeGradientPath(string? fileName)
		{
			if (string.IsNullOrWhiteSpace(fileName))
			{
				return null;
			}
			return Path.GetFullPath(Path.IsPathRooted(fileName) ? fileName : Path.Combine(ConfigDirectory, fileName));
		}

		private static void EnsureGradientFileForState(MovementStateConfig state, bool overwrite)
		{
			if (!string.IsNullOrWhiteSpace(state.GradientTextureFile.Value))
			{
				Color[] gradientStops = GetGradientStops(state);
				EnsureGradientFile(state.GradientTextureFile.Value, gradientStops, overwrite);
			}
		}

		private static Color[] GetGradientStops(MovementStateConfig state)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			return (Color[])(object)new Color[2]
			{
				state.Color.Value,
				state.SecondaryColor.Value
			};
		}
	}
	[BepInPlugin("rewind.rwafterimages", "[rw]Afterimages", "1.0.0")]
	[BepInProcess("Bomb Rush Cyberfunk.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static Harmony harmony { get; private set; }

		public static Config CFG { get; private set; }

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			CFG = new Config(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("rewind.rwafterimages");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"v1.0.0 loaded :3");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "rewind.rwafterimages";

		public const string PLUGIN_NAME = "[rw]Afterimages";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Plugin.Patches
{
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatch
	{
		private static readonly Config ConfigSettings = Plugin.CFG;

		private static readonly (string Key, Func<Player, bool> Condition, Config.MovementStateConfig Config)[] StateConfigs = new(string, Func<Player, bool>, Config.MovementStateConfig)[14]
		{
			("staticaf", (Player p) => true, ConfigSettings.staticaf),
			("boostaf", (Player p) => p.boosting, ConfigSettings.boost),
			("boosttrickaf", delegate(Player p)
			{
				if (p.ability == p.groundTrickAbility)
				{
					Ability ability6 = p.ability;
					GroundTrickAbility val6 = (GroundTrickAbility)(object)((ability6 is GroundTrickAbility) ? ability6 : null);
					if (val6 != null)
					{
						return val6.boostTrick;
					}
				}
				return false;
			}, ConfigSettings.boosttrick),
			("trickaf", (Player p) => p.ability == p.groundTrickAbility, ConfigSettings.trick),
			("airboosttrickaf", delegate(Player p)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				if (p.ability == p.airTrickAbility)
				{
					Ability ability5 = p.ability;
					AirTrickAbility val5 = (AirTrickAbility)(object)((ability5 is AirTrickAbility) ? ability5 : null);
					if (val5 != null)
					{
						return (int)val5.trickType == 2;
					}
				}
				return false;
			}, ConfigSettings.airboosttrick),
			("airtrickaf", (Player p) => p.ability == p.airTrickAbility, ConfigSettings.airtrick),
			("slidenormalaf", (Player p) => p.ability == p.slideAbility && (int)p.slideAbility.slideState == 1, ConfigSettings.slidenormal),
			("slideslopeaf", (Player p) => p.ability == p.slideAbility && (int)p.slideAbility.slideState == 2, ConfigSettings.slideslope),
			("slidesuperaf", (Player p) => p.ability == p.slideAbility && (int)p.slideAbility.slideState == 3, ConfigSettings.slidesuper),
			("airDashaf", (Player p) => p.ability == p.airDashAbility, ConfigSettings.airDash),
			("grindnormalaf", delegate(Player p)
			{
				if (p.ability == p.grindAbility)
				{
					Ability ability4 = p.ability;
					GrindAbility val4 = (GrindAbility)(object)((ability4 is GrindAbility) ? ability4 : null);
					if (val4 != null && val4.trickTimer <= 0f)
					{
						return !val4.softCornerBoost;
					}
				}
				return false;
			}, ConfigSettings.grindnormal),
			("grindtrickaf", delegate(Player p)
			{
				if (p.ability == p.grindAbility)
				{
					Ability ability3 = p.ability;
					GrindAbility val3 = (GrindAbility)(object)((ability3 is GrindAbility) ? ability3 : null);
					if (val3 != null && val3.trickTimer > 0f)
					{
						return !val3.curTrickBoost;
					}
				}
				return false;
			}, ConfigSettings.grindtrick),
			("grindboosttrickaf", delegate(Player p)
			{
				if (p.ability == p.grindAbility)
				{
					Ability ability2 = p.ability;
					GrindAbility val2 = (GrindAbility)(object)((ability2 is GrindAbility) ? ability2 : null);
					if (val2 != null && val2.curTrickBoost)
					{
						return val2.trickTimer > 0f;
					}
				}
				return false;
			}, ConfigSettings.grindboosttrick),
			("grindcorneraf", delegate(Player p)
			{
				if (p.ability == p.grindAbility)
				{
					Ability ability = p.ability;
					GrindAbility val = (GrindAbility)(object)((ability is GrindAbility) ? ability : null);
					if (val != null)
					{
						return val.softCornerBoost;
					}
				}
				return false;
			}, ConfigSettings.grindcorner)
		};

		[HarmonyPostfix]
		[HarmonyPatch("Init")]
		public static void Post_Init(Player __instance)
		{
			if (!__instance.isAI)
			{
				Gscope.Player = __instance;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdatePlayer")]
		public static void Post_UpdatePlayer(Player __instance)
		{
			if (__instance.isAI)
			{
				return;
			}
			(string, Func<Player, bool>, Config.MovementStateConfig)[] stateConfigs = StateConfigs;
			for (int i = 0; i < stateConfigs.Length; i++)
			{
				var (requesterId, func, movementStateConfig) = stateConfigs[i];
				if (movementStateConfig.Enabled.Value)
				{
					AfterimageManager.Request(__instance.characterVisual, requesterId, func(__instance), movementStateConfig.CurrentData);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}