using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SandevistanAfterimage;
using UnityEngine;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "Sandevistan Afterimage", "0.9.7", "OpenAI", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SandevistanAfterimage")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SandevistanAfterimage")]
[assembly: AssemblyTitle("SandevistanAfterimage")]
[assembly: AssemblyVersion("1.0.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 SandevistanAfterimage
{
public class Main : MelonMod
{
private class TintOverlay
{
public Camera camera;
public GameObject quad;
public Material material;
}
private class GhostSnapshot
{
public readonly float created;
public readonly float lifetime;
public readonly Vector3 origin;
public readonly Material bodyMaterial;
public readonly Material shellMaterial;
public readonly List<GhostPart> parts = new List<GhostPart>();
public GhostSnapshot(float createdTime, float life, Vector3 originPosition, Material body, Material shell)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
created = createdTime;
lifetime = life;
origin = originPosition;
bodyMaterial = body;
shellMaterial = shell;
}
}
private class GhostPart
{
public readonly GameObject bodyObject;
public readonly GameObject shellObject;
public readonly Mesh mesh;
public readonly Mesh shellMesh;
public GhostPart(GameObject body, GameObject shell, Mesh meshValue, Mesh shellMeshValue)
{
bodyObject = body;
shellObject = shell;
mesh = meshValue;
shellMesh = shellMeshValue;
}
}
private static readonly Color BodyNear = new Color(0.05f, 0.95f, 0.9f, 1f);
private static readonly Color BodyFar = new Color(0.02f, 0.5f, 0.4f, 1f);
private static readonly Color RimNear = new Color(0.55f, 1f, 0.95f, 1f);
private static readonly Color RimFar = new Color(0.05f, 0.85f, 0.65f, 1f);
private static readonly Color TintColor = new Color(0.04f, 0.68f, 0.18f, 1f);
private static readonly Color AfterimageFadeGreen = new Color(0.08f, 0.88f, 0.24f, 1f);
private MelonPreferences_Category prefs;
private MelonPreferences_Entry<bool> enabledPref;
private MelonPreferences_Entry<bool> slowMoPref;
private MelonPreferences_Entry<float> thresholdPref;
private MelonPreferences_Entry<int> ghostCountPref;
private MelonPreferences_Entry<float> spawnIntervalPref;
private MelonPreferences_Entry<float> lifetimePref;
private MelonPreferences_Entry<float> alphaPref;
private MelonPreferences_Entry<bool> movementOnlyPref;
private MelonPreferences_Entry<float> spawnDistancePref;
private MelonPreferences_Entry<float> trailLengthPref;
private MelonPreferences_Entry<bool> rimPref;
private MelonPreferences_Entry<float> rimWidthPref;
private MelonPreferences_Entry<bool> additivePref;
private MelonPreferences_Entry<bool> worldTintPref;
private MelonPreferences_Entry<float> worldTintStrengthPref;
private MelonPreferences_Entry<bool> debugPref;
private MelonPreferences_Entry<bool> hotkeyPref;
private readonly List<GhostSnapshot> snapshots = new List<GhostSnapshot>();
private SkinnedMeshRenderer[] avatarRenderers = (SkinnedMeshRenderer[])(object)new SkinnedMeshRenderer[0];
private GameObject avatarObject;
private Vector3 lastSpawnPosition;
private Vector3 lastMovementDirection = Vector3.forward;
private float spawnTimer;
private float scanTimer;
private bool wasSlow;
private bool lastEnabled;
private bool announcedAvatar;
private Material ghostMaterialTemplate;
private bool blendControllable;
private readonly List<TintOverlay> tintOverlays = new List<TintOverlay>();
private Material tintMaterialTemplate;
private bool tintActive;
private float tintFade;
private const float TintFadeDuration = 0.12f;
private bool fogSaved;
private bool savedFog;
private Color savedFogColor;
private float savedFogDensity;
private FogMode savedFogMode;
private Color savedAmbient;
private float savedAmbientIntensity;
private static Mesh unitQuadMesh;
public override void OnInitializeMelon()
{
prefs = MelonPreferences.CreateCategory("SandevistanAfterimage", "Sandevistan Afterimage");
enabledPref = prefs.CreateEntry<bool>("Enabled", true, "Enabled", "Master switch.", false, false, (ValueValidator)null, (string)null);
slowMoPref = prefs.CreateEntry<bool>("TriggerOnSlowMotion", true, "Trigger on slow motion", "Activate when Time.timeScale is below threshold (Quicksilver compatible).", false, false, (ValueValidator)null, (string)null);
thresholdPref = prefs.CreateEntry<float>("SlowMotionThreshold", 0.92f, "Slow-motion threshold", "Below this timeScale the effect runs.", false, false, (ValueValidator)null, (string)null);
ghostCountPref = prefs.CreateEntry<int>("GhostCount", 64, "Ghost count", "Max simultaneous afterimages.", false, false, (ValueValidator)null, (string)null);
spawnIntervalPref = prefs.CreateEntry<float>("SpawnInterval", 0.02f, "Min spawn interval", "Min unscaled seconds between snapshots.", false, false, (ValueValidator)null, (string)null);
lifetimePref = prefs.CreateEntry<float>("Lifetime", 8f, "Lifetime", "Unscaled seconds until a ghost fully fades.", false, false, (ValueValidator)null, (string)null);
alphaPref = prefs.CreateEntry<float>("Alpha", 0.55f, "Alpha", "Starting intensity of each ghost.", false, false, (ValueValidator)null, (string)null);
movementOnlyPref = prefs.CreateEntry<bool>("MovementOnly", true, "Movement only", "Only spawn after moving SpawnDistance.", false, false, (ValueValidator)null, (string)null);
spawnDistancePref = prefs.CreateEntry<float>("SpawnDistance", 0.55f, "Spawn distance", "Meters between ghosts.", false, false, (ValueValidator)null, (string)null);
trailLengthPref = prefs.CreateEntry<float>("TrailLength", 18f, "Trail length", "Meters until fully faded.", false, false, (ValueValidator)null, (string)null);
rimPref = prefs.CreateEntry<bool>("RimGlow", true, "Rim glow", "Bright inverted-hull outline.", false, false, (ValueValidator)null, (string)null);
rimWidthPref = prefs.CreateEntry<float>("RimWidth", 0.016f, "Rim width", "Outline thickness in meters.", false, false, (ValueValidator)null, (string)null);
additivePref = prefs.CreateEntry<bool>("Additive", true, "Additive glow", "Additive blending for brighter overlaps.", false, false, (ValueValidator)null, (string)null);
worldTintPref = prefs.CreateEntry<bool>("WorldTint", true, "World green tint", "Full-screen green overlay + ambient while slow-mo is active.", false, false, (ValueValidator)null, (string)null);
worldTintStrengthPref = prefs.CreateEntry<float>("WorldTintStrength", 0.25f, "World tint strength", "0 = off, 1 = heavy green. Affects only your view.", false, false, (ValueValidator)null, (string)null);
debugPref = prefs.CreateEntry<bool>("DebugLogging", true, "Debug logging", "Console diagnostics.", false, false, (ValueValidator)null, (string)null);
hotkeyPref = prefs.CreateEntry<bool>("F8Toggle", true, "F8 toggle", "Press F8 to toggle.", false, false, (ValueValidator)null, (string)null);
prefs.SaveToFile(false);
lastEnabled = enabledPref.Value;
MelonLogger.Msg("Sandevistan Afterimage 0.9.6 loaded.");
MelonLogger.Msg("Afterimages + full-screen green tint are client-side only (Fusion-safe).");
MelonLogger.Msg("Settings: UserData/MelonPreferences.cfg [SandevistanAfterimage]");
}
public override void OnUpdate()
{
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
//IL_022c: Unknown result type (might be due to invalid IL or missing references)
//IL_0285: Unknown result type (might be due to invalid IL or missing references)
//IL_028a: Unknown result type (might be due to invalid IL or missing references)
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
if (hotkeyPref.Value && Input.GetKeyDown((KeyCode)289))
{
enabledPref.Value = !enabledPref.Value;
prefs.SaveToFile(false);
if (!enabledPref.Value)
{
ClearSnapshots();
SetTintActive(active: false);
}
MelonLogger.Msg("Sandevistan Afterimage: " + (enabledPref.Value ? "ON" : "OFF"));
}
if (lastEnabled != enabledPref.Value)
{
lastEnabled = enabledPref.Value;
if (!lastEnabled)
{
ClearSnapshots();
SetTintActive(active: false);
}
}
UpdateSnapshots();
if (!enabledPref.Value)
{
SetTintActive(active: false);
return;
}
scanTimer -= Time.unscaledDeltaTime;
if (scanTimer <= 0f)
{
scanTimer = 0.4f;
RefreshAvatar();
RefreshTintCameras();
}
if ((Object)(object)avatarObject == (Object)null || avatarRenderers.Length == 0)
{
SetTintActive(active: false);
return;
}
bool flag = slowMoPref.Value && Time.timeScale < Mathf.Clamp(thresholdPref.Value, 0.01f, 1f);
if (flag && !wasSlow)
{
lastSpawnPosition = avatarObject.transform.position;
if (debugPref.Value)
{
MelonLogger.Msg("Slow motion ON timeScale=" + Time.timeScale.ToString("0.000"));
}
}
if (!flag && wasSlow && debugPref.Value)
{
MelonLogger.Msg("Slow motion OFF");
}
wasSlow = flag;
SetTintActive(flag && worldTintPref.Value);
if (!flag)
{
return;
}
spawnTimer -= Time.unscaledDeltaTime;
if (spawnTimer > 0f)
{
return;
}
Vector3 position = avatarObject.transform.position;
Vector3 val = position - lastSpawnPosition;
float num = Mathf.Max(0.02f, spawnDistancePref.Value);
if (movementOnlyPref.Value && ((Vector3)(ref val)).sqrMagnitude < num * num)
{
return;
}
if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
{
lastMovementDirection = ((Vector3)(ref val)).normalized;
}
else
{
Vector3 forward = avatarObject.transform.forward;
if (((Vector3)(ref forward)).sqrMagnitude > 0.0001f)
{
forward = avatarObject.transform.forward;
lastMovementDirection = ((Vector3)(ref forward)).normalized;
}
}
spawnTimer = Mathf.Max(0.008f, spawnIntervalPref.Value);
lastSpawnPosition = position;
CreateSnapshot(lastMovementDirection);
}
private void RefreshAvatar()
{
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Player.RigManager == (Object)null)
{
if (debugPref.Value && !announcedAvatar)
{
MelonLogger.Msg("Waiting for BoneLib player...");
}
return;
}
GameObject val = null;
try
{
if ((Object)(object)Player.Avatar != (Object)null)
{
val = ((Component)Player.Avatar).gameObject;
}
}
catch (Exception ex)
{
if (debugPref.Value)
{
MelonLogger.Warning("Player.Avatar read failed: " + ex.Message);
}
return;
}
if (!((Object)(object)val == (Object)null) && (Object)(object)avatarObject != (Object)(object)val)
{
avatarObject = val;
avatarRenderers = Il2CppArrayBase<SkinnedMeshRenderer>.op_Implicit(avatarObject.GetComponentsInChildren<SkinnedMeshRenderer>(true));
lastSpawnPosition = avatarObject.transform.position;
ClearSnapshots();
announcedAvatar = true;
string[] obj = new string[6]
{
"Avatar: ",
((Object)avatarObject).name,
" renderers=",
avatarRenderers.Length.ToString(),
" rootLossyScale=",
null
};
Vector3 lossyScale = avatarObject.transform.lossyScale;
obj[5] = ((Vector3)(ref lossyScale)).ToString("F3");
MelonLogger.Msg(string.Concat(obj));
}
}
private void CreateSnapshot(Vector3 movementDirection)
{
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Expected O, but got Unknown
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
Material val = CreateGhostMaterial(shell: false);
if ((Object)(object)val == (Object)null)
{
if (debugPref.Value)
{
MelonLogger.Warning("No usable shader for ghost material.");
}
return;
}
Material val2 = ((rimPref.Value && (Object)(object)ghostMaterialTemplate != (Object)null && ghostMaterialTemplate.HasProperty("_Cull")) ? CreateGhostMaterial(shell: true) : null);
float width = Mathf.Clamp(rimWidthPref.Value, 0.001f, 0.08f);
GhostSnapshot ghostSnapshot = new GhostSnapshot(Time.unscaledTime, Mathf.Max(0.02f, lifetimePref.Value), avatarObject.transform.position, val, val2);
int num = 0;
for (int i = 0; i < avatarRenderers.Length; i++)
{
SkinnedMeshRenderer val3 = avatarRenderers[i];
if ((Object)(object)val3 == (Object)null || !((Renderer)val3).enabled || (Object)(object)val3.sharedMesh == (Object)null || val3.sharedMesh.vertexCount < 12)
{
continue;
}
GameObject val4 = null;
GameObject val5 = null;
Mesh val6 = null;
Mesh val7 = null;
try
{
val6 = new Mesh();
((Object)val6).name = "SandevistanAfterimageMesh";
val3.BakeMesh(val6, true);
val4 = SpawnGhostPart("SandevistanAfterimagePart", ((Component)val3).transform, val6, val, -movementDirection * 0.25f);
if ((Object)(object)val2 != (Object)null)
{
val7 = BuildShellMesh(val6, width);
if ((Object)(object)val7 != (Object)null)
{
val5 = SpawnGhostPart("SandevistanAfterimageRim", ((Component)val3).transform, val7, val2, -movementDirection * 0.25f);
}
}
ghostSnapshot.parts.Add(new GhostPart(val4, val5, val6, val7));
num++;
}
catch (Exception ex)
{
if ((Object)(object)val4 != (Object)null)
{
Object.Destroy((Object)(object)val4);
}
if ((Object)(object)val5 != (Object)null)
{
Object.Destroy((Object)(object)val5);
}
if ((Object)(object)val6 != (Object)null)
{
Object.Destroy((Object)(object)val6);
}
if ((Object)(object)val7 != (Object)null)
{
Object.Destroy((Object)(object)val7);
}
if (debugPref.Value)
{
MelonLogger.Warning("Bake failed on " + ((Object)val3).name + ": " + ex.Message);
}
}
}
if (num == 0)
{
DestroySnapshot(ghostSnapshot);
if (debugPref.Value)
{
MelonLogger.Warning("Snapshot produced 0 mesh parts.");
}
return;
}
ApplySnapshotColors(ghostSnapshot, 0f);
snapshots.Add(ghostSnapshot);
TrimSnapshots();
if (debugPref.Value)
{
MelonLogger.Msg("Snapshot: " + num + " parts" + (((Object)(object)val2 != (Object)null) ? " +rim" : ""));
}
}
private static GameObject SpawnGhostPart(string name, Transform source, Mesh mesh, Material material, Vector3 worldOffset)
{
//IL_0001: 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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: 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_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
GameObject val = new GameObject(name);
val.transform.position = source.position + worldOffset;
val.transform.rotation = source.rotation;
val.transform.localScale = source.lossyScale;
MeshFilter val2 = val.AddComponent<MeshFilter>();
MeshRenderer obj = val.AddComponent<MeshRenderer>();
val2.sharedMesh = mesh;
((Renderer)obj).sharedMaterial = material;
((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)obj).receiveShadows = false;
return val;
}
private static Mesh BuildShellMesh(Mesh baked, float width)
{
//IL_0046: 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)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
Mesh val = Object.Instantiate<Mesh>(baked);
((Object)val).name = "SandevistanAfterimageRimMesh";
Vector3[] array = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)val.vertices);
Vector3[] array2 = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)val.normals);
if (array == null || array2 == null || array2.Length != array.Length)
{
Object.Destroy((Object)(object)val);
return null;
}
for (int i = 0; i < array.Length; i++)
{
Vector3 val2 = array2[i];
float magnitude = ((Vector3)(ref val2)).magnitude;
if (magnitude > 1E-05f)
{
array[i] += val2 * (width / magnitude);
}
}
val.vertices = Il2CppStructArray<Vector3>.op_Implicit(array);
val.RecalculateBounds();
return val;
}
private Material CreateGhostMaterial(bool shell)
{
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Unknown result type (might be due to invalid IL or missing references)
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)ghostMaterialTemplate == (Object)null)
{
Shader val = Shader.Find("Universal Render Pipeline/Unlit");
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Unlit/Transparent");
}
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Sprites/Default");
}
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Standard");
}
if ((Object)(object)val == (Object)null)
{
return null;
}
ghostMaterialTemplate = new Material(val);
((Object)ghostMaterialTemplate).name = "SandevistanAfterimageMatTemplate";
blendControllable = ghostMaterialTemplate.HasProperty("_SrcBlend") && ghostMaterialTemplate.HasProperty("_DstBlend");
if (debugPref.Value)
{
MelonLogger.Msg("Ghost shader: " + ((Object)val).name + " blend=" + blendControllable + " _Cull=" + ghostMaterialTemplate.HasProperty("_Cull"));
}
}
Material val2 = new Material(ghostMaterialTemplate);
bool flag = additivePref.Value && blendControllable;
if (val2.HasProperty("_Surface"))
{
val2.SetFloat("_Surface", 1f);
val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
val2.SetOverrideTag("RenderType", "Transparent");
}
if (val2.HasProperty("_Blend"))
{
val2.SetFloat("_Blend", flag ? 2f : 0f);
}
if (val2.HasProperty("_SrcBlend"))
{
val2.SetFloat("_SrcBlend", flag ? 1f : 5f);
}
if (val2.HasProperty("_DstBlend"))
{
val2.SetFloat("_DstBlend", flag ? 1f : 10f);
}
if (val2.HasProperty("_ZWrite"))
{
val2.SetFloat("_ZWrite", 0f);
}
if (val2.HasProperty("_Cull"))
{
val2.SetFloat("_Cull", shell ? 1f : 0f);
}
val2.renderQueue = (shell ? 3001 : 3000);
SetMaterialColor(val2, Compose(shell ? RimNear : BodyNear, Mathf.Clamp01(alphaPref.Value)));
return val2;
}
private Color Compose(Color rgb, float intensity)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_001d: 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_002e: Unknown result type (might be due to invalid IL or missing references)
if (additivePref.Value && blendControllable)
{
return new Color(rgb.r * intensity, rgb.g * intensity, rgb.b * intensity, intensity);
}
return new Color(rgb.r, rgb.g, rgb.b, intensity);
}
private static void SetMaterialColor(Material material, Color color)
{
//IL_001d: 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)
if (!((Object)(object)material == (Object)null))
{
if (material.HasProperty("_Color"))
{
material.SetColor("_Color", color);
}
if (material.HasProperty("_BaseColor"))
{
material.SetColor("_BaseColor", color);
}
}
}
private void ApplySnapshotColors(GhostSnapshot snapshot, float t)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Clamp01(alphaPref.Value) * Mathf.Pow(1f - t, 1.35f);
float num2 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.65f, 1f, t));
Color rgb = Color.Lerp(Color.Lerp(BodyNear, BodyFar, t), AfterimageFadeGreen, num2);
Color rgb2 = Color.Lerp(Color.Lerp(RimNear, RimFar, t), AfterimageFadeGreen, num2);
SetMaterialColor(snapshot.bodyMaterial, Compose(rgb, num));
if ((Object)(object)snapshot.shellMaterial != (Object)null)
{
SetMaterialColor(snapshot.shellMaterial, Compose(rgb2, Mathf.Clamp01(num * 1.7f)));
}
}
private void UpdateSnapshots()
{
//IL_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
float unscaledTime = Time.unscaledTime;
float value = trailLengthPref.Value;
bool flag = (Object)(object)avatarObject != (Object)null;
Vector3 val = (flag ? avatarObject.transform.position : Vector3.zero);
for (int num = snapshots.Count - 1; num >= 0; num--)
{
GhostSnapshot ghostSnapshot = snapshots[num];
if (ghostSnapshot == null)
{
snapshots.RemoveAt(num);
}
else
{
float num2 = (unscaledTime - ghostSnapshot.created) / ghostSnapshot.lifetime;
float num3 = 0f;
if (flag && value > 0.05f)
{
num3 = Vector3.Distance(ghostSnapshot.origin, val) / value;
}
float num4 = Mathf.Clamp01(Mathf.Max(num2, num3));
ApplySnapshotColors(ghostSnapshot, num4);
if (num4 >= 1f)
{
DestroySnapshot(ghostSnapshot);
snapshots.RemoveAt(num);
}
}
}
}
private void TrimSnapshots()
{
int num = Mathf.Clamp(ghostCountPref.Value, 1, 64);
while (snapshots.Count > num)
{
DestroySnapshot(snapshots[0]);
snapshots.RemoveAt(0);
}
}
private void DestroySnapshot(GhostSnapshot snapshot)
{
for (int i = 0; i < snapshot.parts.Count; i++)
{
GhostPart ghostPart = snapshot.parts[i];
if (ghostPart != null)
{
if ((Object)(object)ghostPart.mesh != (Object)null)
{
Object.Destroy((Object)(object)ghostPart.mesh);
}
if ((Object)(object)ghostPart.shellMesh != (Object)null)
{
Object.Destroy((Object)(object)ghostPart.shellMesh);
}
if ((Object)(object)ghostPart.bodyObject != (Object)null)
{
Object.Destroy((Object)(object)ghostPart.bodyObject);
}
if ((Object)(object)ghostPart.shellObject != (Object)null)
{
Object.Destroy((Object)(object)ghostPart.shellObject);
}
}
}
snapshot.parts.Clear();
if ((Object)(object)snapshot.bodyMaterial != (Object)null)
{
Object.Destroy((Object)(object)snapshot.bodyMaterial);
}
if ((Object)(object)snapshot.shellMaterial != (Object)null)
{
Object.Destroy((Object)(object)snapshot.shellMaterial);
}
}
private void ClearSnapshots()
{
for (int i = 0; i < snapshots.Count; i++)
{
DestroySnapshot(snapshots[i]);
}
snapshots.Clear();
wasSlow = false;
}
private void RefreshTintCameras()
{
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Expected O, but got Unknown
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
for (int num = tintOverlays.Count - 1; num >= 0; num--)
{
if ((Object)(object)tintOverlays[num].camera == (Object)null || (Object)(object)tintOverlays[num].quad == (Object)null)
{
if ((Object)(object)tintOverlays[num].quad != (Object)null)
{
Object.Destroy((Object)(object)tintOverlays[num].quad);
}
tintOverlays.RemoveAt(num);
}
}
Camera[] array = Il2CppArrayBase<Camera>.op_Implicit((Il2CppArrayBase<Camera>)(object)Camera.allCameras);
foreach (Camera val in array)
{
if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled || !((Component)val).gameObject.activeInHierarchy || (val.orthographic && val.depth < 0f))
{
continue;
}
bool flag = false;
for (int j = 0; j < tintOverlays.Count; j++)
{
if ((Object)(object)tintOverlays[j].camera == (Object)(object)val)
{
flag = true;
break;
}
}
if (!flag)
{
GameObject val2 = new GameObject("SandevistanTintOverlay");
val2.transform.SetParent(((Component)val).transform, false);
float num2 = Mathf.Max(0.01f, val.nearClipPlane + 0.02f);
val2.transform.localPosition = new Vector3(0f, 0f, num2);
val2.transform.localRotation = Quaternion.identity;
float num3 = val.fieldOfView * 0.5f * ((float)Math.PI / 180f);
float num4 = 2f * num2 * Mathf.Tan(num3);
float num5 = num4 * val.aspect;
val2.transform.localScale = new Vector3(num5 * 1.25f, num4 * 1.25f, 1f);
val2.AddComponent<MeshFilter>().sharedMesh = BuildUnitQuad();
MeshRenderer obj = val2.AddComponent<MeshRenderer>();
Material material = (((Renderer)obj).sharedMaterial = CreateTintMaterial());
((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)obj).receiveShadows = false;
((Renderer)obj).sortingOrder = 32767;
val2.SetActive(false);
tintOverlays.Add(new TintOverlay
{
camera = val,
quad = val2,
material = material
});
if (debugPref.Value)
{
MelonLogger.Msg("Tint overlay attached to camera: " + ((Object)val).name);
}
}
}
}
private static Mesh BuildUnitQuad()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)unitQuadMesh != (Object)null)
{
return unitQuadMesh;
}
unitQuadMesh = new Mesh();
((Object)unitQuadMesh).name = "SandevistanTintQuad";
unitQuadMesh.vertices = Il2CppStructArray<Vector3>.op_Implicit((Vector3[])(object)new Vector3[4]
{
new Vector3(-0.5f, -0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f),
new Vector3(-0.5f, 0.5f, 0f),
new Vector3(0.5f, 0.5f, 0f)
});
unitQuadMesh.uv = Il2CppStructArray<Vector2>.op_Implicit((Vector2[])(object)new Vector2[4]
{
new Vector2(0f, 0f),
new Vector2(1f, 0f),
new Vector2(0f, 1f),
new Vector2(1f, 1f)
});
unitQuadMesh.triangles = Il2CppStructArray<int>.op_Implicit(new int[6] { 0, 2, 1, 2, 3, 1 });
unitQuadMesh.RecalculateNormals();
unitQuadMesh.RecalculateBounds();
return unitQuadMesh;
}
private Material CreateTintMaterial()
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)tintMaterialTemplate == (Object)null)
{
Shader val = Shader.Find("Universal Render Pipeline/Unlit");
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Unlit/Transparent");
}
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Sprites/Default");
}
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("UI/Default");
}
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Standard");
}
tintMaterialTemplate = new Material(val);
((Object)tintMaterialTemplate).name = "SandevistanTintMatTemplate";
}
Material val2 = new Material(tintMaterialTemplate);
if (val2.HasProperty("_Surface"))
{
val2.SetFloat("_Surface", 1f);
val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
val2.SetOverrideTag("RenderType", "Transparent");
}
if (val2.HasProperty("_SrcBlend"))
{
val2.SetFloat("_SrcBlend", 5f);
}
if (val2.HasProperty("_DstBlend"))
{
val2.SetFloat("_DstBlend", 10f);
}
if (val2.HasProperty("_ZWrite"))
{
val2.SetFloat("_ZWrite", 0f);
}
if (val2.HasProperty("_Cull"))
{
val2.SetFloat("_Cull", 0f);
}
val2.renderQueue = 5000;
SetMaterialColor(val2, new Color(TintColor.r, TintColor.g, TintColor.b, 0f));
return val2;
}
private void SetTintActive(bool active)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: Unknown result type (might be due to invalid IL or missing references)
//IL_038b: Unknown result type (might be due to invalid IL or missing references)
//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Clamp01(worldTintStrengthPref.Value);
bool flag = active && num > 0.01f;
if (flag && !fogSaved)
{
savedFog = RenderSettings.fog;
savedFogColor = RenderSettings.fogColor;
savedFogDensity = RenderSettings.fogDensity;
savedFogMode = RenderSettings.fogMode;
savedAmbient = RenderSettings.ambientLight;
savedAmbientIntensity = RenderSettings.ambientIntensity;
fogSaved = true;
}
float num2 = Time.unscaledDeltaTime / Mathf.Max(0.01f, 0.12f);
tintFade = Mathf.MoveTowards(tintFade, flag ? 1f : 0f, num2);
if (tintFade > 0.001f && fogSaved)
{
float num3 = num * tintFade;
Color color = default(Color);
((Color)(ref color))..ctor(TintColor.r, TintColor.g, TintColor.b, num3 * 0.32f);
for (int i = 0; i < tintOverlays.Count; i++)
{
TintOverlay tintOverlay = tintOverlays[i];
if (!((Object)(object)tintOverlay.quad == (Object)null))
{
tintOverlay.quad.SetActive(true);
if ((Object)(object)tintOverlay.camera != (Object)null)
{
float num4 = Mathf.Max(0.01f, tintOverlay.camera.nearClipPlane + 0.02f);
tintOverlay.quad.transform.localPosition = new Vector3(0f, 0f, num4);
float num5 = tintOverlay.camera.fieldOfView * 0.5f * ((float)Math.PI / 180f);
float num6 = 2f * num4 * Mathf.Tan(num5);
float num7 = num6 * tintOverlay.camera.aspect;
tintOverlay.quad.transform.localScale = new Vector3(num7 * 1.25f, num6 * 1.25f, 1f);
}
if ((Object)(object)tintOverlay.material != (Object)null)
{
SetMaterialColor(tintOverlay.material, color);
}
}
}
RenderSettings.ambientLight = Color.Lerp(savedAmbient, new Color(0.08f, 0.42f, 0.16f), num3 * 0.45f);
RenderSettings.ambientIntensity = Mathf.Lerp(savedAmbientIntensity, Mathf.Max(savedAmbientIntensity, 1.08f), num3 * 0.25f);
RenderSettings.fog = true;
RenderSettings.fogMode = (FogMode)3;
RenderSettings.fogColor = Color.Lerp(savedFogColor, new Color(0.025f, 0.3f, 0.1f), num3 * 0.45f);
RenderSettings.fogDensity = Mathf.Lerp(0.003f, 0.0098f, num3 * 0.45f);
if (!tintActive && debugPref.Value)
{
MelonLogger.Msg("World tint ON (smooth fade) strength=" + num.ToString("0.00") + " overlays=" + tintOverlays.Count);
}
tintActive = true;
}
else
{
if (flag || !(tintFade <= 0.001f))
{
return;
}
for (int j = 0; j < tintOverlays.Count; j++)
{
if ((Object)(object)tintOverlays[j].quad != (Object)null)
{
tintOverlays[j].quad.SetActive(false);
}
}
if (fogSaved)
{
RenderSettings.fog = savedFog;
RenderSettings.fogColor = savedFogColor;
RenderSettings.fogDensity = savedFogDensity;
RenderSettings.fogMode = savedFogMode;
RenderSettings.ambientLight = savedAmbient;
RenderSettings.ambientIntensity = savedAmbientIntensity;
fogSaved = false;
}
if (tintActive && debugPref.Value)
{
MelonLogger.Msg("World tint OFF");
}
tintActive = false;
}
}
private void DestroyAllTintOverlays()
{
for (int i = 0; i < tintOverlays.Count; i++)
{
if ((Object)(object)tintOverlays[i].quad != (Object)null)
{
Object.Destroy((Object)(object)tintOverlays[i].quad);
}
if ((Object)(object)tintOverlays[i].material != (Object)null)
{
Object.Destroy((Object)(object)tintOverlays[i].material);
}
}
tintOverlays.Clear();
}
public override void OnDeinitializeMelon()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
ClearSnapshots();
tintFade = 0f;
if (fogSaved)
{
RenderSettings.fog = savedFog;
RenderSettings.fogColor = savedFogColor;
RenderSettings.fogDensity = savedFogDensity;
RenderSettings.fogMode = savedFogMode;
RenderSettings.ambientLight = savedAmbient;
RenderSettings.ambientIntensity = savedAmbientIntensity;
fogSaved = false;
}
DestroyAllTintOverlays();
if ((Object)(object)ghostMaterialTemplate != (Object)null)
{
Object.Destroy((Object)(object)ghostMaterialTemplate);
}
if ((Object)(object)tintMaterialTemplate != (Object)null)
{
Object.Destroy((Object)(object)tintMaterialTemplate);
}
if ((Object)(object)unitQuadMesh != (Object)null)
{
Object.Destroy((Object)(object)unitQuadMesh);
}
ghostMaterialTemplate = null;
tintMaterialTemplate = null;
unitQuadMesh = null;
}
}
}