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)
{
}
}
}